assembler-mips64.h revision b8a8cc1952d61a2f3a2568848933943a543b5d3e
1b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Copyright (c) 1994-2006 Sun Microsystems Inc.
2b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// All Rights Reserved.
3b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch//
4b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Redistribution and use in source and binary forms, with or without
5b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// modification, are permitted provided that the following conditions are
6b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// met:
7b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch//
8b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// - Redistributions of source code must retain the above copyright notice,
9b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// this list of conditions and the following disclaimer.
10b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch//
11b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// - Redistribution in binary form must reproduce the above copyright
12b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// notice, this list of conditions and the following disclaimer in the
13b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// documentation and/or other materials provided with the distribution.
14b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch//
15b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// - Neither the name of Sun Microsystems or the names of contributors may
16b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// be used to endorse or promote products derived from this software without
17b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// specific prior written permission.
18b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch//
19b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
20b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
21b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
23b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
24b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
25b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
26b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
27b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
28b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
29b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
31b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// The original source code covered by the above license above has been
32b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// modified significantly by Google Inc.
33b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Copyright 2012 the V8 project authors. All rights reserved.
34b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
35b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
36b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#ifndef V8_MIPS_ASSEMBLER_MIPS_H_
37b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#define V8_MIPS_ASSEMBLER_MIPS_H_
38b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
39b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include <stdio.h>
40b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/assembler.h"
41b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/mips64/constants-mips64.h"
42b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/serialize.h"
43b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
44b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochnamespace v8 {
45b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochnamespace internal {
46b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
47b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// CPU Registers.
48b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch//
49b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// 1) We would prefer to use an enum, but enum values are assignment-
50b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// compatible with int, which has caused code-generation bugs.
51b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch//
52b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// 2) We would prefer to use a class instead of a struct but we don't like
53b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// the register initialization to depend on the particular initialization
54b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// order (which appears to be different on OS X, Linux, and Windows for the
55b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// installed versions of C++ we tried). Using a struct permits C-style
56b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// "initialization". Also, the Register objects cannot be const as this
57b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// forces initialization stubs in MSVC, making us dependent on initialization
58b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// order.
59b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch//
60b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// 3) By not using an enum, we are possibly preventing the compiler from
61b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// doing certain constant folds, which may significantly reduce the
62b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// code generated for some assembly instructions (because they boil down
63b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// to a few constants). If this is a problem, we could change the code
64b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// such that we use an enum in optimized mode, and the struct in debug
65b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// mode. This way we get the compile-time error checking in debug mode
66b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// and best performance in optimized code.
67b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
68b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
69b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// -----------------------------------------------------------------------------
70b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Implementation of Register and FPURegister.
71b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
72b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Core register.
73b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochstruct Register {
74b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static const int kNumRegisters = v8::internal::kNumRegisters;
75b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static const int kMaxNumAllocatableRegisters = 14;  // v0 through t6 and cp.
76b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static const int kSizeInBytes = 8;
77b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static const int kCpRegister = 23;  // cp (s7) is the 23rd register.
78b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
79b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  inline static int NumAllocatableRegisters();
80b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
81b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static int ToAllocationIndex(Register reg) {
82b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK((reg.code() - 2) < (kMaxNumAllocatableRegisters - 1) ||
83b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch           reg.is(from_code(kCpRegister)));
84b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return reg.is(from_code(kCpRegister)) ?
85b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch           kMaxNumAllocatableRegisters - 1 :  // Return last index for 'cp'.
86b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch           reg.code() - 2;  // zero_reg and 'at' are skipped.
87b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
88b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
89b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static Register FromAllocationIndex(int index) {
90b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(index >= 0 && index < kMaxNumAllocatableRegisters);
91b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return index == kMaxNumAllocatableRegisters - 1 ?
92b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch           from_code(kCpRegister) :  // Last index is always the 'cp' register.
93b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch           from_code(index + 2);  // zero_reg and 'at' are skipped.
94b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
95b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
96b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static const char* AllocationIndexToString(int index) {
97b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(index >= 0 && index < kMaxNumAllocatableRegisters);
98b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    const char* const names[] = {
99b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      "v0",
100b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      "v1",
101b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      "a0",
102b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      "a1",
103b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      "a2",
104b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      "a3",
105b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      "a4",
106b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      "a5",
107b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      "a6",
108b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      "a7",
109b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      "t0",
110b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      "t1",
111b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      "t2",
112b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      "s7",
113b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    };
114b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return names[index];
115b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
116b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
117b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static Register from_code(int code) {
118b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Register r = { code };
119b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return r;
120b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
121b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
122b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bool is_valid() const { return 0 <= code_ && code_ < kNumRegisters; }
123b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bool is(Register reg) const { return code_ == reg.code_; }
124b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int code() const {
125b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(is_valid());
126b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return code_;
127b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
128b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int bit() const {
129b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(is_valid());
130b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return 1 << code_;
131b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
132b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
133b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Unfortunately we can't make this private in a struct.
134b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int code_;
135b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch};
136b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
137b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#define REGISTER(N, C) \
138b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  const int kRegister_ ## N ## _Code = C; \
139b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  const Register N = { C }
140b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
141b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochREGISTER(no_reg, -1);
142b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Always zero.
143b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochREGISTER(zero_reg, 0);
144b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// at: Reserved for synthetic instructions.
145b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochREGISTER(at, 1);
146b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// v0, v1: Used when returning multiple values from subroutines.
147b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochREGISTER(v0, 2);
148b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochREGISTER(v1, 3);
149b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// a0 - a4: Used to pass non-FP parameters.
150b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochREGISTER(a0, 4);
151b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochREGISTER(a1, 5);
152b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochREGISTER(a2, 6);
153b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochREGISTER(a3, 7);
154b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// a4 - a7 t0 - t3: Can be used without reservation, act as temporary registers
155b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// and are allowed to be destroyed by subroutines.
156b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochREGISTER(a4, 8);
157b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochREGISTER(a5, 9);
158b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochREGISTER(a6, 10);
159b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochREGISTER(a7, 11);
160b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochREGISTER(t0, 12);
161b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochREGISTER(t1, 13);
162b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochREGISTER(t2, 14);
163b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochREGISTER(t3, 15);
164b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// s0 - s7: Subroutine register variables. Subroutines that write to these
165b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// registers must restore their values before exiting so that the caller can
166b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// expect the values to be preserved.
167b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochREGISTER(s0, 16);
168b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochREGISTER(s1, 17);
169b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochREGISTER(s2, 18);
170b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochREGISTER(s3, 19);
171b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochREGISTER(s4, 20);
172b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochREGISTER(s5, 21);
173b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochREGISTER(s6, 22);
174b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochREGISTER(s7, 23);
175b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochREGISTER(t8, 24);
176b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochREGISTER(t9, 25);
177b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// k0, k1: Reserved for system calls and interrupt handlers.
178b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochREGISTER(k0, 26);
179b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochREGISTER(k1, 27);
180b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// gp: Reserved.
181b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochREGISTER(gp, 28);
182b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// sp: Stack pointer.
183b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochREGISTER(sp, 29);
184b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// fp: Frame pointer.
185b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochREGISTER(fp, 30);
186b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// ra: Return address pointer.
187b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochREGISTER(ra, 31);
188b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
189b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#undef REGISTER
190b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
191b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
192b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochint ToNumber(Register reg);
193b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
194b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochRegister ToRegister(int num);
195b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
196b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Coprocessor register.
197b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochstruct FPURegister {
198b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static const int kMaxNumRegisters = v8::internal::kNumFPURegisters;
199b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
200b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // TODO(plind): Warning, inconsistent numbering here. kNumFPURegisters refers
201b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // to number of 32-bit FPU regs, but kNumAllocatableRegisters refers to
202b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // number of Double regs (64-bit regs, or FPU-reg-pairs).
203b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
204b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // A few double registers are reserved: one as a scratch register and one to
205b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // hold 0.0.
206b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  //  f28: 0.0
207b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  //  f30: scratch register.
208b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static const int kNumReservedRegisters = 2;
209b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static const int kMaxNumAllocatableRegisters = kMaxNumRegisters / 2 -
210b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      kNumReservedRegisters;
211b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
212b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  inline static int NumRegisters();
213b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  inline static int NumAllocatableRegisters();
214b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  inline static int ToAllocationIndex(FPURegister reg);
215b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static const char* AllocationIndexToString(int index);
216b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
217b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static FPURegister FromAllocationIndex(int index) {
218b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(index >= 0 && index < kMaxNumAllocatableRegisters);
219b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return from_code(index * 2);
220b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
221b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
222b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static FPURegister from_code(int code) {
223b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    FPURegister r = { code };
224b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return r;
225b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
226b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
227b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bool is_valid() const { return 0 <= code_ && code_ < kMaxNumRegisters ; }
228b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bool is(FPURegister creg) const { return code_ == creg.code_; }
229b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  FPURegister low() const {
230b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // TODO(plind): Create DCHECK for FR=0 mode. This usage suspect for FR=1.
231b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Find low reg of a Double-reg pair, which is the reg itself.
232b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(code_ % 2 == 0);  // Specified Double reg must be even.
233b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    FPURegister reg;
234b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    reg.code_ = code_;
235b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(reg.is_valid());
236b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return reg;
237b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
238b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  FPURegister high() const {
239b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // TODO(plind): Create DCHECK for FR=0 mode. This usage illegal in FR=1.
240b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Find high reg of a Doubel-reg pair, which is reg + 1.
241b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(code_ % 2 == 0);  // Specified Double reg must be even.
242b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    FPURegister reg;
243b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    reg.code_ = code_ + 1;
244b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(reg.is_valid());
245b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return reg;
246b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
247b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
248b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int code() const {
249b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(is_valid());
250b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return code_;
251b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
252b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int bit() const {
253b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(is_valid());
254b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return 1 << code_;
255b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
256b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void setcode(int f) {
257b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    code_ = f;
258b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(is_valid());
259b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
260b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Unfortunately we can't make this private in a struct.
261b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int code_;
262b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch};
263b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
264b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// V8 now supports the O32 ABI, and the FPU Registers are organized as 32
265b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// 32-bit registers, f0 through f31. When used as 'double' they are used
266b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// in pairs, starting with the even numbered register. So a double operation
267b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// on f0 really uses f0 and f1.
268b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// (Modern mips hardware also supports 32 64-bit registers, via setting
269b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// (privileged) Status Register FR bit to 1. This is used by the N32 ABI,
270b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// but it is not in common use. Someday we will want to support this in v8.)
271b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
272b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// For O32 ABI, Floats and Doubles refer to same set of 32 32-bit registers.
273b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochtypedef FPURegister DoubleRegister;
274b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochtypedef FPURegister FloatRegister;
275b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
276b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochconst FPURegister no_freg = { -1 };
277b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
278b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochconst FPURegister f0 = { 0 };  // Return value in hard float mode.
279b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochconst FPURegister f1 = { 1 };
280b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochconst FPURegister f2 = { 2 };
281b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochconst FPURegister f3 = { 3 };
282b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochconst FPURegister f4 = { 4 };
283b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochconst FPURegister f5 = { 5 };
284b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochconst FPURegister f6 = { 6 };
285b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochconst FPURegister f7 = { 7 };
286b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochconst FPURegister f8 = { 8 };
287b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochconst FPURegister f9 = { 9 };
288b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochconst FPURegister f10 = { 10 };
289b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochconst FPURegister f11 = { 11 };
290b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochconst FPURegister f12 = { 12 };  // Arg 0 in hard float mode.
291b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochconst FPURegister f13 = { 13 };
292b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochconst FPURegister f14 = { 14 };  // Arg 1 in hard float mode.
293b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochconst FPURegister f15 = { 15 };
294b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochconst FPURegister f16 = { 16 };
295b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochconst FPURegister f17 = { 17 };
296b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochconst FPURegister f18 = { 18 };
297b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochconst FPURegister f19 = { 19 };
298b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochconst FPURegister f20 = { 20 };
299b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochconst FPURegister f21 = { 21 };
300b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochconst FPURegister f22 = { 22 };
301b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochconst FPURegister f23 = { 23 };
302b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochconst FPURegister f24 = { 24 };
303b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochconst FPURegister f25 = { 25 };
304b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochconst FPURegister f26 = { 26 };
305b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochconst FPURegister f27 = { 27 };
306b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochconst FPURegister f28 = { 28 };
307b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochconst FPURegister f29 = { 29 };
308b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochconst FPURegister f30 = { 30 };
309b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochconst FPURegister f31 = { 31 };
310b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
311b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Register aliases.
312b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// cp is assumed to be a callee saved register.
313b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Defined using #define instead of "static const Register&" because Clang
314b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// complains otherwise when a compilation unit that includes this header
315b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// doesn't use the variables.
316b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#define kRootRegister s6
317b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#define cp s7
318b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#define kLithiumScratchReg s3
319b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#define kLithiumScratchReg2 s4
320b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#define kLithiumScratchDouble f30
321b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#define kDoubleRegZero f28
322b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
323b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// FPU (coprocessor 1) control registers.
324b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Currently only FCSR (#31) is implemented.
325b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochstruct FPUControlRegister {
326b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bool is_valid() const { return code_ == kFCSRRegister; }
327b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bool is(FPUControlRegister creg) const { return code_ == creg.code_; }
328b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int code() const {
329b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(is_valid());
330b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return code_;
331b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
332b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int bit() const {
333b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(is_valid());
334b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return 1 << code_;
335b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
336b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void setcode(int f) {
337b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    code_ = f;
338b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(is_valid());
339b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
340b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Unfortunately we can't make this private in a struct.
341b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int code_;
342b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch};
343b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
344b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochconst FPUControlRegister no_fpucreg = { kInvalidFPUControlRegister };
345b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochconst FPUControlRegister FCSR = { kFCSRRegister };
346b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
347b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
348b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// -----------------------------------------------------------------------------
349b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Machine instruction Operands.
350b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochconst int kSmiShift = kSmiTagSize + kSmiShiftSize;
351b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochconst uint64_t kSmiShiftMask = (1UL << kSmiShift) - 1;
352b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Class Operand represents a shifter operand in data processing instructions.
353b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass Operand BASE_EMBEDDED {
354b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch public:
355b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Immediate.
356b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  INLINE(explicit Operand(int64_t immediate,
357b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch         RelocInfo::Mode rmode = RelocInfo::NONE64));
358b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  INLINE(explicit Operand(const ExternalReference& f));
359b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  INLINE(explicit Operand(const char* s));
360b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  INLINE(explicit Operand(Object** opp));
361b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  INLINE(explicit Operand(Context** cpp));
362b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  explicit Operand(Handle<Object> handle);
363b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  INLINE(explicit Operand(Smi* value));
364b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
365b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Register.
366b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  INLINE(explicit Operand(Register rm));
367b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
368b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Return true if this is a register operand.
369b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  INLINE(bool is_reg() const);
370b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
371b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  inline int64_t immediate() const {
372b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(!is_reg());
373b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return imm64_;
374b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
375b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
376b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Register rm() const { return rm_; }
377b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
378b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch private:
379b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Register rm_;
380b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int64_t imm64_;  // Valid if rm_ == no_reg.
381b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  RelocInfo::Mode rmode_;
382b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
383b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  friend class Assembler;
384b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  friend class MacroAssembler;
385b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch};
386b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
387b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
388b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// On MIPS we have only one adressing mode with base_reg + offset.
389b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Class MemOperand represents a memory operand in load and store instructions.
390b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass MemOperand : public Operand {
391b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch public:
392b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Immediate value attached to offset.
393b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  enum OffsetAddend {
394b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    offset_minus_one = -1,
395b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    offset_zero = 0
396b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  };
397b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
398b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  explicit MemOperand(Register rn, int64_t offset = 0);
399b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  explicit MemOperand(Register rn, int64_t unit, int64_t multiplier,
400b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                      OffsetAddend offset_addend = offset_zero);
401b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int32_t offset() const { return offset_; }
402b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
403b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bool OffsetIsInt16Encodable() const {
404b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return is_int16(offset_);
405b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
406b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
407b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch private:
408b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int32_t offset_;
409b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
410b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  friend class Assembler;
411b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch};
412b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
413b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
414b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass Assembler : public AssemblerBase {
415b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch public:
416b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Create an assembler. Instructions and relocation information are emitted
417b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // into a buffer, with the instructions starting from the beginning and the
418b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // relocation information starting from the end of the buffer. See CodeDesc
419b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // for a detailed comment on the layout (globals.h).
420b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  //
421b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // If the provided buffer is NULL, the assembler allocates and grows its own
422b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // buffer, and buffer_size determines the initial buffer size. The buffer is
423b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // owned by the assembler and deallocated upon destruction of the assembler.
424b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  //
425b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // If the provided buffer is not NULL, the assembler uses the provided buffer
426b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // for code generation and assumes its size to be buffer_size. If the buffer
427b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // is too small, a fatal error occurs. No deallocation of the buffer is done
428b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // upon destruction of the assembler.
429b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Assembler(Isolate* isolate, void* buffer, int buffer_size);
430b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  virtual ~Assembler() { }
431b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
432b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // GetCode emits any pending (non-emitted) code and fills the descriptor
433b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // desc. GetCode() is idempotent; it returns the same result if no other
434b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Assembler functions are invoked in between GetCode() calls.
435b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void GetCode(CodeDesc* desc);
436b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
437b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Label operations & relative jumps (PPUM Appendix D).
438b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  //
439b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Takes a branch opcode (cc) and a label (L) and generates
440b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // either a backward branch or a forward branch and links it
441b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // to the label fixup chain. Usage:
442b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  //
443b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Label L;    // unbound label
444b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // j(cc, &L);  // forward branch to unbound label
445b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // bind(&L);   // bind label to the current pc
446b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // j(cc, &L);  // backward branch to bound label
447b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // bind(&L);   // illegal: a label may be bound only once
448b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  //
449b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Note: The same Label can be used for forward and backward branches
450b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // but it may be bound only once.
451b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void bind(Label* L);  // Binds an unbound label L to current code position.
452b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Determines if Label is bound and near enough so that branch instruction
453b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // can be used to reach it, instead of jump instruction.
454b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bool is_near(Label* L);
455b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
456b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Returns the branch offset to the given label from the current code
457b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // position. Links the label to the current position if it is still unbound.
458b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Manages the jump elimination optimization if the second parameter is true.
459b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int32_t branch_offset(Label* L, bool jump_elimination_allowed);
460b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int32_t branch_offset_compact(Label* L, bool jump_elimination_allowed);
461b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int32_t branch_offset21(Label* L, bool jump_elimination_allowed);
462b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int32_t branch_offset21_compact(Label* L, bool jump_elimination_allowed);
463b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int32_t shifted_branch_offset(Label* L, bool jump_elimination_allowed) {
464b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    int32_t o = branch_offset(L, jump_elimination_allowed);
465b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK((o & 3) == 0);   // Assert the offset is aligned.
466b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return o >> 2;
467b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
468b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int32_t shifted_branch_offset_compact(Label* L,
469b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      bool jump_elimination_allowed) {
470b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    int32_t o = branch_offset_compact(L, jump_elimination_allowed);
471b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK((o & 3) == 0);   // Assert the offset is aligned.
472b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return o >> 2;
473b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
474b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  uint64_t jump_address(Label* L);
475b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
476b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Puts a labels target address at the given position.
477b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // The high 8 bits are set to zero.
478b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void label_at_put(Label* L, int at_offset);
479b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
480b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Read/Modify the code target address in the branch/call instruction at pc.
481b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static Address target_address_at(Address pc);
482b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static void set_target_address_at(Address pc,
483b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                    Address target,
484b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                    ICacheFlushMode icache_flush_mode =
485b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                        FLUSH_ICACHE_IF_NEEDED);
486b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // On MIPS there is no Constant Pool so we skip that parameter.
487b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  INLINE(static Address target_address_at(Address pc,
488b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                          ConstantPoolArray* constant_pool)) {
489b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return target_address_at(pc);
490b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
491b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  INLINE(static void set_target_address_at(Address pc,
492b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                           ConstantPoolArray* constant_pool,
493b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                           Address target,
494b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                           ICacheFlushMode icache_flush_mode =
495b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                               FLUSH_ICACHE_IF_NEEDED)) {
496b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    set_target_address_at(pc, target, icache_flush_mode);
497b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
498b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  INLINE(static Address target_address_at(Address pc, Code* code)) {
499b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    ConstantPoolArray* constant_pool = code ? code->constant_pool() : NULL;
500b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return target_address_at(pc, constant_pool);
501b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
502b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  INLINE(static void set_target_address_at(Address pc,
503b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                           Code* code,
504b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                           Address target,
505b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                           ICacheFlushMode icache_flush_mode =
506b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                               FLUSH_ICACHE_IF_NEEDED)) {
507b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    ConstantPoolArray* constant_pool = code ? code->constant_pool() : NULL;
508b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    set_target_address_at(pc, constant_pool, target, icache_flush_mode);
509b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
510b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
511b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Return the code target address at a call site from the return address
512b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // of that call in the instruction stream.
513b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  inline static Address target_address_from_return_address(Address pc);
514b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
515b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Return the code target address of the patch debug break slot
516b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  inline static Address break_address_from_return_address(Address pc);
517b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
518b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static void JumpLabelToJumpRegister(Address pc);
519b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
520b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static void QuietNaN(HeapObject* nan);
521b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
522b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // This sets the branch destination (which gets loaded at the call address).
523b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // This is for calls and branches within generated code.  The serializer
524b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // has already deserialized the lui/ori instructions etc.
525b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  inline static void deserialization_set_special_target_at(
526b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      Address instruction_payload, Code* code, Address target) {
527b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    set_target_address_at(
528b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        instruction_payload - kInstructionsFor64BitConstant * kInstrSize,
529b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        code,
530b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        target);
531b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
532b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
533b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Size of an instruction.
534b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static const int kInstrSize = sizeof(Instr);
535b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
536b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Difference between address of current opcode and target address offset.
537b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static const int kBranchPCOffset = 4;
538b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
539b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Here we are patching the address in the LUI/ORI instruction pair.
540b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // These values are used in the serialization process and must be zero for
541b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // MIPS platform, as Code, Embedded Object or External-reference pointers
542b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // are split across two consecutive instructions and don't exist separately
543b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // in the code, so the serializer should not step forwards in memory after
544b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // a target is resolved and written.
545b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static const int kSpecialTargetSize = 0;
546b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
547b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Number of consecutive instructions used to store 32bit/64bit constant.
548b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Before jump-optimizations, this constant was used in
549b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // RelocInfo::target_address_address() function to tell serializer address of
550b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // the instruction that follows LUI/ORI instruction pair. Now, with new jump
551b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // optimization, where jump-through-register instruction that usually
552b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // follows LUI/ORI pair is substituted with J/JAL, this constant equals
553b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // to 3 instructions (LUI+ORI+J/JAL/JR/JALR).
554b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static const int kInstructionsFor32BitConstant = 3;
555b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static const int kInstructionsFor64BitConstant = 5;
556b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
557b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Distance between the instruction referring to the address of the call
558b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // target and the return address.
559b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static const int kCallTargetAddressOffset = 6 * kInstrSize;
560b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
561b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Distance between start of patched return sequence and the emitted address
562b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // to jump to.
563b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static const int kPatchReturnSequenceAddressOffset = 0;
564b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
565b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Distance between start of patched debug break slot and the emitted address
566b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // to jump to.
567b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static const int kPatchDebugBreakSlotAddressOffset =  0 * kInstrSize;
568b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
569b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Difference between address of current opcode and value read from pc
570b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // register.
571b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static const int kPcLoadDelta = 4;
572b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
573b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static const int kPatchDebugBreakSlotReturnOffset = 6 * kInstrSize;
574b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
575b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Number of instructions used for the JS return sequence. The constant is
576b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // used by the debugger to patch the JS return sequence.
577b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static const int kJSReturnSequenceInstructions = 7;
578b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static const int kDebugBreakSlotInstructions = 6;
579b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static const int kDebugBreakSlotLength =
580b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      kDebugBreakSlotInstructions * kInstrSize;
581b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
582b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
583b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // ---------------------------------------------------------------------------
584b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Code generation.
585b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
586b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Insert the smallest number of nop instructions
587b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // possible to align the pc offset to a multiple
588b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // of m. m must be a power of 2 (>= 4).
589b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void Align(int m);
590b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Aligns code to something that's optimal for a jump target for the platform.
591b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void CodeTargetAlign();
592b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
593b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Different nop operations are used by the code generator to detect certain
594b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // states of the generated code.
595b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  enum NopMarkerTypes {
596b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    NON_MARKING_NOP = 0,
597b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DEBUG_BREAK_NOP,
598b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // IC markers.
599b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    PROPERTY_ACCESS_INLINED,
600b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    PROPERTY_ACCESS_INLINED_CONTEXT,
601b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    PROPERTY_ACCESS_INLINED_CONTEXT_DONT_DELETE,
602b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Helper values.
603b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    LAST_CODE_MARKER,
604b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    FIRST_IC_MARKER = PROPERTY_ACCESS_INLINED,
605b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Code aging
606b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    CODE_AGE_MARKER_NOP = 6,
607b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    CODE_AGE_SEQUENCE_NOP
608b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  };
609b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
610b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Type == 0 is the default non-marking nop. For mips this is a
611b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // sll(zero_reg, zero_reg, 0). We use rt_reg == at for non-zero
612b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // marking, to avoid conflict with ssnop and ehb instructions.
613b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void nop(unsigned int type = 0) {
614b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(type < 32);
615b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Register nop_rt_reg = (type == 0) ? zero_reg : at;
616b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    sll(zero_reg, nop_rt_reg, type, true);
617b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
618b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
619b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
620b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // --------Branch-and-jump-instructions----------
621b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // We don't use likely variant of instructions.
622b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void b(int16_t offset);
623b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void b(Label* L) { b(branch_offset(L, false)>>2); }
624b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void bal(int16_t offset);
625b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void bal(Label* L) { bal(branch_offset(L, false)>>2); }
626b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
627b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void beq(Register rs, Register rt, int16_t offset);
628b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void beq(Register rs, Register rt, Label* L) {
629b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    beq(rs, rt, branch_offset(L, false) >> 2);
630b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
631b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void bgez(Register rs, int16_t offset);
632b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void bgezc(Register rt, int16_t offset);
633b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void bgezc(Register rt, Label* L) {
634b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    bgezc(rt, branch_offset_compact(L, false)>>2);
635b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
636b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void bgeuc(Register rs, Register rt, int16_t offset);
637b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void bgeuc(Register rs, Register rt, Label* L) {
638b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    bgeuc(rs, rt, branch_offset_compact(L, false)>>2);
639b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
640b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void bgec(Register rs, Register rt, int16_t offset);
641b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void bgec(Register rs, Register rt, Label* L) {
642b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    bgec(rs, rt, branch_offset_compact(L, false)>>2);
643b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
644b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void bgezal(Register rs, int16_t offset);
645b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void bgezalc(Register rt, int16_t offset);
646b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void bgezalc(Register rt, Label* L) {
647b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    bgezalc(rt, branch_offset_compact(L, false)>>2);
648b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
649b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void bgezall(Register rs, int16_t offset);
650b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void bgezall(Register rs, Label* L) {
651b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    bgezall(rs, branch_offset(L, false)>>2);
652b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
653b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void bgtz(Register rs, int16_t offset);
654b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void bgtzc(Register rt, int16_t offset);
655b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void bgtzc(Register rt, Label* L) {
656b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    bgtzc(rt, branch_offset_compact(L, false)>>2);
657b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
658b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void blez(Register rs, int16_t offset);
659b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void blezc(Register rt, int16_t offset);
660b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void blezc(Register rt, Label* L) {
661b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    blezc(rt, branch_offset_compact(L, false)>>2);
662b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
663b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void bltz(Register rs, int16_t offset);
664b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void bltzc(Register rt, int16_t offset);
665b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void bltzc(Register rt, Label* L) {
666b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    bltzc(rt, branch_offset_compact(L, false)>>2);
667b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
668b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void bltuc(Register rs, Register rt, int16_t offset);
669b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void bltuc(Register rs, Register rt, Label* L) {
670b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    bltuc(rs, rt, branch_offset_compact(L, false)>>2);
671b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
672b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void bltc(Register rs, Register rt, int16_t offset);
673b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void bltc(Register rs, Register rt, Label* L) {
674b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    bltc(rs, rt, branch_offset_compact(L, false)>>2);
675b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
676b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
677b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void bltzal(Register rs, int16_t offset);
678b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void blezalc(Register rt, int16_t offset);
679b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void blezalc(Register rt, Label* L) {
680b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    blezalc(rt, branch_offset_compact(L, false)>>2);
681b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
682b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void bltzalc(Register rt, int16_t offset);
683b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void bltzalc(Register rt, Label* L) {
684b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    bltzalc(rt, branch_offset_compact(L, false)>>2);
685b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
686b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void bgtzalc(Register rt, int16_t offset);
687b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void bgtzalc(Register rt, Label* L) {
688b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    bgtzalc(rt, branch_offset_compact(L, false)>>2);
689b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
690b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void beqzalc(Register rt, int16_t offset);
691b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void beqzalc(Register rt, Label* L) {
692b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    beqzalc(rt, branch_offset_compact(L, false)>>2);
693b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
694b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void beqc(Register rs, Register rt, int16_t offset);
695b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void beqc(Register rs, Register rt, Label* L) {
696b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    beqc(rs, rt, branch_offset_compact(L, false)>>2);
697b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
698b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void beqzc(Register rs, int32_t offset);
699b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void beqzc(Register rs, Label* L) {
700b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    beqzc(rs, branch_offset21_compact(L, false)>>2);
701b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
702b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void bnezalc(Register rt, int16_t offset);
703b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void bnezalc(Register rt, Label* L) {
704b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    bnezalc(rt, branch_offset_compact(L, false)>>2);
705b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
706b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void bnec(Register rs, Register rt, int16_t offset);
707b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void bnec(Register rs, Register rt, Label* L) {
708b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    bnec(rs, rt, branch_offset_compact(L, false)>>2);
709b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
710b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void bnezc(Register rt, int32_t offset);
711b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void bnezc(Register rt, Label* L) {
712b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    bnezc(rt, branch_offset21_compact(L, false)>>2);
713b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
714b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void bne(Register rs, Register rt, int16_t offset);
715b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void bne(Register rs, Register rt, Label* L) {
716b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    bne(rs, rt, branch_offset(L, false)>>2);
717b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
718b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void bovc(Register rs, Register rt, int16_t offset);
719b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void bovc(Register rs, Register rt, Label* L) {
720b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    bovc(rs, rt, branch_offset_compact(L, false)>>2);
721b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
722b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void bnvc(Register rs, Register rt, int16_t offset);
723b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void bnvc(Register rs, Register rt, Label* L) {
724b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    bnvc(rs, rt, branch_offset_compact(L, false)>>2);
725b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
726b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
727b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Never use the int16_t b(l)cond version with a branch offset
728b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // instead of using the Label* version.
729b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
730b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Jump targets must be in the current 256 MB-aligned region. i.e. 28 bits.
731b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void j(int64_t target);
732b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void jal(int64_t target);
733b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void jalr(Register rs, Register rd = ra);
734b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void jr(Register target);
735b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void j_or_jr(int64_t target, Register rs);
736b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void jal_or_jalr(int64_t target, Register rs);
737b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
738b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
739b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // -------Data-processing-instructions---------
740b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
741b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Arithmetic.
742b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void addu(Register rd, Register rs, Register rt);
743b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void subu(Register rd, Register rs, Register rt);
744b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
745b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void div(Register rs, Register rt);
746b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void divu(Register rs, Register rt);
747b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void ddiv(Register rs, Register rt);
748b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void ddivu(Register rs, Register rt);
749b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void div(Register rd, Register rs, Register rt);
750b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void divu(Register rd, Register rs, Register rt);
751b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void ddiv(Register rd, Register rs, Register rt);
752b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void ddivu(Register rd, Register rs, Register rt);
753b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void mod(Register rd, Register rs, Register rt);
754b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void modu(Register rd, Register rs, Register rt);
755b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void dmod(Register rd, Register rs, Register rt);
756b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void dmodu(Register rd, Register rs, Register rt);
757b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
758b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void mul(Register rd, Register rs, Register rt);
759b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void muh(Register rd, Register rs, Register rt);
760b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void mulu(Register rd, Register rs, Register rt);
761b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void muhu(Register rd, Register rs, Register rt);
762b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void mult(Register rs, Register rt);
763b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void multu(Register rs, Register rt);
764b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void dmul(Register rd, Register rs, Register rt);
765b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void dmuh(Register rd, Register rs, Register rt);
766b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void dmulu(Register rd, Register rs, Register rt);
767b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void dmuhu(Register rd, Register rs, Register rt);
768b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void daddu(Register rd, Register rs, Register rt);
769b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void dsubu(Register rd, Register rs, Register rt);
770b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void dmult(Register rs, Register rt);
771b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void dmultu(Register rs, Register rt);
772b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
773b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void addiu(Register rd, Register rs, int32_t j);
774b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void daddiu(Register rd, Register rs, int32_t j);
775b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
776b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Logical.
777b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void and_(Register rd, Register rs, Register rt);
778b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void or_(Register rd, Register rs, Register rt);
779b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void xor_(Register rd, Register rs, Register rt);
780b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void nor(Register rd, Register rs, Register rt);
781b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
782b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void andi(Register rd, Register rs, int32_t j);
783b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void ori(Register rd, Register rs, int32_t j);
784b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void xori(Register rd, Register rs, int32_t j);
785b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void lui(Register rd, int32_t j);
786b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void aui(Register rs, Register rt, int32_t j);
787b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void daui(Register rs, Register rt, int32_t j);
788b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void dahi(Register rs, int32_t j);
789b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void dati(Register rs, int32_t j);
790b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
791b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Shifts.
792b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Please note: sll(zero_reg, zero_reg, x) instructions are reserved as nop
793b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // and may cause problems in normal code. coming_from_nop makes sure this
794b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // doesn't happen.
795b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void sll(Register rd, Register rt, uint16_t sa, bool coming_from_nop = false);
796b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void sllv(Register rd, Register rt, Register rs);
797b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void srl(Register rd, Register rt, uint16_t sa);
798b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void srlv(Register rd, Register rt, Register rs);
799b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void sra(Register rt, Register rd, uint16_t sa);
800b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void srav(Register rt, Register rd, Register rs);
801b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void rotr(Register rd, Register rt, uint16_t sa);
802b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void rotrv(Register rd, Register rt, Register rs);
803b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void dsll(Register rd, Register rt, uint16_t sa);
804b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void dsllv(Register rd, Register rt, Register rs);
805b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void dsrl(Register rd, Register rt, uint16_t sa);
806b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void dsrlv(Register rd, Register rt, Register rs);
807b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void drotr(Register rd, Register rt, uint16_t sa);
808b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void drotrv(Register rd, Register rt, Register rs);
809b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void dsra(Register rt, Register rd, uint16_t sa);
810b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void dsrav(Register rd, Register rt, Register rs);
811b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void dsll32(Register rt, Register rd, uint16_t sa);
812b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void dsrl32(Register rt, Register rd, uint16_t sa);
813b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void dsra32(Register rt, Register rd, uint16_t sa);
814b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
815b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
816b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // ------------Memory-instructions-------------
817b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
818b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void lb(Register rd, const MemOperand& rs);
819b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void lbu(Register rd, const MemOperand& rs);
820b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void lh(Register rd, const MemOperand& rs);
821b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void lhu(Register rd, const MemOperand& rs);
822b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void lw(Register rd, const MemOperand& rs);
823b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void lwu(Register rd, const MemOperand& rs);
824b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void lwl(Register rd, const MemOperand& rs);
825b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void lwr(Register rd, const MemOperand& rs);
826b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void sb(Register rd, const MemOperand& rs);
827b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void sh(Register rd, const MemOperand& rs);
828b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void sw(Register rd, const MemOperand& rs);
829b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void swl(Register rd, const MemOperand& rs);
830b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void swr(Register rd, const MemOperand& rs);
831b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void ldl(Register rd, const MemOperand& rs);
832b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void ldr(Register rd, const MemOperand& rs);
833b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void sdl(Register rd, const MemOperand& rs);
834b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void sdr(Register rd, const MemOperand& rs);
835b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void ld(Register rd, const MemOperand& rs);
836b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void sd(Register rd, const MemOperand& rs);
837b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
838b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
839b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // ----------------Prefetch--------------------
840b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
841b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void pref(int32_t hint, const MemOperand& rs);
842b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
843b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
844b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // -------------Misc-instructions--------------
845b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
846b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Break / Trap instructions.
847b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void break_(uint32_t code, bool break_as_stop = false);
848b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void stop(const char* msg, uint32_t code = kMaxStopCode);
849b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void tge(Register rs, Register rt, uint16_t code);
850b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void tgeu(Register rs, Register rt, uint16_t code);
851b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void tlt(Register rs, Register rt, uint16_t code);
852b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void tltu(Register rs, Register rt, uint16_t code);
853b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void teq(Register rs, Register rt, uint16_t code);
854b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void tne(Register rs, Register rt, uint16_t code);
855b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
856b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Move from HI/LO register.
857b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void mfhi(Register rd);
858b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void mflo(Register rd);
859b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
860b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Set on less than.
861b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void slt(Register rd, Register rs, Register rt);
862b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void sltu(Register rd, Register rs, Register rt);
863b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void slti(Register rd, Register rs, int32_t j);
864b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void sltiu(Register rd, Register rs, int32_t j);
865b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
866b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Conditional move.
867b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void movz(Register rd, Register rs, Register rt);
868b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void movn(Register rd, Register rs, Register rt);
869b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void movt(Register rd, Register rs, uint16_t cc = 0);
870b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void movf(Register rd, Register rs, uint16_t cc = 0);
871b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
872b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void sel(SecondaryField fmt, FPURegister fd, FPURegister ft,
873b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      FPURegister fs, uint8_t sel);
874b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void seleqz(Register rs, Register rt, Register rd);
875b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void seleqz(SecondaryField fmt, FPURegister fd, FPURegister ft,
876b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      FPURegister fs);
877b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void selnez(Register rs, Register rt, Register rd);
878b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void selnez(SecondaryField fmt, FPURegister fd, FPURegister ft,
879b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      FPURegister fs);
880b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
881b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Bit twiddling.
882b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void clz(Register rd, Register rs);
883b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void ins_(Register rt, Register rs, uint16_t pos, uint16_t size);
884b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void ext_(Register rt, Register rs, uint16_t pos, uint16_t size);
885b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
886b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // --------Coprocessor-instructions----------------
887b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
888b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Load, store, and move.
889b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void lwc1(FPURegister fd, const MemOperand& src);
890b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void ldc1(FPURegister fd, const MemOperand& src);
891b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
892b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void swc1(FPURegister fs, const MemOperand& dst);
893b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void sdc1(FPURegister fs, const MemOperand& dst);
894b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
895b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void mtc1(Register rt, FPURegister fs);
896b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void mthc1(Register rt, FPURegister fs);
897b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void dmtc1(Register rt, FPURegister fs);
898b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
899b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void mfc1(Register rt, FPURegister fs);
900b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void mfhc1(Register rt, FPURegister fs);
901b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void dmfc1(Register rt, FPURegister fs);
902b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
903b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void ctc1(Register rt, FPUControlRegister fs);
904b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void cfc1(Register rt, FPUControlRegister fs);
905b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
906b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Arithmetic.
907b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void add_d(FPURegister fd, FPURegister fs, FPURegister ft);
908b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void sub_d(FPURegister fd, FPURegister fs, FPURegister ft);
909b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void mul_d(FPURegister fd, FPURegister fs, FPURegister ft);
910b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void madd_d(FPURegister fd, FPURegister fr, FPURegister fs, FPURegister ft);
911b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void div_d(FPURegister fd, FPURegister fs, FPURegister ft);
912b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void abs_d(FPURegister fd, FPURegister fs);
913b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void mov_d(FPURegister fd, FPURegister fs);
914b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void neg_d(FPURegister fd, FPURegister fs);
915b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void sqrt_d(FPURegister fd, FPURegister fs);
916b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
917b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Conversion.
918b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void cvt_w_s(FPURegister fd, FPURegister fs);
919b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void cvt_w_d(FPURegister fd, FPURegister fs);
920b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void trunc_w_s(FPURegister fd, FPURegister fs);
921b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void trunc_w_d(FPURegister fd, FPURegister fs);
922b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void round_w_s(FPURegister fd, FPURegister fs);
923b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void round_w_d(FPURegister fd, FPURegister fs);
924b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void floor_w_s(FPURegister fd, FPURegister fs);
925b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void floor_w_d(FPURegister fd, FPURegister fs);
926b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void ceil_w_s(FPURegister fd, FPURegister fs);
927b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void ceil_w_d(FPURegister fd, FPURegister fs);
928b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
929b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void cvt_l_s(FPURegister fd, FPURegister fs);
930b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void cvt_l_d(FPURegister fd, FPURegister fs);
931b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void trunc_l_s(FPURegister fd, FPURegister fs);
932b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void trunc_l_d(FPURegister fd, FPURegister fs);
933b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void round_l_s(FPURegister fd, FPURegister fs);
934b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void round_l_d(FPURegister fd, FPURegister fs);
935b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void floor_l_s(FPURegister fd, FPURegister fs);
936b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void floor_l_d(FPURegister fd, FPURegister fs);
937b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void ceil_l_s(FPURegister fd, FPURegister fs);
938b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void ceil_l_d(FPURegister fd, FPURegister fs);
939b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
940b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void min(SecondaryField fmt, FPURegister fd, FPURegister ft, FPURegister fs);
941b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void mina(SecondaryField fmt, FPURegister fd, FPURegister ft, FPURegister fs);
942b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void max(SecondaryField fmt, FPURegister fd, FPURegister ft, FPURegister fs);
943b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void maxa(SecondaryField fmt, FPURegister fd, FPURegister ft, FPURegister fs);
944b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
945b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void cvt_s_w(FPURegister fd, FPURegister fs);
946b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void cvt_s_l(FPURegister fd, FPURegister fs);
947b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void cvt_s_d(FPURegister fd, FPURegister fs);
948b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
949b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void cvt_d_w(FPURegister fd, FPURegister fs);
950b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void cvt_d_l(FPURegister fd, FPURegister fs);
951b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void cvt_d_s(FPURegister fd, FPURegister fs);
952b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
953b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Conditions and branches for MIPSr6.
954b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void cmp(FPUCondition cond, SecondaryField fmt,
955b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch         FPURegister fd, FPURegister ft, FPURegister fs);
956b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
957b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void bc1eqz(int16_t offset, FPURegister ft);
958b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void bc1eqz(Label* L, FPURegister ft) {
959b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    bc1eqz(branch_offset(L, false)>>2, ft);
960b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
961b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void bc1nez(int16_t offset, FPURegister ft);
962b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void bc1nez(Label* L, FPURegister ft) {
963b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    bc1nez(branch_offset(L, false)>>2, ft);
964b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
965b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
966b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Conditions and branches for non MIPSr6.
967b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void c(FPUCondition cond, SecondaryField fmt,
968b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch         FPURegister ft, FPURegister fs, uint16_t cc = 0);
969b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
970b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void bc1f(int16_t offset, uint16_t cc = 0);
971b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void bc1f(Label* L, uint16_t cc = 0) {
972b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    bc1f(branch_offset(L, false)>>2, cc);
973b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
974b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void bc1t(int16_t offset, uint16_t cc = 0);
975b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void bc1t(Label* L, uint16_t cc = 0) {
976b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    bc1t(branch_offset(L, false)>>2, cc);
977b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
978b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void fcmp(FPURegister src1, const double src2, FPUCondition cond);
979b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
980b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Check the code size generated from label to here.
981b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int SizeOfCodeGeneratedSince(Label* label) {
982b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return pc_offset() - label->pos();
983b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
984b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
985b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Check the number of instructions generated from label to here.
986b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int InstructionsGeneratedSince(Label* label) {
987b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return SizeOfCodeGeneratedSince(label) / kInstrSize;
988b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
989b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
990b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Class for scoping postponing the trampoline pool generation.
991b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  class BlockTrampolinePoolScope {
992b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch   public:
993b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    explicit BlockTrampolinePoolScope(Assembler* assem) : assem_(assem) {
994b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      assem_->StartBlockTrampolinePool();
995b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
996b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    ~BlockTrampolinePoolScope() {
997b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      assem_->EndBlockTrampolinePool();
998b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
999b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1000b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch   private:
1001b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Assembler* assem_;
1002b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1003b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DISALLOW_IMPLICIT_CONSTRUCTORS(BlockTrampolinePoolScope);
1004b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  };
1005b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1006b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Class for postponing the assembly buffer growth. Typically used for
1007b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // sequences of instructions that must be emitted as a unit, before
1008b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // buffer growth (and relocation) can occur.
1009b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // This blocking scope is not nestable.
1010b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  class BlockGrowBufferScope {
1011b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch   public:
1012b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    explicit BlockGrowBufferScope(Assembler* assem) : assem_(assem) {
1013b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      assem_->StartBlockGrowBuffer();
1014b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
1015b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    ~BlockGrowBufferScope() {
1016b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      assem_->EndBlockGrowBuffer();
1017b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
1018b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1019b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch   private:
1020b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Assembler* assem_;
1021b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1022b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DISALLOW_IMPLICIT_CONSTRUCTORS(BlockGrowBufferScope);
1023b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  };
1024b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1025b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Debugging.
1026b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1027b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Mark address of the ExitJSFrame code.
1028b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void RecordJSReturn();
1029b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1030b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Mark address of a debug break slot.
1031b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void RecordDebugBreakSlot();
1032b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1033b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Record the AST id of the CallIC being compiled, so that it can be placed
1034b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // in the relocation information.
1035b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void SetRecordedAstId(TypeFeedbackId ast_id) {
1036b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(recorded_ast_id_.IsNone());
1037b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    recorded_ast_id_ = ast_id;
1038b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1039b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1040b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  TypeFeedbackId RecordedAstId() {
1041b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(!recorded_ast_id_.IsNone());
1042b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return recorded_ast_id_;
1043b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1044b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1045b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void ClearRecordedAstId() { recorded_ast_id_ = TypeFeedbackId::None(); }
1046b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1047b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Record a comment relocation entry that can be used by a disassembler.
1048b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Use --code-comments to enable.
1049b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void RecordComment(const char* msg);
1050b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1051b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static int RelocateInternalReference(byte* pc, intptr_t pc_delta);
1052b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1053b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Writes a single byte or word of data in the code stream.  Used for
1054b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // inline tables, e.g., jump-tables.
1055b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void db(uint8_t data);
1056b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void dd(uint32_t data);
1057b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1058b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Emits the address of the code stub's first instruction.
1059b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void emit_code_stub_address(Code* stub);
1060b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1061b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  PositionsRecorder* positions_recorder() { return &positions_recorder_; }
1062b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1063b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Postpone the generation of the trampoline pool for the specified number of
1064b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // instructions.
1065b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void BlockTrampolinePoolFor(int instructions);
1066b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1067b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Check if there is less than kGap bytes available in the buffer.
1068b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // If this is the case, we need to grow the buffer before emitting
1069b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // an instruction or relocation information.
1070b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  inline bool overflow() const { return pc_ >= reloc_info_writer.pos() - kGap; }
1071b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1072b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Get the number of bytes available in the buffer.
1073b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  inline int available_space() const { return reloc_info_writer.pos() - pc_; }
1074b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1075b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Read/patch instructions.
1076b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static Instr instr_at(byte* pc) { return *reinterpret_cast<Instr*>(pc); }
1077b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static void instr_at_put(byte* pc, Instr instr) {
1078b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    *reinterpret_cast<Instr*>(pc) = instr;
1079b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1080b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Instr instr_at(int pos) { return *reinterpret_cast<Instr*>(buffer_ + pos); }
1081b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void instr_at_put(int pos, Instr instr) {
1082b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    *reinterpret_cast<Instr*>(buffer_ + pos) = instr;
1083b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1084b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1085b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Check if an instruction is a branch of some kind.
1086b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static bool IsBranch(Instr instr);
1087b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static bool IsBeq(Instr instr);
1088b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static bool IsBne(Instr instr);
1089b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1090b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static bool IsJump(Instr instr);
1091b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static bool IsJ(Instr instr);
1092b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static bool IsLui(Instr instr);
1093b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static bool IsOri(Instr instr);
1094b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1095b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static bool IsJal(Instr instr);
1096b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static bool IsJr(Instr instr);
1097b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static bool IsJalr(Instr instr);
1098b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1099b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static bool IsNop(Instr instr, unsigned int type);
1100b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static bool IsPop(Instr instr);
1101b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static bool IsPush(Instr instr);
1102b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static bool IsLwRegFpOffset(Instr instr);
1103b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static bool IsSwRegFpOffset(Instr instr);
1104b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static bool IsLwRegFpNegOffset(Instr instr);
1105b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static bool IsSwRegFpNegOffset(Instr instr);
1106b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1107b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static Register GetRtReg(Instr instr);
1108b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static Register GetRsReg(Instr instr);
1109b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static Register GetRdReg(Instr instr);
1110b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1111b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static uint32_t GetRt(Instr instr);
1112b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static uint32_t GetRtField(Instr instr);
1113b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static uint32_t GetRs(Instr instr);
1114b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static uint32_t GetRsField(Instr instr);
1115b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static uint32_t GetRd(Instr instr);
1116b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static uint32_t GetRdField(Instr instr);
1117b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static uint32_t GetSa(Instr instr);
1118b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static uint32_t GetSaField(Instr instr);
1119b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static uint32_t GetOpcodeField(Instr instr);
1120b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static uint32_t GetFunction(Instr instr);
1121b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static uint32_t GetFunctionField(Instr instr);
1122b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static uint32_t GetImmediate16(Instr instr);
1123b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static uint32_t GetLabelConst(Instr instr);
1124b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1125b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static int32_t GetBranchOffset(Instr instr);
1126b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static bool IsLw(Instr instr);
1127b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static int16_t GetLwOffset(Instr instr);
1128b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static Instr SetLwOffset(Instr instr, int16_t offset);
1129b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1130b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static bool IsSw(Instr instr);
1131b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static Instr SetSwOffset(Instr instr, int16_t offset);
1132b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static bool IsAddImmediate(Instr instr);
1133b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static Instr SetAddImmediateOffset(Instr instr, int16_t offset);
1134b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1135b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static bool IsAndImmediate(Instr instr);
1136b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static bool IsEmittedConstant(Instr instr);
1137b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1138b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void CheckTrampolinePool();
1139b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1140b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Allocate a constant pool of the correct size for the generated code.
1141b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Handle<ConstantPoolArray> NewConstantPool(Isolate* isolate);
1142b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1143b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Generate the constant pool for the generated code.
1144b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void PopulateConstantPool(ConstantPoolArray* constant_pool);
1145b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1146b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch protected:
1147b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Relocation for a type-recording IC has the AST id added to it.  This
1148b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // member variable is a way to pass the information from the call site to
1149b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // the relocation info.
1150b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  TypeFeedbackId recorded_ast_id_;
1151b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1152b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int64_t buffer_space() const { return reloc_info_writer.pos() - pc_; }
1153b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1154b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Decode branch instruction at pos and return branch target pos.
1155b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int64_t target_at(int64_t pos);
1156b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1157b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Patch branch instruction at pos to branch to given branch target pos.
1158b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void target_at_put(int64_t pos, int64_t target_pos);
1159b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1160b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Say if we need to relocate with this mode.
1161b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bool MustUseReg(RelocInfo::Mode rmode);
1162b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1163b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Record reloc info for current pc_.
1164b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void RecordRelocInfo(RelocInfo::Mode rmode, intptr_t data = 0);
1165b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1166b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Block the emission of the trampoline pool before pc_offset.
1167b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void BlockTrampolinePoolBefore(int pc_offset) {
1168b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (no_trampoline_pool_before_ < pc_offset)
1169b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      no_trampoline_pool_before_ = pc_offset;
1170b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1171b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1172b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void StartBlockTrampolinePool() {
1173b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    trampoline_pool_blocked_nesting_++;
1174b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1175b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1176b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void EndBlockTrampolinePool() {
1177b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    trampoline_pool_blocked_nesting_--;
1178b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1179b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1180b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bool is_trampoline_pool_blocked() const {
1181b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return trampoline_pool_blocked_nesting_ > 0;
1182b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1183b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1184b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bool has_exception() const {
1185b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return internal_trampoline_exception_;
1186b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1187b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1188b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void DoubleAsTwoUInt32(double d, uint32_t* lo, uint32_t* hi);
1189b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1190b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bool is_trampoline_emitted() const {
1191b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return trampoline_emitted_;
1192b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1193b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1194b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Temporarily block automatic assembly buffer growth.
1195b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void StartBlockGrowBuffer() {
1196b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(!block_buffer_growth_);
1197b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    block_buffer_growth_ = true;
1198b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1199b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1200b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void EndBlockGrowBuffer() {
1201b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(block_buffer_growth_);
1202b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    block_buffer_growth_ = false;
1203b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1204b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1205b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bool is_buffer_growth_blocked() const {
1206b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return block_buffer_growth_;
1207b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1208b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1209b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch private:
1210b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Buffer size and constant pool distance are checked together at regular
1211b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // intervals of kBufferCheckInterval emitted bytes.
1212b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static const int kBufferCheckInterval = 1*KB/2;
1213b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1214b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Code generation.
1215b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // The relocation writer's position is at least kGap bytes below the end of
1216b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // the generated instructions. This is so that multi-instruction sequences do
1217b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // not have to check for overflow. The same is true for writes of large
1218b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // relocation info entries.
1219b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static const int kGap = 32;
1220b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1221b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1222b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Repeated checking whether the trampoline pool should be emitted is rather
1223b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // expensive. By default we only check again once a number of instructions
1224b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // has been generated.
1225b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static const int kCheckConstIntervalInst = 32;
1226b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static const int kCheckConstInterval = kCheckConstIntervalInst * kInstrSize;
1227b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1228b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int next_buffer_check_;  // pc offset of next buffer check.
1229b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1230b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Emission of the trampoline pool may be blocked in some code sequences.
1231b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int trampoline_pool_blocked_nesting_;  // Block emission if this is not zero.
1232b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int no_trampoline_pool_before_;  // Block emission before this pc offset.
1233b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1234b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Keep track of the last emitted pool to guarantee a maximal distance.
1235b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int last_trampoline_pool_end_;  // pc offset of the end of the last pool.
1236b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1237b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Automatic growth of the assembly buffer may be blocked for some sequences.
1238b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bool block_buffer_growth_;  // Block growth when true.
1239b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1240b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Relocation information generation.
1241b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Each relocation is encoded as a variable size value.
1242b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static const int kMaxRelocSize = RelocInfoWriter::kMaxSize;
1243b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  RelocInfoWriter reloc_info_writer;
1244b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1245b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // The bound position, before this we cannot do instruction elimination.
1246b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int last_bound_pos_;
1247b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1248b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Code emission.
1249b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  inline void CheckBuffer();
1250b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void GrowBuffer();
1251b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  inline void emit(Instr x);
1252b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  inline void emit(uint64_t x);
1253b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  inline void CheckTrampolinePoolQuick();
1254b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1255b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Instruction generation.
1256b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // We have 3 different kind of encoding layout on MIPS.
1257b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // However due to many different types of objects encoded in the same fields
1258b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // we have quite a few aliases for each mode.
1259b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Using the same structure to refer to Register and FPURegister would spare a
1260b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // few aliases, but mixing both does not look clean to me.
1261b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Anyway we could surely implement this differently.
1262b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1263b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void GenInstrRegister(Opcode opcode,
1264b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                        Register rs,
1265b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                        Register rt,
1266b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                        Register rd,
1267b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                        uint16_t sa = 0,
1268b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                        SecondaryField func = NULLSF);
1269b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1270b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void GenInstrRegister(Opcode opcode,
1271b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                        Register rs,
1272b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                        Register rt,
1273b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                        uint16_t msb,
1274b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                        uint16_t lsb,
1275b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                        SecondaryField func);
1276b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1277b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void GenInstrRegister(Opcode opcode,
1278b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                        SecondaryField fmt,
1279b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                        FPURegister ft,
1280b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                        FPURegister fs,
1281b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                        FPURegister fd,
1282b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                        SecondaryField func = NULLSF);
1283b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1284b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void GenInstrRegister(Opcode opcode,
1285b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                        FPURegister fr,
1286b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                        FPURegister ft,
1287b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                        FPURegister fs,
1288b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                        FPURegister fd,
1289b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                        SecondaryField func = NULLSF);
1290b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1291b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void GenInstrRegister(Opcode opcode,
1292b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                        SecondaryField fmt,
1293b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                        Register rt,
1294b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                        FPURegister fs,
1295b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                        FPURegister fd,
1296b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                        SecondaryField func = NULLSF);
1297b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1298b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void GenInstrRegister(Opcode opcode,
1299b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                        SecondaryField fmt,
1300b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                        Register rt,
1301b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                        FPUControlRegister fs,
1302b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                        SecondaryField func = NULLSF);
1303b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1304b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1305b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void GenInstrImmediate(Opcode opcode,
1306b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                         Register rs,
1307b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                         Register rt,
1308b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                         int32_t  j);
1309b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void GenInstrImmediate(Opcode opcode,
1310b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                         Register rs,
1311b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                         SecondaryField SF,
1312b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                         int32_t  j);
1313b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void GenInstrImmediate(Opcode opcode,
1314b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                         Register r1,
1315b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                         FPURegister r2,
1316b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                         int32_t  j);
1317b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1318b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1319b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void GenInstrJump(Opcode opcode,
1320b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                     uint32_t address);
1321b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1322b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Helpers.
1323b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void LoadRegPlusOffsetToAt(const MemOperand& src);
1324b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1325b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Labels.
1326b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void print(Label* L);
1327b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void bind_to(Label* L, int pos);
1328b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void next(Label* L);
1329b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1330b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // One trampoline consists of:
1331b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // - space for trampoline slots,
1332b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // - space for labels.
1333b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  //
1334b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Space for trampoline slots is equal to slot_count * 2 * kInstrSize.
1335b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Space for trampoline slots preceeds space for labels. Each label is of one
1336b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // instruction size, so total amount for labels is equal to
1337b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // label_count *  kInstrSize.
1338b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  class Trampoline {
1339b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch   public:
1340b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Trampoline() {
1341b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      start_ = 0;
1342b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      next_slot_ = 0;
1343b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      free_slot_count_ = 0;
1344b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      end_ = 0;
1345b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
1346b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Trampoline(int start, int slot_count) {
1347b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      start_ = start;
1348b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      next_slot_ = start;
1349b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      free_slot_count_ = slot_count;
1350b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      end_ = start + slot_count * kTrampolineSlotsSize;
1351b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
1352b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    int start() {
1353b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      return start_;
1354b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
1355b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    int end() {
1356b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      return end_;
1357b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
1358b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    int take_slot() {
1359b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      int trampoline_slot = kInvalidSlotPos;
1360b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      if (free_slot_count_ <= 0) {
1361b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        // We have run out of space on trampolines.
1362b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        // Make sure we fail in debug mode, so we become aware of each case
1363b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        // when this happens.
1364b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        DCHECK(0);
1365b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        // Internal exception will be caught.
1366b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      } else {
1367b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        trampoline_slot = next_slot_;
1368b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        free_slot_count_--;
1369b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        next_slot_ += kTrampolineSlotsSize;
1370b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
1371b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      return trampoline_slot;
1372b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
1373b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1374b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch   private:
1375b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    int start_;
1376b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    int end_;
1377b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    int next_slot_;
1378b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    int free_slot_count_;
1379b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  };
1380b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1381b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int32_t get_trampoline_entry(int32_t pos);
1382b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int unbound_labels_count_;
1383b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // If trampoline is emitted, generated code is becoming large. As this is
1384b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // already a slow case which can possibly break our code generation for the
1385b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // extreme case, we use this information to trigger different mode of
1386b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // branch instruction generation, where we use jump instructions rather
1387b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // than regular branch instructions.
1388b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bool trampoline_emitted_;
1389b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static const int kTrampolineSlotsSize = 6 * kInstrSize;
1390b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static const int kMaxBranchOffset = (1 << (18 - 1)) - 1;
1391b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static const int kInvalidSlotPos = -1;
1392b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1393b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Trampoline trampoline_;
1394b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bool internal_trampoline_exception_;
1395b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1396b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  friend class RegExpMacroAssemblerMIPS;
1397b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  friend class RelocInfo;
1398b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  friend class CodePatcher;
1399b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  friend class BlockTrampolinePoolScope;
1400b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1401b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  PositionsRecorder positions_recorder_;
1402b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  friend class PositionsRecorder;
1403b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  friend class EnsureSpace;
1404b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch};
1405b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1406b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1407b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass EnsureSpace BASE_EMBEDDED {
1408b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch public:
1409b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  explicit EnsureSpace(Assembler* assembler) {
1410b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    assembler->CheckBuffer();
1411b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1412b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch};
1413b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1414b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} }  // namespace v8::internal
1415b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1416b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#endif  // V8_ARM_ASSEMBLER_MIPS_H_
1417