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#include "src/v8.h"
37b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
38b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#if V8_TARGET_ARCH_MIPS64
39b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
40b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/base/cpu.h"
41b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/mips64/assembler-mips64-inl.h"
42b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/serialize.h"
43b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
44b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochnamespace v8 {
45b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochnamespace internal {
46b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
47b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
48b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Get the CPU features enabled by the build. For cross compilation the
49b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// preprocessor symbols CAN_USE_FPU_INSTRUCTIONS
50b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// can be defined to enable FPU instructions when building the
51b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// snapshot.
52b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochstatic unsigned CpuFeaturesImpliedByCompiler() {
53b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  unsigned answer = 0;
54b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#ifdef CAN_USE_FPU_INSTRUCTIONS
55b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  answer |= 1u << FPU;
56b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#endif  // def CAN_USE_FPU_INSTRUCTIONS
57b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
58b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // If the compiler is allowed to use FPU then we can use FPU too in our code
59b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // generation even when generating snapshots.  This won't work for cross
60b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // compilation.
61b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#if defined(__mips__) && defined(__mips_hard_float) && __mips_hard_float != 0
62b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  answer |= 1u << FPU;
63b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#endif
64b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
65b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return answer;
66b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
67b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
68b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
69b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochconst char* DoubleRegister::AllocationIndexToString(int index) {
70b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(index >= 0 && index < kMaxNumAllocatableRegisters);
71b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  const char* const names[] = {
72b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    "f0",
73b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    "f2",
74b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    "f4",
75b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    "f6",
76b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    "f8",
77b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    "f10",
78b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    "f12",
79b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    "f14",
80b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    "f16",
81b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    "f18",
82b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    "f20",
83b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    "f22",
84b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    "f24",
85b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    "f26"
86b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  };
87b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return names[index];
88b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
89b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
90b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
91b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid CpuFeatures::ProbeImpl(bool cross_compile) {
92b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  supported_ |= CpuFeaturesImpliedByCompiler();
93b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
94b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Only use statically determined features for cross compile (snapshot).
95b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (cross_compile) return;
96b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
97b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // If the compiler is allowed to use fpu then we can use fpu too in our
98b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // code generation.
99b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#ifndef __mips__
100b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // For the simulator build, use FPU.
101b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  supported_ |= 1u << FPU;
102b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#else
103b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Probe for additional features at runtime.
104b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  base::CPU cpu;
105b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (cpu.has_fpu()) supported_ |= 1u << FPU;
106b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#endif
107b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
108b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
109b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
110b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid CpuFeatures::PrintTarget() { }
111b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid CpuFeatures::PrintFeatures() { }
112b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
113b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
114b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochint ToNumber(Register reg) {
115b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(reg.is_valid());
116b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  const int kNumbers[] = {
117b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    0,    // zero_reg
118b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    1,    // at
119b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    2,    // v0
120b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    3,    // v1
121b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    4,    // a0
122b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    5,    // a1
123b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    6,    // a2
124b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    7,    // a3
125b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    8,    // a4
126b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    9,    // a5
127b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    10,   // a6
128b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    11,   // a7
129b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    12,   // t0
130b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    13,   // t1
131b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    14,   // t2
132b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    15,   // t3
133b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    16,   // s0
134b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    17,   // s1
135b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    18,   // s2
136b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    19,   // s3
137b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    20,   // s4
138b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    21,   // s5
139b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    22,   // s6
140b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    23,   // s7
141b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    24,   // t8
142b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    25,   // t9
143b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    26,   // k0
144b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    27,   // k1
145b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    28,   // gp
146b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    29,   // sp
147b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    30,   // fp
148b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    31,   // ra
149b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  };
150b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return kNumbers[reg.code()];
151b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
152b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
153b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
154b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochRegister ToRegister(int num) {
155b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(num >= 0 && num < kNumRegisters);
156b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  const Register kRegisters[] = {
157b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    zero_reg,
158b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    at,
159b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    v0, v1,
160b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    a0, a1, a2, a3, a4, a5, a6, a7,
161b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    t0, t1, t2, t3,
162b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    s0, s1, s2, s3, s4, s5, s6, s7,
163b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    t8, t9,
164b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    k0, k1,
165b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    gp,
166b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    sp,
167b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    fp,
168b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    ra
169b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  };
170b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return kRegisters[num];
171b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
172b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
173b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
174b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// -----------------------------------------------------------------------------
175b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Implementation of RelocInfo.
176b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
177b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochconst int RelocInfo::kApplyMask = RelocInfo::kCodeTargetMask |
178b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                  1 << RelocInfo::INTERNAL_REFERENCE;
179b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
180b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
181b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochbool RelocInfo::IsCodedSpecially() {
182b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // The deserializer needs to know whether a pointer is specially coded.  Being
183b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // specially coded on MIPS means that it is a lui/ori instruction, and that is
184b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // always the case inside code objects.
185b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return true;
186b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
187b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
188b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
189b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochbool RelocInfo::IsInConstantPool() {
190b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return false;
191b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
192b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
193b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
194b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Patch the code at the current address with the supplied instructions.
195b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid RelocInfo::PatchCode(byte* instructions, int instruction_count) {
196b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Instr* pc = reinterpret_cast<Instr*>(pc_);
197b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Instr* instr = reinterpret_cast<Instr*>(instructions);
198b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  for (int i = 0; i < instruction_count; i++) {
199b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    *(pc + i) = *(instr + i);
200b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
201b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
202b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Indicate that code has changed.
203b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  CpuFeatures::FlushICache(pc_, instruction_count * Assembler::kInstrSize);
204b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
205b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
206b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
207b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Patch the code at the current PC with a call to the target address.
208b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Additional guard instructions can be added if required.
209b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid RelocInfo::PatchCodeWithCall(Address target, int guard_bytes) {
210b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Patch the code at the current address with a call to the target.
211b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  UNIMPLEMENTED_MIPS();
212b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
213b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
214b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
215b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// -----------------------------------------------------------------------------
216b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Implementation of Operand and MemOperand.
217b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// See assembler-mips-inl.h for inlined constructors.
218b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
219b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochOperand::Operand(Handle<Object> handle) {
220b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  AllowDeferredHandleDereference using_raw_address;
221b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  rm_ = no_reg;
222b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Verify all Objects referred by code are NOT in new space.
223b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Object* obj = *handle;
224b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (obj->IsHeapObject()) {
225b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(!HeapObject::cast(obj)->GetHeap()->InNewSpace(obj));
226b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    imm64_ = reinterpret_cast<intptr_t>(handle.location());
227b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    rmode_ = RelocInfo::EMBEDDED_OBJECT;
228b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } else {
229b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // No relocation needed.
230b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    imm64_ = reinterpret_cast<intptr_t>(obj);
231b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    rmode_ = RelocInfo::NONE64;
232b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
233b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
234b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
235b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
236b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochMemOperand::MemOperand(Register rm, int64_t offset) : Operand(rm) {
237b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  offset_ = offset;
238b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
239b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
240b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
241b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochMemOperand::MemOperand(Register rm, int64_t unit, int64_t multiplier,
242b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                       OffsetAddend offset_addend) : Operand(rm) {
243b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  offset_ = unit * multiplier + offset_addend;
244b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
245b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
246b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
247b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// -----------------------------------------------------------------------------
248b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Specific instructions, constants, and masks.
249b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
250b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochstatic const int kNegOffset = 0x00008000;
251b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// daddiu(sp, sp, 8) aka Pop() operation or part of Pop(r)
252b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// operations as post-increment of sp.
253b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochconst Instr kPopInstruction = DADDIU | (kRegister_sp_Code << kRsShift)
254b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      | (kRegister_sp_Code << kRtShift)
255b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      | (kPointerSize & kImm16Mask);  // NOLINT
256b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// daddiu(sp, sp, -8) part of Push(r) operation as pre-decrement of sp.
257b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochconst Instr kPushInstruction = DADDIU | (kRegister_sp_Code << kRsShift)
258b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      | (kRegister_sp_Code << kRtShift)
259b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      | (-kPointerSize & kImm16Mask);  // NOLINT
260b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// sd(r, MemOperand(sp, 0))
261b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochconst Instr kPushRegPattern = SD | (kRegister_sp_Code << kRsShift)
262b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      |  (0 & kImm16Mask);  // NOLINT
263b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch//  ld(r, MemOperand(sp, 0))
264b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochconst Instr kPopRegPattern = LD | (kRegister_sp_Code << kRsShift)
265b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      |  (0 & kImm16Mask);  // NOLINT
266b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
267b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochconst Instr kLwRegFpOffsetPattern = LW | (kRegister_fp_Code << kRsShift)
268b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      |  (0 & kImm16Mask);  // NOLINT
269b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
270b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochconst Instr kSwRegFpOffsetPattern = SW | (kRegister_fp_Code << kRsShift)
271b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      |  (0 & kImm16Mask);  // NOLINT
272b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
273b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochconst Instr kLwRegFpNegOffsetPattern = LW | (kRegister_fp_Code << kRsShift)
274b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      |  (kNegOffset & kImm16Mask);  // NOLINT
275b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
276b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochconst Instr kSwRegFpNegOffsetPattern = SW | (kRegister_fp_Code << kRsShift)
277b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      |  (kNegOffset & kImm16Mask);  // NOLINT
278b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// A mask for the Rt register for push, pop, lw, sw instructions.
279b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochconst Instr kRtMask = kRtFieldMask;
280b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochconst Instr kLwSwInstrTypeMask = 0xffe00000;
281b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochconst Instr kLwSwInstrArgumentMask  = ~kLwSwInstrTypeMask;
282b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochconst Instr kLwSwOffsetMask = kImm16Mask;
283b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
284b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
285b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochAssembler::Assembler(Isolate* isolate, void* buffer, int buffer_size)
286b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    : AssemblerBase(isolate, buffer, buffer_size),
287b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      recorded_ast_id_(TypeFeedbackId::None()),
288b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      positions_recorder_(this) {
289b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  reloc_info_writer.Reposition(buffer_ + buffer_size_, pc_);
290b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
291b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  last_trampoline_pool_end_ = 0;
292b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  no_trampoline_pool_before_ = 0;
293b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  trampoline_pool_blocked_nesting_ = 0;
294b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // We leave space (16 * kTrampolineSlotsSize)
295b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // for BlockTrampolinePoolScope buffer.
296b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  next_buffer_check_ = FLAG_force_long_branches
297b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      ? kMaxInt : kMaxBranchOffset - kTrampolineSlotsSize * 16;
298b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  internal_trampoline_exception_ = false;
299b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  last_bound_pos_ = 0;
300b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
301b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  trampoline_emitted_ = FLAG_force_long_branches;
302b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  unbound_labels_count_ = 0;
303b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  block_buffer_growth_ = false;
304b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
305b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  ClearRecordedAstId();
306b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
307b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
308b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
309b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::GetCode(CodeDesc* desc) {
310b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(pc_ <= reloc_info_writer.pos());  // No overlap.
311b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Set up code descriptor.
312b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  desc->buffer = buffer_;
313b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  desc->buffer_size = buffer_size_;
314b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  desc->instr_size = pc_offset();
315b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  desc->reloc_size = (buffer_ + buffer_size_) - reloc_info_writer.pos();
316b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  desc->origin = this;
317b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
318b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
319b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
320b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::Align(int m) {
321b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(m >= 4 && base::bits::IsPowerOfTwo32(m));
322b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  while ((pc_offset() & (m - 1)) != 0) {
323b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    nop();
324b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
325b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
326b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
327b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
328b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::CodeTargetAlign() {
329b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // No advantage to aligning branch/call targets to more than
330b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // single instruction, that I am aware of.
331b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Align(4);
332b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
333b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
334b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
335b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochRegister Assembler::GetRtReg(Instr instr) {
336b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Register rt;
337b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  rt.code_ = (instr & kRtFieldMask) >> kRtShift;
338b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return rt;
339b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
340b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
341b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
342b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochRegister Assembler::GetRsReg(Instr instr) {
343b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Register rs;
344b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  rs.code_ = (instr & kRsFieldMask) >> kRsShift;
345b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return rs;
346b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
347b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
348b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
349b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochRegister Assembler::GetRdReg(Instr instr) {
350b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Register rd;
351b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  rd.code_ = (instr & kRdFieldMask) >> kRdShift;
352b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return rd;
353b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
354b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
355b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
356b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochuint32_t Assembler::GetRt(Instr instr) {
357b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return (instr & kRtFieldMask) >> kRtShift;
358b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
359b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
360b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
361b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochuint32_t Assembler::GetRtField(Instr instr) {
362b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return instr & kRtFieldMask;
363b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
364b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
365b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
366b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochuint32_t Assembler::GetRs(Instr instr) {
367b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return (instr & kRsFieldMask) >> kRsShift;
368b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
369b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
370b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
371b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochuint32_t Assembler::GetRsField(Instr instr) {
372b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return instr & kRsFieldMask;
373b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
374b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
375b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
376b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochuint32_t Assembler::GetRd(Instr instr) {
377b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return  (instr & kRdFieldMask) >> kRdShift;
378b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
379b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
380b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
381b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochuint32_t Assembler::GetRdField(Instr instr) {
382b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return  instr & kRdFieldMask;
383b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
384b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
385b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
386b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochuint32_t Assembler::GetSa(Instr instr) {
387b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return (instr & kSaFieldMask) >> kSaShift;
388b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
389b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
390b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
391b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochuint32_t Assembler::GetSaField(Instr instr) {
392b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return instr & kSaFieldMask;
393b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
394b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
395b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
396b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochuint32_t Assembler::GetOpcodeField(Instr instr) {
397b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return instr & kOpcodeMask;
398b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
399b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
400b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
401b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochuint32_t Assembler::GetFunction(Instr instr) {
402b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return (instr & kFunctionFieldMask) >> kFunctionShift;
403b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
404b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
405b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
406b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochuint32_t Assembler::GetFunctionField(Instr instr) {
407b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return instr & kFunctionFieldMask;
408b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
409b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
410b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
411b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochuint32_t Assembler::GetImmediate16(Instr instr) {
412b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return instr & kImm16Mask;
413b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
414b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
415b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
416b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochuint32_t Assembler::GetLabelConst(Instr instr) {
417b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return instr & ~kImm16Mask;
418b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
419b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
420b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
421b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochbool Assembler::IsPop(Instr instr) {
422b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return (instr & ~kRtMask) == kPopRegPattern;
423b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
424b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
425b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
426b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochbool Assembler::IsPush(Instr instr) {
427b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return (instr & ~kRtMask) == kPushRegPattern;
428b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
429b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
430b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
431b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochbool Assembler::IsSwRegFpOffset(Instr instr) {
432b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return ((instr & kLwSwInstrTypeMask) == kSwRegFpOffsetPattern);
433b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
434b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
435b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
436b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochbool Assembler::IsLwRegFpOffset(Instr instr) {
437b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return ((instr & kLwSwInstrTypeMask) == kLwRegFpOffsetPattern);
438b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
439b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
440b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
441b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochbool Assembler::IsSwRegFpNegOffset(Instr instr) {
442b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return ((instr & (kLwSwInstrTypeMask | kNegOffset)) ==
443b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          kSwRegFpNegOffsetPattern);
444b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
445b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
446b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
447b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochbool Assembler::IsLwRegFpNegOffset(Instr instr) {
448b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return ((instr & (kLwSwInstrTypeMask | kNegOffset)) ==
449b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          kLwRegFpNegOffsetPattern);
450b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
451b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
452b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
453b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Labels refer to positions in the (to be) generated code.
454b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// There are bound, linked, and unused labels.
455b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch//
456b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Bound labels refer to known positions in the already
457b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// generated code. pos() is the position the label refers to.
458b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch//
459b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Linked labels refer to unknown positions in the code
460b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// to be generated; pos() is the position of the last
461b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// instruction using the label.
462b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
463b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// The link chain is terminated by a value in the instruction of -1,
464b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// which is an otherwise illegal value (branch -1 is inf loop).
465b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// The instruction 16-bit offset field addresses 32-bit words, but in
466b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// code is conv to an 18-bit value addressing bytes, hence the -4 value.
467b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
468b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochconst int kEndOfChain = -4;
469b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Determines the end of the Jump chain (a subset of the label link chain).
470b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochconst int kEndOfJumpChain = 0;
471b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
472b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
473b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochbool Assembler::IsBranch(Instr instr) {
474b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  uint32_t opcode   = GetOpcodeField(instr);
475b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  uint32_t rt_field = GetRtField(instr);
476b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  uint32_t rs_field = GetRsField(instr);
477b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Checks if the instruction is a branch.
478b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return opcode == BEQ ||
479b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      opcode == BNE ||
480b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      opcode == BLEZ ||
481b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      opcode == BGTZ ||
482b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      opcode == BEQL ||
483b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      opcode == BNEL ||
484b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      opcode == BLEZL ||
485b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      opcode == BGTZL ||
486b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      (opcode == REGIMM && (rt_field == BLTZ || rt_field == BGEZ ||
487b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                            rt_field == BLTZAL || rt_field == BGEZAL)) ||
488b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      (opcode == COP1 && rs_field == BC1) ||  // Coprocessor branch.
489b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      (opcode == COP1 && rs_field == BC1EQZ) ||
490b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      (opcode == COP1 && rs_field == BC1NEZ);
491b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
492b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
493b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
494b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochbool Assembler::IsEmittedConstant(Instr instr) {
495b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  uint32_t label_constant = GetLabelConst(instr);
496b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return label_constant == 0;  // Emitted label const in reg-exp engine.
497b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
498b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
499b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
500b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochbool Assembler::IsBeq(Instr instr) {
501b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return GetOpcodeField(instr) == BEQ;
502b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
503b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
504b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
505b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochbool Assembler::IsBne(Instr instr) {
506b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return GetOpcodeField(instr) == BNE;
507b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
508b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
509b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
510b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochbool Assembler::IsJump(Instr instr) {
511b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  uint32_t opcode   = GetOpcodeField(instr);
512b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  uint32_t rt_field = GetRtField(instr);
513b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  uint32_t rd_field = GetRdField(instr);
514b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  uint32_t function_field = GetFunctionField(instr);
515b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Checks if the instruction is a jump.
516b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return opcode == J || opcode == JAL ||
517b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      (opcode == SPECIAL && rt_field == 0 &&
518b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      ((function_field == JALR) || (rd_field == 0 && (function_field == JR))));
519b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
520b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
521b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
522b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochbool Assembler::IsJ(Instr instr) {
523b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  uint32_t opcode = GetOpcodeField(instr);
524b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Checks if the instruction is a jump.
525b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return opcode == J;
526b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
527b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
528b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
529b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochbool Assembler::IsJal(Instr instr) {
530b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return GetOpcodeField(instr) == JAL;
531b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
532b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
533b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
534b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochbool Assembler::IsJr(Instr instr) {
535b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return GetOpcodeField(instr) == SPECIAL && GetFunctionField(instr) == JR;
536b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
537b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
538b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
539b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochbool Assembler::IsJalr(Instr instr) {
540b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return GetOpcodeField(instr) == SPECIAL && GetFunctionField(instr) == JALR;
541b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
542b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
543b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
544b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochbool Assembler::IsLui(Instr instr) {
545b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  uint32_t opcode = GetOpcodeField(instr);
546b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Checks if the instruction is a load upper immediate.
547b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return opcode == LUI;
548b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
549b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
550b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
551b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochbool Assembler::IsOri(Instr instr) {
552b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  uint32_t opcode = GetOpcodeField(instr);
553b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Checks if the instruction is a load upper immediate.
554b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return opcode == ORI;
555b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
556b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
557b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
558b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochbool Assembler::IsNop(Instr instr, unsigned int type) {
559b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // See Assembler::nop(type).
560b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(type < 32);
561b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  uint32_t opcode = GetOpcodeField(instr);
562b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  uint32_t function = GetFunctionField(instr);
563b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  uint32_t rt = GetRt(instr);
564b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  uint32_t rd = GetRd(instr);
565b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  uint32_t sa = GetSa(instr);
566b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
567b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Traditional mips nop == sll(zero_reg, zero_reg, 0)
568b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // When marking non-zero type, use sll(zero_reg, at, type)
569b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // to avoid use of mips ssnop and ehb special encodings
570b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // of the sll instruction.
571b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
572b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Register nop_rt_reg = (type == 0) ? zero_reg : at;
573b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bool ret = (opcode == SPECIAL && function == SLL &&
574b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch              rd == static_cast<uint32_t>(ToNumber(zero_reg)) &&
575b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch              rt == static_cast<uint32_t>(ToNumber(nop_rt_reg)) &&
576b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch              sa == type);
577b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
578b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return ret;
579b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
580b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
581b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
582b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochint32_t Assembler::GetBranchOffset(Instr instr) {
583b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(IsBranch(instr));
584b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return (static_cast<int16_t>(instr & kImm16Mask)) << 2;
585b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
586b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
587b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
588b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochbool Assembler::IsLw(Instr instr) {
589b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return ((instr & kOpcodeMask) == LW);
590b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
591b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
592b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
593b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochint16_t Assembler::GetLwOffset(Instr instr) {
594b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(IsLw(instr));
595b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return ((instr & kImm16Mask));
596b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
597b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
598b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
599b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochInstr Assembler::SetLwOffset(Instr instr, int16_t offset) {
600b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(IsLw(instr));
601b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
602b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // We actually create a new lw instruction based on the original one.
603b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Instr temp_instr = LW | (instr & kRsFieldMask) | (instr & kRtFieldMask)
604b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      | (offset & kImm16Mask);
605b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
606b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return temp_instr;
607b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
608b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
609b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
610b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochbool Assembler::IsSw(Instr instr) {
611b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return ((instr & kOpcodeMask) == SW);
612b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
613b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
614b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
615b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochInstr Assembler::SetSwOffset(Instr instr, int16_t offset) {
616b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(IsSw(instr));
617b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return ((instr & ~kImm16Mask) | (offset & kImm16Mask));
618b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
619b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
620b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
621b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochbool Assembler::IsAddImmediate(Instr instr) {
622b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return ((instr & kOpcodeMask) == ADDIU || (instr & kOpcodeMask) == DADDIU);
623b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
624b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
625b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
626b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochInstr Assembler::SetAddImmediateOffset(Instr instr, int16_t offset) {
627b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(IsAddImmediate(instr));
628b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return ((instr & ~kImm16Mask) | (offset & kImm16Mask));
629b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
630b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
631b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
632b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochbool Assembler::IsAndImmediate(Instr instr) {
633b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return GetOpcodeField(instr) == ANDI;
634b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
635b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
636b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
637b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochint64_t Assembler::target_at(int64_t pos) {
638b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Instr instr = instr_at(pos);
639b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if ((instr & ~kImm16Mask) == 0) {
640b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Emitted label constant, not part of a branch.
641b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (instr == 0) {
642b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch       return kEndOfChain;
643b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch     } else {
644b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch       int32_t imm18 =((instr & static_cast<int32_t>(kImm16Mask)) << 16) >> 14;
645b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch       return (imm18 + pos);
646b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch     }
647b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
648b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Check we have a branch or jump instruction.
649b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(IsBranch(instr) || IsJ(instr) || IsLui(instr));
650b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Do NOT change this to <<2. We rely on arithmetic shifts here, assuming
651b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // the compiler uses arithmetic shifts for signed integers.
652b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (IsBranch(instr)) {
653b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    int32_t imm18 = ((instr & static_cast<int32_t>(kImm16Mask)) << 16) >> 14;
654b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (imm18 == kEndOfChain) {
655b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      // EndOfChain sentinel is returned directly, not relative to pc or pos.
656b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      return kEndOfChain;
657b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    } else {
658b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      return pos + kBranchPCOffset + imm18;
659b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
660b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } else if (IsLui(instr)) {
661b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Instr instr_lui = instr_at(pos + 0 * Assembler::kInstrSize);
662b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Instr instr_ori = instr_at(pos + 1 * Assembler::kInstrSize);
663b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Instr instr_ori2 = instr_at(pos + 3 * Assembler::kInstrSize);
664b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(IsOri(instr_ori));
665b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(IsOri(instr_ori2));
666b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
667b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // TODO(plind) create named constants for shift values.
668b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    int64_t imm = static_cast<int64_t>(instr_lui & kImm16Mask) << 48;
669b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    imm |= static_cast<int64_t>(instr_ori & kImm16Mask) << 32;
670b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    imm |= static_cast<int64_t>(instr_ori2 & kImm16Mask) << 16;
671b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Sign extend address;
672b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    imm >>= 16;
673b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
674b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (imm == kEndOfJumpChain) {
675b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      // EndOfChain sentinel is returned directly, not relative to pc or pos.
676b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      return kEndOfChain;
677b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    } else {
678b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      uint64_t instr_address = reinterpret_cast<int64_t>(buffer_ + pos);
679b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      int64_t delta = instr_address - imm;
680b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      DCHECK(pos > delta);
681b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      return pos - delta;
682b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
683b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } else {
684b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    int32_t imm28 = (instr & static_cast<int32_t>(kImm26Mask)) << 2;
685b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (imm28 == kEndOfJumpChain) {
686b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      // EndOfChain sentinel is returned directly, not relative to pc or pos.
687b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      return kEndOfChain;
688b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    } else {
689b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      uint64_t instr_address = reinterpret_cast<int64_t>(buffer_ + pos);
690b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      instr_address &= kImm28Mask;
691b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      int64_t delta = instr_address - imm28;
692b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      DCHECK(pos > delta);
693b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      return pos - delta;
694b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
695b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
696b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
697b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
698b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
699b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::target_at_put(int64_t pos, int64_t target_pos) {
700b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Instr instr = instr_at(pos);
701b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if ((instr & ~kImm16Mask) == 0) {
702b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(target_pos == kEndOfChain || target_pos >= 0);
703b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Emitted label constant, not part of a branch.
704b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Make label relative to Code* of generated Code object.
705b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    instr_at_put(pos, target_pos + (Code::kHeaderSize - kHeapObjectTag));
706b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return;
707b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
708b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
709b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(IsBranch(instr) || IsJ(instr) || IsLui(instr));
710b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (IsBranch(instr)) {
711b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    int32_t imm18 = target_pos - (pos + kBranchPCOffset);
712b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK((imm18 & 3) == 0);
713b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
714b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    instr &= ~kImm16Mask;
715b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    int32_t imm16 = imm18 >> 2;
716b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(is_int16(imm16));
717b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
718b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    instr_at_put(pos, instr | (imm16 & kImm16Mask));
719b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } else if (IsLui(instr)) {
720b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Instr instr_lui = instr_at(pos + 0 * Assembler::kInstrSize);
721b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Instr instr_ori = instr_at(pos + 1 * Assembler::kInstrSize);
722b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Instr instr_ori2 = instr_at(pos + 3 * Assembler::kInstrSize);
723b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(IsOri(instr_ori));
724b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(IsOri(instr_ori2));
725b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
726b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    uint64_t imm = reinterpret_cast<uint64_t>(buffer_) + target_pos;
727b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK((imm & 3) == 0);
728b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
729b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    instr_lui &= ~kImm16Mask;
730b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    instr_ori &= ~kImm16Mask;
731b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    instr_ori2 &= ~kImm16Mask;
732b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
733b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    instr_at_put(pos + 0 * Assembler::kInstrSize,
734b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                 instr_lui | ((imm >> 32) & kImm16Mask));
735b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    instr_at_put(pos + 1 * Assembler::kInstrSize,
736b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                 instr_ori | ((imm >> 16) & kImm16Mask));
737b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    instr_at_put(pos + 3 * Assembler::kInstrSize,
738b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                 instr_ori2 | (imm & kImm16Mask));
739b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } else {
740b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    uint64_t imm28 = reinterpret_cast<uint64_t>(buffer_) + target_pos;
741b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    imm28 &= kImm28Mask;
742b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK((imm28 & 3) == 0);
743b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
744b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    instr &= ~kImm26Mask;
745b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    uint32_t imm26 = imm28 >> 2;
746b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(is_uint26(imm26));
747b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
748b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    instr_at_put(pos, instr | (imm26 & kImm26Mask));
749b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
750b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
751b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
752b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
753b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::print(Label* L) {
754b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (L->is_unused()) {
755b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    PrintF("unused label\n");
756b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } else if (L->is_bound()) {
757b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    PrintF("bound label to %d\n", L->pos());
758b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } else if (L->is_linked()) {
759b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Label l = *L;
760b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    PrintF("unbound label");
761b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    while (l.is_linked()) {
762b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      PrintF("@ %d ", l.pos());
763b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      Instr instr = instr_at(l.pos());
764b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      if ((instr & ~kImm16Mask) == 0) {
765b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        PrintF("value\n");
766b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      } else {
767b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        PrintF("%d\n", instr);
768b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
769b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      next(&l);
770b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
771b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } else {
772b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    PrintF("label in inconsistent state (pos = %d)\n", L->pos_);
773b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
774b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
775b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
776b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
777b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::bind_to(Label* L, int pos) {
778b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(0 <= pos && pos <= pc_offset());  // Must have valid binding position.
779b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int32_t trampoline_pos = kInvalidSlotPos;
780b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (L->is_linked() && !trampoline_emitted_) {
781b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    unbound_labels_count_--;
782b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    next_buffer_check_ += kTrampolineSlotsSize;
783b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
784b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
785b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  while (L->is_linked()) {
786b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    int32_t fixup_pos = L->pos();
787b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    int32_t dist = pos - fixup_pos;
788b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    next(L);  // Call next before overwriting link with target at fixup_pos.
789b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Instr instr = instr_at(fixup_pos);
790b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (IsBranch(instr)) {
791b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      if (dist > kMaxBranchOffset) {
792b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        if (trampoline_pos == kInvalidSlotPos) {
793b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          trampoline_pos = get_trampoline_entry(fixup_pos);
794b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          CHECK(trampoline_pos != kInvalidSlotPos);
795b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        }
796b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        DCHECK((trampoline_pos - fixup_pos) <= kMaxBranchOffset);
797b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        target_at_put(fixup_pos, trampoline_pos);
798b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        fixup_pos = trampoline_pos;
799b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        dist = pos - fixup_pos;
800b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
801b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      target_at_put(fixup_pos, pos);
802b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    } else {
803b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      DCHECK(IsJ(instr) || IsLui(instr) || IsEmittedConstant(instr));
804b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      target_at_put(fixup_pos, pos);
805b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
806b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
807b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  L->bind_to(pos);
808b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
809b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Keep track of the last bound label so we don't eliminate any instructions
810b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // before a bound label.
811b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (pos > last_bound_pos_)
812b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    last_bound_pos_ = pos;
813b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
814b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
815b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
816b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::bind(Label* L) {
817b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(!L->is_bound());  // Label can only be bound once.
818b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bind_to(L, pc_offset());
819b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
820b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
821b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
822b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::next(Label* L) {
823b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(L->is_linked());
824b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int link = target_at(L->pos());
825b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (link == kEndOfChain) {
826b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    L->Unuse();
827b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } else {
828b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(link >= 0);
829b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    L->link_to(link);
830b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
831b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
832b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
833b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
834b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochbool Assembler::is_near(Label* L) {
835b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (L->is_bound()) {
836b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return ((pc_offset() - L->pos()) < kMaxBranchOffset - 4 * kInstrSize);
837b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
838b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return false;
839b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
840b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
841b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
842b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// We have to use a temporary register for things that can be relocated even
843b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// if they can be encoded in the MIPS's 16 bits of immediate-offset instruction
844b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// space.  There is no guarantee that the relocated location can be similarly
845b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// encoded.
846b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochbool Assembler::MustUseReg(RelocInfo::Mode rmode) {
847b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return !RelocInfo::IsNone(rmode);
848b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
849b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
850b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::GenInstrRegister(Opcode opcode,
851b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                 Register rs,
852b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                 Register rt,
853b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                 Register rd,
854b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                 uint16_t sa,
855b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                 SecondaryField func) {
856b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(rd.is_valid() && rs.is_valid() && rt.is_valid() && is_uint5(sa));
857b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Instr instr = opcode | (rs.code() << kRsShift) | (rt.code() << kRtShift)
858b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      | (rd.code() << kRdShift) | (sa << kSaShift) | func;
859b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  emit(instr);
860b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
861b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
862b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
863b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::GenInstrRegister(Opcode opcode,
864b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                 Register rs,
865b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                 Register rt,
866b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                 uint16_t msb,
867b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                 uint16_t lsb,
868b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                 SecondaryField func) {
869b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(rs.is_valid() && rt.is_valid() && is_uint5(msb) && is_uint5(lsb));
870b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Instr instr = opcode | (rs.code() << kRsShift) | (rt.code() << kRtShift)
871b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      | (msb << kRdShift) | (lsb << kSaShift) | func;
872b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  emit(instr);
873b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
874b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
875b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
876b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::GenInstrRegister(Opcode opcode,
877b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                 SecondaryField fmt,
878b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                 FPURegister ft,
879b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                 FPURegister fs,
880b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                 FPURegister fd,
881b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                 SecondaryField func) {
882b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(fd.is_valid() && fs.is_valid() && ft.is_valid());
883b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Instr instr = opcode | fmt | (ft.code() << kFtShift) | (fs.code() << kFsShift)
884b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      | (fd.code() << kFdShift) | func;
885b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  emit(instr);
886b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
887b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
888b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
889b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::GenInstrRegister(Opcode opcode,
890b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                 FPURegister fr,
891b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                 FPURegister ft,
892b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                 FPURegister fs,
893b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                 FPURegister fd,
894b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                 SecondaryField func) {
895b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(fd.is_valid() && fr.is_valid() && fs.is_valid() && ft.is_valid());
896b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Instr instr = opcode | (fr.code() << kFrShift) | (ft.code() << kFtShift)
897b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      | (fs.code() << kFsShift) | (fd.code() << kFdShift) | func;
898b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  emit(instr);
899b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
900b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
901b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
902b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::GenInstrRegister(Opcode opcode,
903b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                 SecondaryField fmt,
904b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                 Register rt,
905b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                 FPURegister fs,
906b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                 FPURegister fd,
907b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                 SecondaryField func) {
908b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(fd.is_valid() && fs.is_valid() && rt.is_valid());
909b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Instr instr = opcode | fmt | (rt.code() << kRtShift)
910b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      | (fs.code() << kFsShift) | (fd.code() << kFdShift) | func;
911b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  emit(instr);
912b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
913b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
914b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
915b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::GenInstrRegister(Opcode opcode,
916b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                 SecondaryField fmt,
917b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                 Register rt,
918b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                 FPUControlRegister fs,
919b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                 SecondaryField func) {
920b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(fs.is_valid() && rt.is_valid());
921b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Instr instr =
922b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      opcode | fmt | (rt.code() << kRtShift) | (fs.code() << kFsShift) | func;
923b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  emit(instr);
924b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
925b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
926b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
927b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Instructions with immediate value.
928b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Registers are in the order of the instruction encoding, from left to right.
929b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::GenInstrImmediate(Opcode opcode,
930b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                  Register rs,
931b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                  Register rt,
932b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                  int32_t j) {
933b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(rs.is_valid() && rt.is_valid() && (is_int16(j) || is_uint16(j)));
934b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Instr instr = opcode | (rs.code() << kRsShift) | (rt.code() << kRtShift)
935b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      | (j & kImm16Mask);
936b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  emit(instr);
937b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
938b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
939b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
940b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::GenInstrImmediate(Opcode opcode,
941b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                  Register rs,
942b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                  SecondaryField SF,
943b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                  int32_t j) {
944b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(rs.is_valid() && (is_int16(j) || is_uint16(j)));
945b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Instr instr = opcode | (rs.code() << kRsShift) | SF | (j & kImm16Mask);
946b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  emit(instr);
947b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
948b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
949b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
950b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::GenInstrImmediate(Opcode opcode,
951b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                  Register rs,
952b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                  FPURegister ft,
953b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                  int32_t j) {
954b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(rs.is_valid() && ft.is_valid() && (is_int16(j) || is_uint16(j)));
955b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Instr instr = opcode | (rs.code() << kRsShift) | (ft.code() << kFtShift)
956b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      | (j & kImm16Mask);
957b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  emit(instr);
958b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
959b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
960b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
961b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::GenInstrJump(Opcode opcode,
962b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                             uint32_t address) {
963b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  BlockTrampolinePoolScope block_trampoline_pool(this);
964b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(is_uint26(address));
965b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Instr instr = opcode | address;
966b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  emit(instr);
967b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  BlockTrampolinePoolFor(1);  // For associated delay slot.
968b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
969b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
970b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
971b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Returns the next free trampoline entry.
972b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochint32_t Assembler::get_trampoline_entry(int32_t pos) {
973b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int32_t trampoline_entry = kInvalidSlotPos;
974b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (!internal_trampoline_exception_) {
975b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (trampoline_.start() > pos) {
976b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch     trampoline_entry = trampoline_.take_slot();
977b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
978b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
979b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (kInvalidSlotPos == trampoline_entry) {
980b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      internal_trampoline_exception_ = true;
981b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
982b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
983b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return trampoline_entry;
984b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
985b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
986b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
987b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochuint64_t Assembler::jump_address(Label* L) {
988b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int64_t target_pos;
989b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (L->is_bound()) {
990b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    target_pos = L->pos();
991b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } else {
992b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (L->is_linked()) {
993b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      target_pos = L->pos();  // L's link.
994b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      L->link_to(pc_offset());
995b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    } else {
996b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      L->link_to(pc_offset());
997b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      return kEndOfJumpChain;
998b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
999b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1000b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1001b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  uint64_t imm = reinterpret_cast<uint64_t>(buffer_) + target_pos;
1002b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK((imm & 3) == 0);
1003b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1004b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return imm;
1005b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1006b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1007b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1008b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochint32_t Assembler::branch_offset(Label* L, bool jump_elimination_allowed) {
1009b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int32_t target_pos;
1010b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (L->is_bound()) {
1011b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    target_pos = L->pos();
1012b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } else {
1013b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (L->is_linked()) {
1014b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      target_pos = L->pos();
1015b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      L->link_to(pc_offset());
1016b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    } else {
1017b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      L->link_to(pc_offset());
1018b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      if (!trampoline_emitted_) {
1019b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        unbound_labels_count_++;
1020b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        next_buffer_check_ -= kTrampolineSlotsSize;
1021b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
1022b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      return kEndOfChain;
1023b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
1024b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1025b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1026b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int32_t offset = target_pos - (pc_offset() + kBranchPCOffset);
1027b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK((offset & 3) == 0);
1028b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(is_int16(offset >> 2));
1029b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1030b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return offset;
1031b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1032b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1033b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1034b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochint32_t Assembler::branch_offset_compact(Label* L,
1035b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    bool jump_elimination_allowed) {
1036b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int32_t target_pos;
1037b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (L->is_bound()) {
1038b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    target_pos = L->pos();
1039b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } else {
1040b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (L->is_linked()) {
1041b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      target_pos = L->pos();
1042b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      L->link_to(pc_offset());
1043b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    } else {
1044b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      L->link_to(pc_offset());
1045b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      if (!trampoline_emitted_) {
1046b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        unbound_labels_count_++;
1047b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        next_buffer_check_ -= kTrampolineSlotsSize;
1048b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
1049b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      return kEndOfChain;
1050b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
1051b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1052b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1053b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int32_t offset = target_pos - pc_offset();
1054b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK((offset & 3) == 0);
1055b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(is_int16(offset >> 2));
1056b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1057b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return offset;
1058b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1059b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1060b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1061b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochint32_t Assembler::branch_offset21(Label* L, bool jump_elimination_allowed) {
1062b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int32_t target_pos;
1063b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (L->is_bound()) {
1064b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    target_pos = L->pos();
1065b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } else {
1066b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (L->is_linked()) {
1067b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      target_pos = L->pos();
1068b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      L->link_to(pc_offset());
1069b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    } else {
1070b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      L->link_to(pc_offset());
1071b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      if (!trampoline_emitted_) {
1072b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        unbound_labels_count_++;
1073b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        next_buffer_check_ -= kTrampolineSlotsSize;
1074b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
1075b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      return kEndOfChain;
1076b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
1077b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1078b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1079b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int32_t offset = target_pos - (pc_offset() + kBranchPCOffset);
1080b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK((offset & 3) == 0);
1081b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(((offset >> 2) & 0xFFE00000) == 0);  // Offset is 21bit width.
1082b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1083b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return offset;
1084b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1085b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1086b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1087b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochint32_t Assembler::branch_offset21_compact(Label* L,
1088b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    bool jump_elimination_allowed) {
1089b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int32_t target_pos;
1090b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (L->is_bound()) {
1091b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    target_pos = L->pos();
1092b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } else {
1093b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (L->is_linked()) {
1094b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      target_pos = L->pos();
1095b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      L->link_to(pc_offset());
1096b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    } else {
1097b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      L->link_to(pc_offset());
1098b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      if (!trampoline_emitted_) {
1099b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        unbound_labels_count_++;
1100b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        next_buffer_check_ -= kTrampolineSlotsSize;
1101b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
1102b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      return kEndOfChain;
1103b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
1104b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1105b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1106b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int32_t offset = target_pos - pc_offset();
1107b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK((offset & 3) == 0);
1108b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(((offset >> 2) & 0xFFE00000) == 0);  // Offset is 21bit width.
1109b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1110b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return offset;
1111b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1112b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1113b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1114b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::label_at_put(Label* L, int at_offset) {
1115b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int target_pos;
1116b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (L->is_bound()) {
1117b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    target_pos = L->pos();
1118b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    instr_at_put(at_offset, target_pos + (Code::kHeaderSize - kHeapObjectTag));
1119b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } else {
1120b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (L->is_linked()) {
1121b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      target_pos = L->pos();  // L's link.
1122b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      int32_t imm18 = target_pos - at_offset;
1123b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      DCHECK((imm18 & 3) == 0);
1124b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      int32_t imm16 = imm18 >> 2;
1125b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      DCHECK(is_int16(imm16));
1126b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      instr_at_put(at_offset, (imm16 & kImm16Mask));
1127b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    } else {
1128b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      target_pos = kEndOfChain;
1129b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      instr_at_put(at_offset, 0);
1130b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      if (!trampoline_emitted_) {
1131b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        unbound_labels_count_++;
1132b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        next_buffer_check_ -= kTrampolineSlotsSize;
1133b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
1134b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
1135b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    L->link_to(at_offset);
1136b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1137b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1138b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1139b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1140b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch//------- Branch and jump instructions --------
1141b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1142b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::b(int16_t offset) {
1143b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  beq(zero_reg, zero_reg, offset);
1144b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1145b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1146b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1147b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::bal(int16_t offset) {
1148b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  positions_recorder()->WriteRecordedPositions();
1149b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bgezal(zero_reg, offset);
1150b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1151b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1152b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1153b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::beq(Register rs, Register rt, int16_t offset) {
1154b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  BlockTrampolinePoolScope block_trampoline_pool(this);
1155b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  GenInstrImmediate(BEQ, rs, rt, offset);
1156b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  BlockTrampolinePoolFor(1);  // For associated delay slot.
1157b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1158b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1159b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1160b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::bgez(Register rs, int16_t offset) {
1161b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  BlockTrampolinePoolScope block_trampoline_pool(this);
1162b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  GenInstrImmediate(REGIMM, rs, BGEZ, offset);
1163b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  BlockTrampolinePoolFor(1);  // For associated delay slot.
1164b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1165b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1166b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1167b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::bgezc(Register rt, int16_t offset) {
1168b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(kArchVariant == kMips64r6);
1169b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(!(rt.is(zero_reg)));
1170b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  GenInstrImmediate(BLEZL, rt, rt, offset);
1171b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1172b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1173b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1174b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::bgeuc(Register rs, Register rt, int16_t offset) {
1175b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(kArchVariant == kMips64r6);
1176b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(!(rs.is(zero_reg)));
1177b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(!(rt.is(zero_reg)));
1178b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(rs.code() != rt.code());
1179b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  GenInstrImmediate(BLEZ, rs, rt, offset);
1180b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1181b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1182b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1183b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::bgec(Register rs, Register rt, int16_t offset) {
1184b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(kArchVariant == kMips64r6);
1185b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(!(rs.is(zero_reg)));
1186b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(!(rt.is(zero_reg)));
1187b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(rs.code() != rt.code());
1188b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  GenInstrImmediate(BLEZL, rs, rt, offset);
1189b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1190b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1191b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1192b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::bgezal(Register rs, int16_t offset) {
1193b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(kArchVariant != kMips64r6 || rs.is(zero_reg));
1194b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  BlockTrampolinePoolScope block_trampoline_pool(this);
1195b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  positions_recorder()->WriteRecordedPositions();
1196b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  GenInstrImmediate(REGIMM, rs, BGEZAL, offset);
1197b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  BlockTrampolinePoolFor(1);  // For associated delay slot.
1198b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1199b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1200b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1201b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::bgtz(Register rs, int16_t offset) {
1202b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  BlockTrampolinePoolScope block_trampoline_pool(this);
1203b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  GenInstrImmediate(BGTZ, rs, zero_reg, offset);
1204b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  BlockTrampolinePoolFor(1);  // For associated delay slot.
1205b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1206b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1207b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1208b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::bgtzc(Register rt, int16_t offset) {
1209b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(kArchVariant == kMips64r6);
1210b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(!(rt.is(zero_reg)));
1211b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  GenInstrImmediate(BGTZL, zero_reg, rt, offset);
1212b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1213b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1214b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1215b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::blez(Register rs, int16_t offset) {
1216b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  BlockTrampolinePoolScope block_trampoline_pool(this);
1217b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  GenInstrImmediate(BLEZ, rs, zero_reg, offset);
1218b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  BlockTrampolinePoolFor(1);  // For associated delay slot.
1219b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1220b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1221b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1222b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::blezc(Register rt, int16_t offset) {
1223b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(kArchVariant == kMips64r6);
1224b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(!(rt.is(zero_reg)));
1225b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  GenInstrImmediate(BLEZL, zero_reg, rt, offset);
1226b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1227b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1228b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1229b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::bltzc(Register rt, int16_t offset) {
1230b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(kArchVariant == kMips64r6);
1231b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(!(rt.is(zero_reg)));
1232b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  GenInstrImmediate(BGTZL, rt, rt, offset);
1233b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1234b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1235b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1236b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::bltuc(Register rs, Register rt, int16_t offset) {
1237b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(kArchVariant == kMips64r6);
1238b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(!(rs.is(zero_reg)));
1239b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(!(rt.is(zero_reg)));
1240b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(rs.code() != rt.code());
1241b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  GenInstrImmediate(BGTZ, rs, rt, offset);
1242b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1243b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1244b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1245b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::bltc(Register rs, Register rt, int16_t offset) {
1246b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(kArchVariant == kMips64r6);
1247b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(!(rs.is(zero_reg)));
1248b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(!(rt.is(zero_reg)));
1249b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(rs.code() != rt.code());
1250b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  GenInstrImmediate(BGTZL, rs, rt, offset);
1251b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1252b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1253b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1254b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::bltz(Register rs, int16_t offset) {
1255b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  BlockTrampolinePoolScope block_trampoline_pool(this);
1256b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  GenInstrImmediate(REGIMM, rs, BLTZ, offset);
1257b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  BlockTrampolinePoolFor(1);  // For associated delay slot.
1258b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1259b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1260b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1261b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::bltzal(Register rs, int16_t offset) {
1262b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(kArchVariant != kMips64r6 || rs.is(zero_reg));
1263b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  BlockTrampolinePoolScope block_trampoline_pool(this);
1264b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  positions_recorder()->WriteRecordedPositions();
1265b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  GenInstrImmediate(REGIMM, rs, BLTZAL, offset);
1266b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  BlockTrampolinePoolFor(1);  // For associated delay slot.
1267b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1268b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1269b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1270b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::bne(Register rs, Register rt, int16_t offset) {
1271b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  BlockTrampolinePoolScope block_trampoline_pool(this);
1272b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  GenInstrImmediate(BNE, rs, rt, offset);
1273b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  BlockTrampolinePoolFor(1);  // For associated delay slot.
1274b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1275b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1276b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1277b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::bovc(Register rs, Register rt, int16_t offset) {
1278b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(kArchVariant == kMips64r6);
1279b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(!(rs.is(zero_reg)));
1280b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(rs.code() >= rt.code());
1281b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  GenInstrImmediate(ADDI, rs, rt, offset);
1282b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1283b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1284b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1285b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::bnvc(Register rs, Register rt, int16_t offset) {
1286b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(kArchVariant == kMips64r6);
1287b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(!(rs.is(zero_reg)));
1288b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(rs.code() >= rt.code());
1289b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  GenInstrImmediate(DADDI, rs, rt, offset);
1290b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1291b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1292b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1293b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::blezalc(Register rt, int16_t offset) {
1294b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(kArchVariant == kMips64r6);
1295b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(!(rt.is(zero_reg)));
1296b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  GenInstrImmediate(BLEZ, zero_reg, rt, offset);
1297b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1298b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1299b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1300b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::bgezalc(Register rt, int16_t offset) {
1301b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(kArchVariant == kMips64r6);
1302b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(!(rt.is(zero_reg)));
1303b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  GenInstrImmediate(BLEZ, rt, rt, offset);
1304b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1305b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1306b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1307b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::bgezall(Register rs, int16_t offset) {
1308b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(kArchVariant == kMips64r6);
1309b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(!(rs.is(zero_reg)));
1310b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  GenInstrImmediate(REGIMM, rs, BGEZALL, offset);
1311b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1312b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1313b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1314b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::bltzalc(Register rt, int16_t offset) {
1315b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(kArchVariant == kMips64r6);
1316b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(!(rt.is(zero_reg)));
1317b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  GenInstrImmediate(BGTZ, rt, rt, offset);
1318b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1319b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1320b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1321b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::bgtzalc(Register rt, int16_t offset) {
1322b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(kArchVariant == kMips64r6);
1323b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(!(rt.is(zero_reg)));
1324b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  GenInstrImmediate(BGTZ, zero_reg, rt, offset);
1325b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1326b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1327b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1328b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::beqzalc(Register rt, int16_t offset) {
1329b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(kArchVariant == kMips64r6);
1330b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(!(rt.is(zero_reg)));
1331b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  GenInstrImmediate(ADDI, zero_reg, rt, offset);
1332b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1333b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1334b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1335b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::bnezalc(Register rt, int16_t offset) {
1336b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(kArchVariant == kMips64r6);
1337b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(!(rt.is(zero_reg)));
1338b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  GenInstrImmediate(DADDI, zero_reg, rt, offset);
1339b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1340b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1341b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1342b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::beqc(Register rs, Register rt, int16_t offset) {
1343b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(kArchVariant == kMips64r6);
1344b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(rs.code() < rt.code());
1345b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  GenInstrImmediate(ADDI, rs, rt, offset);
1346b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1347b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1348b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1349b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::beqzc(Register rs, int32_t offset) {
1350b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(kArchVariant == kMips64r6);
1351b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(!(rs.is(zero_reg)));
1352b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Instr instr = BEQZC | (rs.code() << kRsShift) | offset;
1353b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  emit(instr);
1354b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1355b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1356b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1357b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::bnec(Register rs, Register rt, int16_t offset) {
1358b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(kArchVariant == kMips64r6);
1359b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(rs.code() < rt.code());
1360b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  GenInstrImmediate(DADDI, rs, rt, offset);
1361b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1362b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1363b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1364b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::bnezc(Register rs, int32_t offset) {
1365b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(kArchVariant == kMips64r6);
1366b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(!(rs.is(zero_reg)));
1367b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Instr instr = BNEZC | (rs.code() << kRsShift) | offset;
1368b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  emit(instr);
1369b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1370b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1371b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1372b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::j(int64_t target) {
1373b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#if DEBUG
1374b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Get pc of delay slot.
1375b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  uint64_t ipc = reinterpret_cast<uint64_t>(pc_ + 1 * kInstrSize);
1376b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bool in_range = (ipc ^ static_cast<uint64_t>(target) >>
1377b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                  (kImm26Bits + kImmFieldShift)) == 0;
1378b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(in_range && ((target & 3) == 0));
1379b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#endif
1380b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  GenInstrJump(J, target >> 2);
1381b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1382b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1383b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1384b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::jr(Register rs) {
1385b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (kArchVariant != kMips64r6) {
1386b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    BlockTrampolinePoolScope block_trampoline_pool(this);
1387b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (rs.is(ra)) {
1388b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      positions_recorder()->WriteRecordedPositions();
1389b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
1390b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    GenInstrRegister(SPECIAL, rs, zero_reg, zero_reg, 0, JR);
1391b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    BlockTrampolinePoolFor(1);  // For associated delay slot.
1392b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } else {
1393b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    jalr(rs, zero_reg);
1394b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1395b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1396b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1397b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1398b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::jal(int64_t target) {
1399b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#ifdef DEBUG
1400b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Get pc of delay slot.
1401b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  uint64_t ipc = reinterpret_cast<uint64_t>(pc_ + 1 * kInstrSize);
1402b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bool in_range = (ipc ^ static_cast<uint64_t>(target) >>
1403b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                  (kImm26Bits + kImmFieldShift)) == 0;
1404b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(in_range && ((target & 3) == 0));
1405b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#endif
1406b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  positions_recorder()->WriteRecordedPositions();
1407b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  GenInstrJump(JAL, target >> 2);
1408b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1409b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1410b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1411b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::jalr(Register rs, Register rd) {
1412b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  BlockTrampolinePoolScope block_trampoline_pool(this);
1413b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  positions_recorder()->WriteRecordedPositions();
1414b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  GenInstrRegister(SPECIAL, rs, zero_reg, rd, 0, JALR);
1415b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  BlockTrampolinePoolFor(1);  // For associated delay slot.
1416b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1417b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1418b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1419b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::j_or_jr(int64_t target, Register rs) {
1420b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Get pc of delay slot.
1421b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  uint64_t ipc = reinterpret_cast<uint64_t>(pc_ + 1 * kInstrSize);
1422b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bool in_range = (ipc ^ static_cast<uint64_t>(target) >>
1423b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                  (kImm26Bits + kImmFieldShift)) == 0;
1424b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (in_range) {
1425b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      j(target);
1426b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } else {
1427b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      jr(t9);
1428b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1429b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1430b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1431b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1432b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::jal_or_jalr(int64_t target, Register rs) {
1433b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Get pc of delay slot.
1434b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  uint64_t ipc = reinterpret_cast<uint64_t>(pc_ + 1 * kInstrSize);
1435b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bool in_range = (ipc ^ static_cast<uint64_t>(target) >>
1436b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                  (kImm26Bits+kImmFieldShift)) == 0;
1437b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (in_range) {
1438b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      jal(target);
1439b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } else {
1440b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      jalr(t9);
1441b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1442b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1443b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1444b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1445b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// -------Data-processing-instructions---------
1446b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1447b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Arithmetic.
1448b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1449b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::addu(Register rd, Register rs, Register rt) {
1450b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  GenInstrRegister(SPECIAL, rs, rt, rd, 0, ADDU);
1451b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1452b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1453b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1454b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::addiu(Register rd, Register rs, int32_t j) {
1455b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  GenInstrImmediate(ADDIU, rs, rd, j);
1456b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1457b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1458b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1459b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::subu(Register rd, Register rs, Register rt) {
1460b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  GenInstrRegister(SPECIAL, rs, rt, rd, 0, SUBU);
1461b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1462b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1463b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1464b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::mul(Register rd, Register rs, Register rt) {
1465b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (kArchVariant == kMips64r6) {
1466b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      GenInstrRegister(SPECIAL, rs, rt, rd, MUL_OP, MUL_MUH);
1467b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } else {
1468b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      GenInstrRegister(SPECIAL2, rs, rt, rd, 0, MUL);
1469b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1470b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1471b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1472b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1473b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::muh(Register rd, Register rs, Register rt) {
1474b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(kArchVariant == kMips64r6);
1475b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  GenInstrRegister(SPECIAL, rs, rt, rd, MUH_OP, MUL_MUH);
1476b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1477b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1478b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1479b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::mulu(Register rd, Register rs, Register rt) {
1480b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(kArchVariant == kMips64r6);
1481b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  GenInstrRegister(SPECIAL, rs, rt, rd, MUL_OP, MUL_MUH_U);
1482b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1483b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1484b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1485b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::muhu(Register rd, Register rs, Register rt) {
1486b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(kArchVariant == kMips64r6);
1487b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  GenInstrRegister(SPECIAL, rs, rt, rd, MUH_OP, MUL_MUH_U);
1488b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1489b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1490b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1491b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::dmul(Register rd, Register rs, Register rt) {
1492b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(kArchVariant == kMips64r6);
1493b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  GenInstrRegister(SPECIAL, rs, rt, rd, MUL_OP, D_MUL_MUH);
1494b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1495b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1496b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1497b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::dmuh(Register rd, Register rs, Register rt) {
1498b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(kArchVariant == kMips64r6);
1499b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  GenInstrRegister(SPECIAL, rs, rt, rd, MUH_OP, D_MUL_MUH);
1500b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1501b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1502b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1503b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::dmulu(Register rd, Register rs, Register rt) {
1504b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(kArchVariant == kMips64r6);
1505b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  GenInstrRegister(SPECIAL, rs, rt, rd, MUL_OP, D_MUL_MUH_U);
1506b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1507b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1508b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1509b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::dmuhu(Register rd, Register rs, Register rt) {
1510b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(kArchVariant == kMips64r6);
1511b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  GenInstrRegister(SPECIAL, rs, rt, rd, MUH_OP, D_MUL_MUH_U);
1512b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1513b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1514b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1515b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::mult(Register rs, Register rt) {
1516b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(kArchVariant != kMips64r6);
1517b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  GenInstrRegister(SPECIAL, rs, rt, zero_reg, 0, MULT);
1518b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1519b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1520b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1521b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::multu(Register rs, Register rt) {
1522b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(kArchVariant != kMips64r6);
1523b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  GenInstrRegister(SPECIAL, rs, rt, zero_reg, 0, MULTU);
1524b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1525b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1526b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1527b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::daddiu(Register rd, Register rs, int32_t j) {
1528b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  GenInstrImmediate(DADDIU, rs, rd, j);
1529b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1530b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1531b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1532b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::div(Register rs, Register rt) {
1533b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  GenInstrRegister(SPECIAL, rs, rt, zero_reg, 0, DIV);
1534b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1535b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1536b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1537b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::div(Register rd, Register rs, Register rt) {
1538b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(kArchVariant == kMips64r6);
1539b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  GenInstrRegister(SPECIAL, rs, rt, rd, DIV_OP, DIV_MOD);
1540b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1541b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1542b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1543b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::mod(Register rd, Register rs, Register rt) {
1544b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(kArchVariant == kMips64r6);
1545b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  GenInstrRegister(SPECIAL, rs, rt, rd, MOD_OP, DIV_MOD);
1546b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1547b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1548b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1549b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::divu(Register rs, Register rt) {
1550b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  GenInstrRegister(SPECIAL, rs, rt, zero_reg, 0, DIVU);
1551b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1552b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1553b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1554b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::divu(Register rd, Register rs, Register rt) {
1555b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(kArchVariant == kMips64r6);
1556b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  GenInstrRegister(SPECIAL, rs, rt, rd, DIV_OP, DIV_MOD_U);
1557b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1558b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1559b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1560b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::modu(Register rd, Register rs, Register rt) {
1561b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(kArchVariant == kMips64r6);
1562b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  GenInstrRegister(SPECIAL, rs, rt, rd, MOD_OP, DIV_MOD_U);
1563b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1564b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1565b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1566b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::daddu(Register rd, Register rs, Register rt) {
1567b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  GenInstrRegister(SPECIAL, rs, rt, rd, 0, DADDU);
1568b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1569b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1570b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1571b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::dsubu(Register rd, Register rs, Register rt) {
1572b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  GenInstrRegister(SPECIAL, rs, rt, rd, 0, DSUBU);
1573b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1574b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1575b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1576b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::dmult(Register rs, Register rt) {
1577b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  GenInstrRegister(SPECIAL, rs, rt, zero_reg, 0, DMULT);
1578b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1579b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1580b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1581b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::dmultu(Register rs, Register rt) {
1582b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  GenInstrRegister(SPECIAL, rs, rt, zero_reg, 0, DMULTU);
1583b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1584b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1585b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1586b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::ddiv(Register rs, Register rt) {
1587b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  GenInstrRegister(SPECIAL, rs, rt, zero_reg, 0, DDIV);
1588b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1589b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1590b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1591b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::ddiv(Register rd, Register rs, Register rt) {
1592b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(kArchVariant == kMips64r6);
1593b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  GenInstrRegister(SPECIAL, rs, rt, rd, DIV_OP, D_DIV_MOD);
1594b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1595b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1596b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1597b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::dmod(Register rd, Register rs, Register rt) {
1598b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(kArchVariant == kMips64r6);
1599b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  GenInstrRegister(SPECIAL, rs, rt, rd, MOD_OP, D_DIV_MOD);
1600b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1601b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1602b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1603b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::ddivu(Register rs, Register rt) {
1604b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  GenInstrRegister(SPECIAL, rs, rt, zero_reg, 0, DDIVU);
1605b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1606b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1607b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1608b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::ddivu(Register rd, Register rs, Register rt) {
1609b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(kArchVariant == kMips64r6);
1610b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  GenInstrRegister(SPECIAL, rs, rt, rd, DIV_OP, D_DIV_MOD_U);
1611b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1612b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1613b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1614b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::dmodu(Register rd, Register rs, Register rt) {
1615b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(kArchVariant == kMips64r6);
1616b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  GenInstrRegister(SPECIAL, rs, rt, rd, MOD_OP, D_DIV_MOD_U);
1617b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1618b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1619b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1620b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Logical.
1621b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1622b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::and_(Register rd, Register rs, Register rt) {
1623b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  GenInstrRegister(SPECIAL, rs, rt, rd, 0, AND);
1624b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1625b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1626b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1627b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::andi(Register rt, Register rs, int32_t j) {
1628b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(is_uint16(j));
1629b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  GenInstrImmediate(ANDI, rs, rt, j);
1630b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1631b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1632b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1633b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::or_(Register rd, Register rs, Register rt) {
1634b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  GenInstrRegister(SPECIAL, rs, rt, rd, 0, OR);
1635b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1636b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1637b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1638b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::ori(Register rt, Register rs, int32_t j) {
1639b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(is_uint16(j));
1640b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  GenInstrImmediate(ORI, rs, rt, j);
1641b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1642b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1643b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1644b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::xor_(Register rd, Register rs, Register rt) {
1645b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  GenInstrRegister(SPECIAL, rs, rt, rd, 0, XOR);
1646b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1647b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1648b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1649b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::xori(Register rt, Register rs, int32_t j) {
1650b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(is_uint16(j));
1651b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  GenInstrImmediate(XORI, rs, rt, j);
1652b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1653b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1654b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1655b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::nor(Register rd, Register rs, Register rt) {
1656b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  GenInstrRegister(SPECIAL, rs, rt, rd, 0, NOR);
1657b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1658b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1659b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1660b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Shifts.
1661b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::sll(Register rd,
1662b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                    Register rt,
1663b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                    uint16_t sa,
1664b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                    bool coming_from_nop) {
1665b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Don't allow nop instructions in the form sll zero_reg, zero_reg to be
1666b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // generated using the sll instruction. They must be generated using
1667b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // nop(int/NopMarkerTypes) or MarkCode(int/NopMarkerTypes) pseudo
1668b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // instructions.
1669b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(coming_from_nop || !(rd.is(zero_reg) && rt.is(zero_reg)));
1670b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  GenInstrRegister(SPECIAL, zero_reg, rt, rd, sa, SLL);
1671b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1672b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1673b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1674b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::sllv(Register rd, Register rt, Register rs) {
1675b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  GenInstrRegister(SPECIAL, rs, rt, rd, 0, SLLV);
1676b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1677b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1678b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1679b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::srl(Register rd, Register rt, uint16_t sa) {
1680b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  GenInstrRegister(SPECIAL, zero_reg, rt, rd, sa, SRL);
1681b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1682b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1683b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1684b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::srlv(Register rd, Register rt, Register rs) {
1685b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  GenInstrRegister(SPECIAL, rs, rt, rd, 0, SRLV);
1686b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1687b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1688b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1689b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::sra(Register rd, Register rt, uint16_t sa) {
1690b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  GenInstrRegister(SPECIAL, zero_reg, rt, rd, sa, SRA);
1691b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1692b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1693b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1694b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::srav(Register rd, Register rt, Register rs) {
1695b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  GenInstrRegister(SPECIAL, rs, rt, rd, 0, SRAV);
1696b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1697b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1698b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1699b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::rotr(Register rd, Register rt, uint16_t sa) {
1700b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Should be called via MacroAssembler::Ror.
1701b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(rd.is_valid() && rt.is_valid() && is_uint5(sa));
1702b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(kArchVariant == kMips64r2);
1703b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Instr instr = SPECIAL | (1 << kRsShift) | (rt.code() << kRtShift)
1704b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      | (rd.code() << kRdShift) | (sa << kSaShift) | SRL;
1705b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  emit(instr);
1706b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1707b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1708b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1709b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::rotrv(Register rd, Register rt, Register rs) {
1710b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Should be called via MacroAssembler::Ror.
1711b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(rd.is_valid() && rt.is_valid() && rs.is_valid() );
1712b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(kArchVariant == kMips64r2);
1713b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Instr instr = SPECIAL | (rs.code() << kRsShift) | (rt.code() << kRtShift)
1714b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch     | (rd.code() << kRdShift) | (1 << kSaShift) | SRLV;
1715b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  emit(instr);
1716b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1717b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1718b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1719b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::dsll(Register rd, Register rt, uint16_t sa) {
1720b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  GenInstrRegister(SPECIAL, zero_reg, rt, rd, sa, DSLL);
1721b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1722b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1723b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1724b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::dsllv(Register rd, Register rt, Register rs) {
1725b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  GenInstrRegister(SPECIAL, rs, rt, rd, 0, DSLLV);
1726b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1727b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1728b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1729b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::dsrl(Register rd, Register rt, uint16_t sa) {
1730b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  GenInstrRegister(SPECIAL, zero_reg, rt, rd, sa, DSRL);
1731b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1732b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1733b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1734b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::dsrlv(Register rd, Register rt, Register rs) {
1735b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  GenInstrRegister(SPECIAL, rs, rt, rd, 0, DSRLV);
1736b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1737b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1738b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1739b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::drotr(Register rd, Register rt, uint16_t sa) {
1740b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(rd.is_valid() && rt.is_valid() && is_uint5(sa));
1741b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Instr instr = SPECIAL | (1 << kRsShift) | (rt.code() << kRtShift)
1742b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      | (rd.code() << kRdShift) | (sa << kSaShift) | DSRL;
1743b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  emit(instr);
1744b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1745b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1746b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1747b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::drotrv(Register rd, Register rt, Register rs) {
1748b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(rd.is_valid() && rt.is_valid() && rs.is_valid() );
1749b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Instr instr = SPECIAL | (rs.code() << kRsShift) | (rt.code() << kRtShift)
1750b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      | (rd.code() << kRdShift) | (1 << kSaShift) | DSRLV;
1751b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  emit(instr);
1752b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1753b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1754b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1755b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::dsra(Register rd, Register rt, uint16_t sa) {
1756b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  GenInstrRegister(SPECIAL, zero_reg, rt, rd, sa, DSRA);
1757b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1758b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1759b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1760b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::dsrav(Register rd, Register rt, Register rs) {
1761b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  GenInstrRegister(SPECIAL, rs, rt, rd, 0, DSRAV);
1762b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1763b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1764b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1765b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::dsll32(Register rd, Register rt, uint16_t sa) {
1766b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  GenInstrRegister(SPECIAL, zero_reg, rt, rd, sa, DSLL32);
1767b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1768b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1769b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1770b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::dsrl32(Register rd, Register rt, uint16_t sa) {
1771b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  GenInstrRegister(SPECIAL, zero_reg, rt, rd, sa, DSRL32);
1772b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1773b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1774b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1775b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::dsra32(Register rd, Register rt, uint16_t sa) {
1776b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  GenInstrRegister(SPECIAL, zero_reg, rt, rd, sa, DSRA32);
1777b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1778b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1779b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1780b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// ------------Memory-instructions-------------
1781b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1782b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Helper for base-reg + offset, when offset is larger than int16.
1783b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::LoadRegPlusOffsetToAt(const MemOperand& src) {
1784b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(!src.rm().is(at));
1785b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(is_int32(src.offset_));
1786b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  daddiu(at, zero_reg, (src.offset_ >> kLuiShift) & kImm16Mask);
1787b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  dsll(at, at, kLuiShift);
1788b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  ori(at, at, src.offset_ & kImm16Mask);  // Load 32-bit offset.
1789b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  daddu(at, at, src.rm());  // Add base register.
1790b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1791b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1792b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1793b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::lb(Register rd, const MemOperand& rs) {
1794b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (is_int16(rs.offset_)) {
1795b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    GenInstrImmediate(LB, rs.rm(), rd, rs.offset_);
1796b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } else {  // Offset > 16 bits, use multiple instructions to load.
1797b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    LoadRegPlusOffsetToAt(rs);
1798b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    GenInstrImmediate(LB, at, rd, 0);  // Equiv to lb(rd, MemOperand(at, 0));
1799b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1800b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1801b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1802b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1803b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::lbu(Register rd, const MemOperand& rs) {
1804b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (is_int16(rs.offset_)) {
1805b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    GenInstrImmediate(LBU, rs.rm(), rd, rs.offset_);
1806b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } else {  // Offset > 16 bits, use multiple instructions to load.
1807b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    LoadRegPlusOffsetToAt(rs);
1808b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    GenInstrImmediate(LBU, at, rd, 0);  // Equiv to lbu(rd, MemOperand(at, 0));
1809b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1810b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1811b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1812b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1813b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::lh(Register rd, const MemOperand& rs) {
1814b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (is_int16(rs.offset_)) {
1815b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    GenInstrImmediate(LH, rs.rm(), rd, rs.offset_);
1816b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } else {  // Offset > 16 bits, use multiple instructions to load.
1817b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    LoadRegPlusOffsetToAt(rs);
1818b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    GenInstrImmediate(LH, at, rd, 0);  // Equiv to lh(rd, MemOperand(at, 0));
1819b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1820b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1821b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1822b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1823b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::lhu(Register rd, const MemOperand& rs) {
1824b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (is_int16(rs.offset_)) {
1825b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    GenInstrImmediate(LHU, rs.rm(), rd, rs.offset_);
1826b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } else {  // Offset > 16 bits, use multiple instructions to load.
1827b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    LoadRegPlusOffsetToAt(rs);
1828b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    GenInstrImmediate(LHU, at, rd, 0);  // Equiv to lhu(rd, MemOperand(at, 0));
1829b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1830b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1831b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1832b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1833b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::lw(Register rd, const MemOperand& rs) {
1834b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (is_int16(rs.offset_)) {
1835b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    GenInstrImmediate(LW, rs.rm(), rd, rs.offset_);
1836b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } else {  // Offset > 16 bits, use multiple instructions to load.
1837b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    LoadRegPlusOffsetToAt(rs);
1838b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    GenInstrImmediate(LW, at, rd, 0);  // Equiv to lw(rd, MemOperand(at, 0));
1839b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1840b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1841b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1842b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1843b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::lwu(Register rd, const MemOperand& rs) {
1844b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (is_int16(rs.offset_)) {
1845b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    GenInstrImmediate(LWU, rs.rm(), rd, rs.offset_);
1846b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } else {  // Offset > 16 bits, use multiple instructions to load.
1847b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    LoadRegPlusOffsetToAt(rs);
1848b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    GenInstrImmediate(LWU, at, rd, 0);  // Equiv to lwu(rd, MemOperand(at, 0));
1849b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1850b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1851b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1852b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1853b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::lwl(Register rd, const MemOperand& rs) {
1854b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  GenInstrImmediate(LWL, rs.rm(), rd, rs.offset_);
1855b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1856b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1857b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1858b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::lwr(Register rd, const MemOperand& rs) {
1859b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  GenInstrImmediate(LWR, rs.rm(), rd, rs.offset_);
1860b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1861b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1862b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1863b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::sb(Register rd, const MemOperand& rs) {
1864b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (is_int16(rs.offset_)) {
1865b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    GenInstrImmediate(SB, rs.rm(), rd, rs.offset_);
1866b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } else {  // Offset > 16 bits, use multiple instructions to store.
1867b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    LoadRegPlusOffsetToAt(rs);
1868b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    GenInstrImmediate(SB, at, rd, 0);  // Equiv to sb(rd, MemOperand(at, 0));
1869b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1870b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1871b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1872b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1873b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::sh(Register rd, const MemOperand& rs) {
1874b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (is_int16(rs.offset_)) {
1875b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    GenInstrImmediate(SH, rs.rm(), rd, rs.offset_);
1876b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } else {  // Offset > 16 bits, use multiple instructions to store.
1877b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    LoadRegPlusOffsetToAt(rs);
1878b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    GenInstrImmediate(SH, at, rd, 0);  // Equiv to sh(rd, MemOperand(at, 0));
1879b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1880b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1881b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1882b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1883b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::sw(Register rd, const MemOperand& rs) {
1884b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (is_int16(rs.offset_)) {
1885b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    GenInstrImmediate(SW, rs.rm(), rd, rs.offset_);
1886b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } else {  // Offset > 16 bits, use multiple instructions to store.
1887b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    LoadRegPlusOffsetToAt(rs);
1888b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    GenInstrImmediate(SW, at, rd, 0);  // Equiv to sw(rd, MemOperand(at, 0));
1889b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1890b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1891b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1892b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1893b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::swl(Register rd, const MemOperand& rs) {
1894b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  GenInstrImmediate(SWL, rs.rm(), rd, rs.offset_);
1895b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1896b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1897b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1898b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::swr(Register rd, const MemOperand& rs) {
1899b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  GenInstrImmediate(SWR, rs.rm(), rd, rs.offset_);
1900b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1901b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1902b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1903b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::lui(Register rd, int32_t j) {
1904b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(is_uint16(j));
1905b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  GenInstrImmediate(LUI, zero_reg, rd, j);
1906b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1907b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1908b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1909b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::aui(Register rs, Register rt, int32_t j) {
1910b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // This instruction uses same opcode as 'lui'. The difference in encoding is
1911b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // 'lui' has zero reg. for rs field.
1912b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(is_uint16(j));
1913b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  GenInstrImmediate(LUI, rs, rt, j);
1914b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1915b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1916b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1917b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::daui(Register rs, Register rt, int32_t j) {
1918b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(is_uint16(j));
1919b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  GenInstrImmediate(DAUI, rs, rt, j);
1920b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1921b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1922b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1923b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::dahi(Register rs, int32_t j) {
1924b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(is_uint16(j));
1925b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  GenInstrImmediate(REGIMM, rs, DAHI, j);
1926b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1927b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1928b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1929b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::dati(Register rs, int32_t j) {
1930b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(is_uint16(j));
1931b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  GenInstrImmediate(REGIMM, rs, DATI, j);
1932b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1933b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1934b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1935b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::ldl(Register rd, const MemOperand& rs) {
1936b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  GenInstrImmediate(LDL, rs.rm(), rd, rs.offset_);
1937b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1938b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1939b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1940b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::ldr(Register rd, const MemOperand& rs) {
1941b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  GenInstrImmediate(LDR, rs.rm(), rd, rs.offset_);
1942b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1943b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1944b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1945b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::sdl(Register rd, const MemOperand& rs) {
1946b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  GenInstrImmediate(SDL, rs.rm(), rd, rs.offset_);
1947b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1948b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1949b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1950b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::sdr(Register rd, const MemOperand& rs) {
1951b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  GenInstrImmediate(SDR, rs.rm(), rd, rs.offset_);
1952b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1953b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1954b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1955b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::ld(Register rd, const MemOperand& rs) {
1956b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (is_int16(rs.offset_)) {
1957b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    GenInstrImmediate(LD, rs.rm(), rd, rs.offset_);
1958b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } else {  // Offset > 16 bits, use multiple instructions to load.
1959b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    LoadRegPlusOffsetToAt(rs);
1960b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    GenInstrImmediate(LD, at, rd, 0);  // Equiv to lw(rd, MemOperand(at, 0));
1961b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1962b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1963b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1964b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1965b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::sd(Register rd, const MemOperand& rs) {
1966b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (is_int16(rs.offset_)) {
1967b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    GenInstrImmediate(SD, rs.rm(), rd, rs.offset_);
1968b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } else {  // Offset > 16 bits, use multiple instructions to store.
1969b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    LoadRegPlusOffsetToAt(rs);
1970b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    GenInstrImmediate(SD, at, rd, 0);  // Equiv to sw(rd, MemOperand(at, 0));
1971b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1972b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1973b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1974b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1975b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// -------------Misc-instructions--------------
1976b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1977b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Break / Trap instructions.
1978b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::break_(uint32_t code, bool break_as_stop) {
1979b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK((code & ~0xfffff) == 0);
1980b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // We need to invalidate breaks that could be stops as well because the
1981b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // simulator expects a char pointer after the stop instruction.
1982b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // See constants-mips.h for explanation.
1983b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK((break_as_stop &&
1984b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          code <= kMaxStopCode &&
1985b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          code > kMaxWatchpointCode) ||
1986b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch         (!break_as_stop &&
1987b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          (code > kMaxStopCode ||
1988b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch           code <= kMaxWatchpointCode)));
1989b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Instr break_instr = SPECIAL | BREAK | (code << 6);
1990b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  emit(break_instr);
1991b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1992b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1993b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1994b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::stop(const char* msg, uint32_t code) {
1995b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(code > kMaxWatchpointCode);
1996b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(code <= kMaxStopCode);
1997b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#if defined(V8_HOST_ARCH_MIPS) || defined(V8_HOST_ARCH_MIPS64)
1998b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  break_(0x54321);
1999b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#else  // V8_HOST_ARCH_MIPS
2000b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  BlockTrampolinePoolFor(3);
2001b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // The Simulator will handle the stop instruction and get the message address.
2002b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // On MIPS stop() is just a special kind of break_().
2003b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  break_(code, true);
2004b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  emit(reinterpret_cast<uint64_t>(msg));
2005b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#endif
2006b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2007b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2008b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2009b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::tge(Register rs, Register rt, uint16_t code) {
2010b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(is_uint10(code));
2011b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Instr instr = SPECIAL | TGE | rs.code() << kRsShift
2012b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      | rt.code() << kRtShift | code << 6;
2013b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  emit(instr);
2014b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2015b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2016b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2017b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::tgeu(Register rs, Register rt, uint16_t code) {
2018b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(is_uint10(code));
2019b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Instr instr = SPECIAL | TGEU | rs.code() << kRsShift
2020b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      | rt.code() << kRtShift | code << 6;
2021b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  emit(instr);
2022b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2023b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2024b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2025b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::tlt(Register rs, Register rt, uint16_t code) {
2026b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(is_uint10(code));
2027b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Instr instr =
2028b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      SPECIAL | TLT | rs.code() << kRsShift | rt.code() << kRtShift | code << 6;
2029b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  emit(instr);
2030b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2031b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2032b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2033b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::tltu(Register rs, Register rt, uint16_t code) {
2034b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(is_uint10(code));
2035b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Instr instr =
2036b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      SPECIAL | TLTU | rs.code() << kRsShift
2037b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      | rt.code() << kRtShift | code << 6;
2038b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  emit(instr);
2039b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2040b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2041b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2042b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::teq(Register rs, Register rt, uint16_t code) {
2043b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(is_uint10(code));
2044b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Instr instr =
2045b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      SPECIAL | TEQ | rs.code() << kRsShift | rt.code() << kRtShift | code << 6;
2046b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  emit(instr);
2047b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2048b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2049b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2050b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::tne(Register rs, Register rt, uint16_t code) {
2051b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(is_uint10(code));
2052b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Instr instr =
2053b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      SPECIAL | TNE | rs.code() << kRsShift | rt.code() << kRtShift | code << 6;
2054b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  emit(instr);
2055b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2056b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2057b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2058b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Move from HI/LO register.
2059b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2060b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::mfhi(Register rd) {
2061b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  GenInstrRegister(SPECIAL, zero_reg, zero_reg, rd, 0, MFHI);
2062b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2063b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2064b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2065b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::mflo(Register rd) {
2066b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  GenInstrRegister(SPECIAL, zero_reg, zero_reg, rd, 0, MFLO);
2067b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2068b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2069b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2070b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Set on less than instructions.
2071b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::slt(Register rd, Register rs, Register rt) {
2072b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  GenInstrRegister(SPECIAL, rs, rt, rd, 0, SLT);
2073b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2074b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2075b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2076b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::sltu(Register rd, Register rs, Register rt) {
2077b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  GenInstrRegister(SPECIAL, rs, rt, rd, 0, SLTU);
2078b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2079b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2080b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2081b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::slti(Register rt, Register rs, int32_t j) {
2082b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  GenInstrImmediate(SLTI, rs, rt, j);
2083b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2084b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2085b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2086b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::sltiu(Register rt, Register rs, int32_t j) {
2087b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  GenInstrImmediate(SLTIU, rs, rt, j);
2088b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2089b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2090b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2091b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Conditional move.
2092b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::movz(Register rd, Register rs, Register rt) {
2093b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  GenInstrRegister(SPECIAL, rs, rt, rd, 0, MOVZ);
2094b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2095b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2096b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2097b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::movn(Register rd, Register rs, Register rt) {
2098b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  GenInstrRegister(SPECIAL, rs, rt, rd, 0, MOVN);
2099b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2100b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2101b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2102b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::movt(Register rd, Register rs, uint16_t cc) {
2103b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Register rt;
2104b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  rt.code_ = (cc & 0x0007) << 2 | 1;
2105b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  GenInstrRegister(SPECIAL, rs, rt, rd, 0, MOVCI);
2106b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2107b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2108b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2109b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::movf(Register rd, Register rs, uint16_t cc) {
2110b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Register rt;
2111b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  rt.code_ = (cc & 0x0007) << 2 | 0;
2112b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  GenInstrRegister(SPECIAL, rs, rt, rd, 0, MOVCI);
2113b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2114b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2115b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2116b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::sel(SecondaryField fmt, FPURegister fd,
2117b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    FPURegister ft, FPURegister fs, uint8_t sel) {
2118b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(kArchVariant == kMips64r6);
2119b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(fmt == D);
2120b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(fmt == S);
2121b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2122b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Instr instr = COP1 | fmt << kRsShift | ft.code() << kFtShift |
2123b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      fs.code() << kFsShift | fd.code() << kFdShift | SEL;
2124b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  emit(instr);
2125b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2126b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2127b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2128b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// GPR.
2129b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::seleqz(Register rs, Register rt, Register rd) {
2130b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(kArchVariant == kMips64r6);
2131b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  GenInstrRegister(SPECIAL, rs, rt, rd, 0, SELEQZ_S);
2132b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2133b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2134b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2135b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// FPR.
2136b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::seleqz(SecondaryField fmt, FPURegister fd,
2137b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    FPURegister ft, FPURegister fs) {
2138b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(kArchVariant == kMips64r6);
2139b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(fmt == D);
2140b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(fmt == S);
2141b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2142b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Instr instr = COP1 | fmt << kRsShift | ft.code() << kFtShift |
2143b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      fs.code() << kFsShift | fd.code() << kFdShift | SELEQZ_C;
2144b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  emit(instr);
2145b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2146b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2147b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2148b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// GPR.
2149b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::selnez(Register rs, Register rt, Register rd) {
2150b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(kArchVariant == kMips64r6);
2151b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  GenInstrRegister(SPECIAL, rs, rt, rd, 0, SELNEZ_S);
2152b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2153b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2154b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2155b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// FPR.
2156b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::selnez(SecondaryField fmt, FPURegister fd,
2157b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    FPURegister ft, FPURegister fs) {
2158b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(kArchVariant == kMips64r6);
2159b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(fmt == D);
2160b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(fmt == S);
2161b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2162b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Instr instr = COP1 | fmt << kRsShift | ft.code() << kFtShift |
2163b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      fs.code() << kFsShift | fd.code() << kFdShift | SELNEZ_C;
2164b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  emit(instr);
2165b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2166b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2167b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2168b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Bit twiddling.
2169b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::clz(Register rd, Register rs) {
2170b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (kArchVariant != kMips64r6) {
2171b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Clz instr requires same GPR number in 'rd' and 'rt' fields.
2172b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    GenInstrRegister(SPECIAL2, rs, rd, rd, 0, CLZ);
2173b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } else {
2174b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    GenInstrRegister(SPECIAL, rs, zero_reg, rd, 1, CLZ_R6);
2175b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
2176b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2177b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2178b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2179b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::ins_(Register rt, Register rs, uint16_t pos, uint16_t size) {
2180b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Should be called via MacroAssembler::Ins.
2181b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Ins instr has 'rt' field as dest, and two uint5: msb, lsb.
2182b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK((kArchVariant == kMips64r2) || (kArchVariant == kMips64r6));
2183b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  GenInstrRegister(SPECIAL3, rs, rt, pos + size - 1, pos, INS);
2184b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2185b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2186b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2187b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::ext_(Register rt, Register rs, uint16_t pos, uint16_t size) {
2188b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Should be called via MacroAssembler::Ext.
2189b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Ext instr has 'rt' field as dest, and two uint5: msb, lsb.
2190b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(kArchVariant == kMips64r2 || kArchVariant == kMips64r6);
2191b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  GenInstrRegister(SPECIAL3, rs, rt, size - 1, pos, EXT);
2192b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2193b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2194b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2195b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::pref(int32_t hint, const MemOperand& rs) {
2196b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(is_uint5(hint) && is_uint16(rs.offset_));
2197b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Instr instr = PREF | (rs.rm().code() << kRsShift) | (hint << kRtShift)
2198b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      | (rs.offset_);
2199b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  emit(instr);
2200b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2201b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2202b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2203b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// --------Coprocessor-instructions----------------
2204b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2205b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Load, store, move.
2206b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::lwc1(FPURegister fd, const MemOperand& src) {
2207b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  GenInstrImmediate(LWC1, src.rm(), fd, src.offset_);
2208b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2209b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2210b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2211b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::ldc1(FPURegister fd, const MemOperand& src) {
2212b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  GenInstrImmediate(LDC1, src.rm(), fd, src.offset_);
2213b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2214b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2215b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2216b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::swc1(FPURegister fd, const MemOperand& src) {
2217b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  GenInstrImmediate(SWC1, src.rm(), fd, src.offset_);
2218b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2219b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2220b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2221b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::sdc1(FPURegister fd, const MemOperand& src) {
2222b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  GenInstrImmediate(SDC1, src.rm(), fd, src.offset_);
2223b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2224b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2225b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2226b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::mtc1(Register rt, FPURegister fs) {
2227b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  GenInstrRegister(COP1, MTC1, rt, fs, f0);
2228b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2229b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2230b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2231b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::mthc1(Register rt, FPURegister fs) {
2232b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  GenInstrRegister(COP1, MTHC1, rt, fs, f0);
2233b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2234b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2235b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2236b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::dmtc1(Register rt, FPURegister fs) {
2237b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  GenInstrRegister(COP1, DMTC1, rt, fs, f0);
2238b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2239b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2240b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2241b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::mfc1(Register rt, FPURegister fs) {
2242b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  GenInstrRegister(COP1, MFC1, rt, fs, f0);
2243b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2244b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2245b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2246b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::mfhc1(Register rt, FPURegister fs) {
2247b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  GenInstrRegister(COP1, MFHC1, rt, fs, f0);
2248b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2249b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2250b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2251b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::dmfc1(Register rt, FPURegister fs) {
2252b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  GenInstrRegister(COP1, DMFC1, rt, fs, f0);
2253b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2254b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2255b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2256b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::ctc1(Register rt, FPUControlRegister fs) {
2257b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  GenInstrRegister(COP1, CTC1, rt, fs);
2258b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2259b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2260b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2261b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::cfc1(Register rt, FPUControlRegister fs) {
2262b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  GenInstrRegister(COP1, CFC1, rt, fs);
2263b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2264b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2265b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2266b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::DoubleAsTwoUInt32(double d, uint32_t* lo, uint32_t* hi) {
2267b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  uint64_t i;
2268b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  memcpy(&i, &d, 8);
2269b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2270b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  *lo = i & 0xffffffff;
2271b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  *hi = i >> 32;
2272b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2273b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2274b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2275b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Arithmetic.
2276b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2277b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::add_d(FPURegister fd, FPURegister fs, FPURegister ft) {
2278b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  GenInstrRegister(COP1, D, ft, fs, fd, ADD_D);
2279b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2280b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2281b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2282b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::sub_d(FPURegister fd, FPURegister fs, FPURegister ft) {
2283b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  GenInstrRegister(COP1, D, ft, fs, fd, SUB_D);
2284b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2285b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2286b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2287b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::mul_d(FPURegister fd, FPURegister fs, FPURegister ft) {
2288b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  GenInstrRegister(COP1, D, ft, fs, fd, MUL_D);
2289b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2290b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2291b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2292b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::madd_d(FPURegister fd, FPURegister fr, FPURegister fs,
2293b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    FPURegister ft) {
2294b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  GenInstrRegister(COP1X, fr, ft, fs, fd, MADD_D);
2295b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2296b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2297b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2298b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::div_d(FPURegister fd, FPURegister fs, FPURegister ft) {
2299b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  GenInstrRegister(COP1, D, ft, fs, fd, DIV_D);
2300b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2301b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2302b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2303b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::abs_d(FPURegister fd, FPURegister fs) {
2304b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  GenInstrRegister(COP1, D, f0, fs, fd, ABS_D);
2305b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2306b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2307b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2308b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::mov_d(FPURegister fd, FPURegister fs) {
2309b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  GenInstrRegister(COP1, D, f0, fs, fd, MOV_D);
2310b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2311b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2312b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2313b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::neg_d(FPURegister fd, FPURegister fs) {
2314b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  GenInstrRegister(COP1, D, f0, fs, fd, NEG_D);
2315b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2316b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2317b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2318b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::sqrt_d(FPURegister fd, FPURegister fs) {
2319b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  GenInstrRegister(COP1, D, f0, fs, fd, SQRT_D);
2320b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2321b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2322b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2323b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Conversions.
2324b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2325b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::cvt_w_s(FPURegister fd, FPURegister fs) {
2326b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  GenInstrRegister(COP1, S, f0, fs, fd, CVT_W_S);
2327b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2328b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2329b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2330b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::cvt_w_d(FPURegister fd, FPURegister fs) {
2331b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  GenInstrRegister(COP1, D, f0, fs, fd, CVT_W_D);
2332b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2333b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2334b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2335b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::trunc_w_s(FPURegister fd, FPURegister fs) {
2336b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  GenInstrRegister(COP1, S, f0, fs, fd, TRUNC_W_S);
2337b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2338b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2339b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2340b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::trunc_w_d(FPURegister fd, FPURegister fs) {
2341b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  GenInstrRegister(COP1, D, f0, fs, fd, TRUNC_W_D);
2342b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2343b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2344b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2345b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::round_w_s(FPURegister fd, FPURegister fs) {
2346b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  GenInstrRegister(COP1, S, f0, fs, fd, ROUND_W_S);
2347b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2348b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2349b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2350b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::round_w_d(FPURegister fd, FPURegister fs) {
2351b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  GenInstrRegister(COP1, D, f0, fs, fd, ROUND_W_D);
2352b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2353b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2354b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2355b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::floor_w_s(FPURegister fd, FPURegister fs) {
2356b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  GenInstrRegister(COP1, S, f0, fs, fd, FLOOR_W_S);
2357b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2358b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2359b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2360b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::floor_w_d(FPURegister fd, FPURegister fs) {
2361b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  GenInstrRegister(COP1, D, f0, fs, fd, FLOOR_W_D);
2362b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2363b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2364b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2365b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::ceil_w_s(FPURegister fd, FPURegister fs) {
2366b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  GenInstrRegister(COP1, S, f0, fs, fd, CEIL_W_S);
2367b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2368b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2369b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2370b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::ceil_w_d(FPURegister fd, FPURegister fs) {
2371b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  GenInstrRegister(COP1, D, f0, fs, fd, CEIL_W_D);
2372b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2373b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2374b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2375b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::cvt_l_s(FPURegister fd, FPURegister fs) {
2376b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(kArchVariant == kMips64r2);
2377b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  GenInstrRegister(COP1, S, f0, fs, fd, CVT_L_S);
2378b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2379b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2380b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2381b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::cvt_l_d(FPURegister fd, FPURegister fs) {
2382b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(kArchVariant == kMips64r2);
2383b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  GenInstrRegister(COP1, D, f0, fs, fd, CVT_L_D);
2384b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2385b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2386b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2387b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::trunc_l_s(FPURegister fd, FPURegister fs) {
2388b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(kArchVariant == kMips64r2);
2389b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  GenInstrRegister(COP1, S, f0, fs, fd, TRUNC_L_S);
2390b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2391b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2392b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2393b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::trunc_l_d(FPURegister fd, FPURegister fs) {
2394b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(kArchVariant == kMips64r2);
2395b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  GenInstrRegister(COP1, D, f0, fs, fd, TRUNC_L_D);
2396b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2397b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2398b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2399b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::round_l_s(FPURegister fd, FPURegister fs) {
2400b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  GenInstrRegister(COP1, S, f0, fs, fd, ROUND_L_S);
2401b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2402b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2403b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2404b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::round_l_d(FPURegister fd, FPURegister fs) {
2405b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  GenInstrRegister(COP1, D, f0, fs, fd, ROUND_L_D);
2406b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2407b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2408b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2409b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::floor_l_s(FPURegister fd, FPURegister fs) {
2410b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  GenInstrRegister(COP1, S, f0, fs, fd, FLOOR_L_S);
2411b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2412b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2413b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2414b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::floor_l_d(FPURegister fd, FPURegister fs) {
2415b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  GenInstrRegister(COP1, D, f0, fs, fd, FLOOR_L_D);
2416b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2417b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2418b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2419b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::ceil_l_s(FPURegister fd, FPURegister fs) {
2420b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  GenInstrRegister(COP1, S, f0, fs, fd, CEIL_L_S);
2421b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2422b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2423b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2424b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::ceil_l_d(FPURegister fd, FPURegister fs) {
2425b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  GenInstrRegister(COP1, D, f0, fs, fd, CEIL_L_D);
2426b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2427b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2428b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2429b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::min(SecondaryField fmt, FPURegister fd, FPURegister ft,
2430b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    FPURegister fs) {
2431b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(kArchVariant == kMips64r6);
2432b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK((fmt == D) || (fmt == S));
2433b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  GenInstrRegister(COP1, fmt, ft, fs, fd, MIN);
2434b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2435b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2436b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2437b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::mina(SecondaryField fmt, FPURegister fd, FPURegister ft,
2438b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    FPURegister fs) {
2439b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(kArchVariant == kMips64r6);
2440b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK((fmt == D) || (fmt == S));
2441b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  GenInstrRegister(COP1, fmt, ft, fs, fd, MINA);
2442b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2443b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2444b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2445b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::max(SecondaryField fmt, FPURegister fd, FPURegister ft,
2446b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    FPURegister fs) {
2447b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(kArchVariant == kMips64r6);
2448b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK((fmt == D) || (fmt == S));
2449b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  GenInstrRegister(COP1, fmt, ft, fs, fd, MAX);
2450b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2451b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2452b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2453b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::maxa(SecondaryField fmt, FPURegister fd, FPURegister ft,
2454b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    FPURegister fs) {
2455b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(kArchVariant == kMips64r6);
2456b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK((fmt == D) || (fmt == S));
2457b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  GenInstrRegister(COP1, fmt, ft, fs, fd, MAXA);
2458b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2459b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2460b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2461b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::cvt_s_w(FPURegister fd, FPURegister fs) {
2462b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  GenInstrRegister(COP1, W, f0, fs, fd, CVT_S_W);
2463b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2464b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2465b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2466b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::cvt_s_l(FPURegister fd, FPURegister fs) {
2467b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(kArchVariant == kMips64r2);
2468b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  GenInstrRegister(COP1, L, f0, fs, fd, CVT_S_L);
2469b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2470b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2471b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2472b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::cvt_s_d(FPURegister fd, FPURegister fs) {
2473b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  GenInstrRegister(COP1, D, f0, fs, fd, CVT_S_D);
2474b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2475b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2476b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2477b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::cvt_d_w(FPURegister fd, FPURegister fs) {
2478b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  GenInstrRegister(COP1, W, f0, fs, fd, CVT_D_W);
2479b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2480b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2481b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2482b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::cvt_d_l(FPURegister fd, FPURegister fs) {
2483b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(kArchVariant == kMips64r2);
2484b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  GenInstrRegister(COP1, L, f0, fs, fd, CVT_D_L);
2485b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2486b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2487b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2488b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::cvt_d_s(FPURegister fd, FPURegister fs) {
2489b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  GenInstrRegister(COP1, S, f0, fs, fd, CVT_D_S);
2490b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2491b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2492b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2493b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Conditions for >= MIPSr6.
2494b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::cmp(FPUCondition cond, SecondaryField fmt,
2495b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    FPURegister fd, FPURegister fs, FPURegister ft) {
2496b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(kArchVariant == kMips64r6);
2497b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK((fmt & ~(31 << kRsShift)) == 0);
2498b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Instr instr = COP1 | fmt | ft.code() << kFtShift |
2499b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      fs.code() << kFsShift | fd.code() << kFdShift | (0 << 5) | cond;
2500b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  emit(instr);
2501b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2502b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2503b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2504b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::bc1eqz(int16_t offset, FPURegister ft) {
2505b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(kArchVariant == kMips64r6);
2506b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Instr instr = COP1 | BC1EQZ | ft.code() << kFtShift | (offset & kImm16Mask);
2507b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  emit(instr);
2508b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2509b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2510b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2511b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::bc1nez(int16_t offset, FPURegister ft) {
2512b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(kArchVariant == kMips64r6);
2513b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Instr instr = COP1 | BC1NEZ | ft.code() << kFtShift | (offset & kImm16Mask);
2514b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  emit(instr);
2515b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2516b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2517b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2518b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Conditions for < MIPSr6.
2519b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::c(FPUCondition cond, SecondaryField fmt,
2520b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    FPURegister fs, FPURegister ft, uint16_t cc) {
2521b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(kArchVariant != kMips64r6);
2522b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(is_uint3(cc));
2523b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK((fmt & ~(31 << kRsShift)) == 0);
2524b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Instr instr = COP1 | fmt | ft.code() << kFtShift | fs.code() << kFsShift
2525b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      | cc << 8 | 3 << 4 | cond;
2526b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  emit(instr);
2527b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2528b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2529b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2530b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::fcmp(FPURegister src1, const double src2,
2531b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      FPUCondition cond) {
2532b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(src2 == 0.0);
2533b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  mtc1(zero_reg, f14);
2534b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  cvt_d_w(f14, f14);
2535b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  c(cond, D, src1, f14, 0);
2536b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2537b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2538b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2539b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::bc1f(int16_t offset, uint16_t cc) {
2540b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(is_uint3(cc));
2541b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Instr instr = COP1 | BC1 | cc << 18 | 0 << 16 | (offset & kImm16Mask);
2542b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  emit(instr);
2543b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2544b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2545b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2546b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::bc1t(int16_t offset, uint16_t cc) {
2547b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(is_uint3(cc));
2548b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Instr instr = COP1 | BC1 | cc << 18 | 1 << 16 | (offset & kImm16Mask);
2549b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  emit(instr);
2550b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2551b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2552b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2553b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Debugging.
2554b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::RecordJSReturn() {
2555b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  positions_recorder()->WriteRecordedPositions();
2556b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  CheckBuffer();
2557b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  RecordRelocInfo(RelocInfo::JS_RETURN);
2558b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2559b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2560b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2561b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::RecordDebugBreakSlot() {
2562b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  positions_recorder()->WriteRecordedPositions();
2563b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  CheckBuffer();
2564b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  RecordRelocInfo(RelocInfo::DEBUG_BREAK_SLOT);
2565b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2566b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2567b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2568b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::RecordComment(const char* msg) {
2569b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (FLAG_code_comments) {
2570b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    CheckBuffer();
2571b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    RecordRelocInfo(RelocInfo::COMMENT, reinterpret_cast<intptr_t>(msg));
2572b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
2573b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2574b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2575b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2576b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochint Assembler::RelocateInternalReference(byte* pc, intptr_t pc_delta) {
2577b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Instr instr = instr_at(pc);
2578b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(IsJ(instr) || IsLui(instr));
2579b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (IsLui(instr)) {
2580b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Instr instr_lui = instr_at(pc + 0 * Assembler::kInstrSize);
2581b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Instr instr_ori = instr_at(pc + 1 * Assembler::kInstrSize);
2582b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Instr instr_ori2 = instr_at(pc + 3 * Assembler::kInstrSize);
2583b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(IsOri(instr_ori));
2584b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(IsOri(instr_ori2));
2585b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // TODO(plind): symbolic names for the shifts.
2586b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    int64_t imm = (instr_lui & static_cast<int64_t>(kImm16Mask)) << 48;
2587b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    imm |= (instr_ori & static_cast<int64_t>(kImm16Mask)) << 32;
2588b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    imm |= (instr_ori2 & static_cast<int64_t>(kImm16Mask)) << 16;
2589b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Sign extend address.
2590b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    imm >>= 16;
2591b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2592b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (imm == kEndOfJumpChain) {
2593b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      return 0;  // Number of instructions patched.
2594b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
2595b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    imm += pc_delta;
2596b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK((imm & 3) == 0);
2597b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2598b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    instr_lui &= ~kImm16Mask;
2599b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    instr_ori &= ~kImm16Mask;
2600b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    instr_ori2 &= ~kImm16Mask;
2601b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2602b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    instr_at_put(pc + 0 * Assembler::kInstrSize,
2603b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                 instr_lui | ((imm >> 32) & kImm16Mask));
2604b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    instr_at_put(pc + 1 * Assembler::kInstrSize,
2605b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                 instr_ori | (imm >> 16 & kImm16Mask));
2606b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    instr_at_put(pc + 3 * Assembler::kInstrSize,
2607b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                 instr_ori2 | (imm & kImm16Mask));
2608b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return 4;  // Number of instructions patched.
2609b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } else {
2610b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    uint32_t imm28 = (instr & static_cast<int32_t>(kImm26Mask)) << 2;
2611b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (static_cast<int32_t>(imm28) == kEndOfJumpChain) {
2612b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      return 0;  // Number of instructions patched.
2613b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
2614b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2615b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    imm28 += pc_delta;
2616b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    imm28 &= kImm28Mask;
2617b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK((imm28 & 3) == 0);
2618b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2619b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    instr &= ~kImm26Mask;
2620b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    uint32_t imm26 = imm28 >> 2;
2621b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(is_uint26(imm26));
2622b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2623b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    instr_at_put(pc, instr | (imm26 & kImm26Mask));
2624b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return 1;  // Number of instructions patched.
2625b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
2626b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2627b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2628b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2629b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::GrowBuffer() {
2630b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (!own_buffer_) FATAL("external code buffer is too small");
2631b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2632b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Compute new buffer size.
2633b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  CodeDesc desc;  // The new buffer.
2634b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (buffer_size_ < 1 * MB) {
2635b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    desc.buffer_size = 2*buffer_size_;
2636b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } else {
2637b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    desc.buffer_size = buffer_size_ + 1*MB;
2638b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
2639b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  CHECK_GT(desc.buffer_size, 0);  // No overflow.
2640b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2641b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Set up new buffer.
2642b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  desc.buffer = NewArray<byte>(desc.buffer_size);
2643b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2644b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  desc.instr_size = pc_offset();
2645b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  desc.reloc_size = (buffer_ + buffer_size_) - reloc_info_writer.pos();
2646b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2647b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Copy the data.
2648b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  intptr_t pc_delta = desc.buffer - buffer_;
2649b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  intptr_t rc_delta = (desc.buffer + desc.buffer_size) -
2650b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      (buffer_ + buffer_size_);
2651b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  MemMove(desc.buffer, buffer_, desc.instr_size);
2652b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  MemMove(reloc_info_writer.pos() + rc_delta,
2653b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch              reloc_info_writer.pos(), desc.reloc_size);
2654b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2655b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Switch buffers.
2656b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DeleteArray(buffer_);
2657b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  buffer_ = desc.buffer;
2658b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  buffer_size_ = desc.buffer_size;
2659b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  pc_ += pc_delta;
2660b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  reloc_info_writer.Reposition(reloc_info_writer.pos() + rc_delta,
2661b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                               reloc_info_writer.last_pc() + pc_delta);
2662b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2663b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Relocate runtime entries.
2664b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  for (RelocIterator it(desc); !it.done(); it.next()) {
2665b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    RelocInfo::Mode rmode = it.rinfo()->rmode();
2666b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (rmode == RelocInfo::INTERNAL_REFERENCE) {
2667b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      byte* p = reinterpret_cast<byte*>(it.rinfo()->pc());
2668b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      RelocateInternalReference(p, pc_delta);
2669b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
2670b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
2671b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2672b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(!overflow());
2673b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2674b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2675b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2676b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::db(uint8_t data) {
2677b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  CheckBuffer();
2678b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  *reinterpret_cast<uint8_t*>(pc_) = data;
2679b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  pc_ += sizeof(uint8_t);
2680b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2681b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2682b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2683b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::dd(uint32_t data) {
2684b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  CheckBuffer();
2685b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  *reinterpret_cast<uint32_t*>(pc_) = data;
2686b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  pc_ += sizeof(uint32_t);
2687b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2688b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2689b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2690b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::emit_code_stub_address(Code* stub) {
2691b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  CheckBuffer();
2692b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  *reinterpret_cast<uint64_t*>(pc_) =
2693b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      reinterpret_cast<uint64_t>(stub->instruction_start());
2694b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  pc_ += sizeof(uint64_t);
2695b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2696b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2697b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2698b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::RecordRelocInfo(RelocInfo::Mode rmode, intptr_t data) {
2699b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // We do not try to reuse pool constants.
2700b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  RelocInfo rinfo(pc_, rmode, data, NULL);
2701b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (rmode >= RelocInfo::JS_RETURN && rmode <= RelocInfo::DEBUG_BREAK_SLOT) {
2702b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Adjust code for new modes.
2703b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(RelocInfo::IsDebugBreakSlot(rmode)
2704b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch           || RelocInfo::IsJSReturn(rmode)
2705b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch           || RelocInfo::IsComment(rmode)
2706b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch           || RelocInfo::IsPosition(rmode));
2707b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // These modes do not need an entry in the constant pool.
2708b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
2709b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (!RelocInfo::IsNone(rinfo.rmode())) {
2710b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Don't record external references unless the heap will be serialized.
2711b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (rmode == RelocInfo::EXTERNAL_REFERENCE &&
2712b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        !serializer_enabled() && !emit_debug_code()) {
2713b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      return;
2714b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
2715b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(buffer_space() >= kMaxRelocSize);  // Too late to grow buffer here.
2716b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (rmode == RelocInfo::CODE_TARGET_WITH_ID) {
2717b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      RelocInfo reloc_info_with_ast_id(pc_,
2718b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                       rmode,
2719b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                       RecordedAstId().ToInt(),
2720b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                       NULL);
2721b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      ClearRecordedAstId();
2722b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      reloc_info_writer.Write(&reloc_info_with_ast_id);
2723b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    } else {
2724b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      reloc_info_writer.Write(&rinfo);
2725b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
2726b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
2727b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2728b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2729b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2730b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::BlockTrampolinePoolFor(int instructions) {
2731b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  BlockTrampolinePoolBefore(pc_offset() + instructions * kInstrSize);
2732b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2733b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2734b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2735b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::CheckTrampolinePool() {
2736b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Some small sequences of instructions must not be broken up by the
2737b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // insertion of a trampoline pool; such sequences are protected by setting
2738b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // either trampoline_pool_blocked_nesting_ or no_trampoline_pool_before_,
2739b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // which are both checked here. Also, recursive calls to CheckTrampolinePool
2740b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // are blocked by trampoline_pool_blocked_nesting_.
2741b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if ((trampoline_pool_blocked_nesting_ > 0) ||
2742b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      (pc_offset() < no_trampoline_pool_before_)) {
2743b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Emission is currently blocked; make sure we try again as soon as
2744b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // possible.
2745b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (trampoline_pool_blocked_nesting_ > 0) {
2746b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      next_buffer_check_ = pc_offset() + kInstrSize;
2747b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    } else {
2748b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      next_buffer_check_ = no_trampoline_pool_before_;
2749b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
2750b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return;
2751b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
2752b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2753b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(!trampoline_emitted_);
2754b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(unbound_labels_count_ >= 0);
2755b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (unbound_labels_count_ > 0) {
2756b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // First we emit jump (2 instructions), then we emit trampoline pool.
2757b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    { BlockTrampolinePoolScope block_trampoline_pool(this);
2758b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      Label after_pool;
2759b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      b(&after_pool);
2760b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      nop();
2761b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2762b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      int pool_start = pc_offset();
2763b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      for (int i = 0; i < unbound_labels_count_; i++) {
2764b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        uint64_t imm64;
2765b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        imm64 = jump_address(&after_pool);
2766b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        { BlockGrowBufferScope block_buf_growth(this);
2767b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          // Buffer growth (and relocation) must be blocked for internal
2768b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          // references until associated instructions are emitted and available
2769b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          // to be patched.
2770b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          RecordRelocInfo(RelocInfo::INTERNAL_REFERENCE);
2771b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          // TODO(plind): Verify this, presume I cannot use macro-assembler
2772b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          // here.
2773b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          lui(at, (imm64 >> 32) & kImm16Mask);
2774b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          ori(at, at, (imm64 >> 16) & kImm16Mask);
2775b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          dsll(at, at, 16);
2776b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          ori(at, at, imm64 & kImm16Mask);
2777b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        }
2778b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        jr(at);
2779b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        nop();
2780b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
2781b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      bind(&after_pool);
2782b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      trampoline_ = Trampoline(pool_start, unbound_labels_count_);
2783b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2784b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      trampoline_emitted_ = true;
2785b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      // As we are only going to emit trampoline once, we need to prevent any
2786b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      // further emission.
2787b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      next_buffer_check_ = kMaxInt;
2788b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
2789b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } else {
2790b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Number of branches to unbound label at this point is zero, so we can
2791b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // move next buffer check to maximum.
2792b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    next_buffer_check_ = pc_offset() +
2793b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        kMaxBranchOffset - kTrampolineSlotsSize * 16;
2794b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
2795b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return;
2796b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2797b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2798b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2799b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochAddress Assembler::target_address_at(Address pc) {
2800b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Instr instr0 = instr_at(pc);
2801b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Instr instr1 = instr_at(pc + 1 * kInstrSize);
2802b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Instr instr3 = instr_at(pc + 3 * kInstrSize);
2803b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2804b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Interpret 4 instructions for address generated by li: See listing in
2805b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Assembler::set_target_address_at() just below.
2806b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if ((GetOpcodeField(instr0) == LUI) && (GetOpcodeField(instr1) == ORI) &&
2807b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      (GetOpcodeField(instr3) == ORI)) {
2808b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Assemble the 48 bit value.
2809b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch     int64_t addr  = static_cast<int64_t>(
2810b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          ((uint64_t)(GetImmediate16(instr0)) << 32) |
2811b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          ((uint64_t)(GetImmediate16(instr1)) << 16) |
2812b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          ((uint64_t)(GetImmediate16(instr3))));
2813b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2814b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Sign extend to get canonical address.
2815b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    addr = (addr << 16) >> 16;
2816b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return reinterpret_cast<Address>(addr);
2817b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
2818b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // We should never get here, force a bad address if we do.
2819b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  UNREACHABLE();
2820b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return (Address)0x0;
2821b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2822b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2823b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2824b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// MIPS and ia32 use opposite encoding for qNaN and sNaN, such that ia32
2825b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// qNaN is a MIPS sNaN, and ia32 sNaN is MIPS qNaN. If running from a heap
2826b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// snapshot generated on ia32, the resulting MIPS sNaN must be quieted.
2827b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// OS::nan_value() returns a qNaN.
2828b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::QuietNaN(HeapObject* object) {
2829b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HeapNumber::cast(object)->set_value(base::OS::nan_value());
2830b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2831b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2832b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2833b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// On Mips64, a target address is stored in a 4-instruction sequence:
2834b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch//    0: lui(rd, (j.imm64_ >> 32) & kImm16Mask);
2835b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch//    1: ori(rd, rd, (j.imm64_ >> 16) & kImm16Mask);
2836b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch//    2: dsll(rd, rd, 16);
2837b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch//    3: ori(rd, rd, j.imm32_ & kImm16Mask);
2838b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch//
2839b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Patching the address must replace all the lui & ori instructions,
2840b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// and flush the i-cache.
2841b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch//
2842b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// There is an optimization below, which emits a nop when the address
2843b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// fits in just 16 bits. This is unlikely to help, and should be benchmarked,
2844b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// and possibly removed.
2845b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::set_target_address_at(Address pc,
2846b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                      Address target,
2847b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                      ICacheFlushMode icache_flush_mode) {
2848b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// There is an optimization where only 4 instructions are used to load address
2849b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// in code on MIP64 because only 48-bits of address is effectively used.
2850b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// It relies on fact the upper [63:48] bits are not used for virtual address
2851b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// translation and they have to be set according to value of bit 47 in order
2852b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// get canonical address.
2853b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Instr instr1 = instr_at(pc + kInstrSize);
2854b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  uint32_t rt_code = GetRt(instr1);
2855b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  uint32_t* p = reinterpret_cast<uint32_t*>(pc);
2856b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  uint64_t itarget = reinterpret_cast<uint64_t>(target);
2857b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2858b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#ifdef DEBUG
2859b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Check we have the result from a li macro-instruction.
2860b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Instr instr0 = instr_at(pc);
2861b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Instr instr3 = instr_at(pc + kInstrSize * 3);
2862b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  CHECK((GetOpcodeField(instr0) == LUI && GetOpcodeField(instr1) == ORI &&
2863b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch         GetOpcodeField(instr3) == ORI));
2864b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#endif
2865b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2866b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Must use 4 instructions to insure patchable code.
2867b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // lui rt, upper-16.
2868b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // ori rt, rt, lower-16.
2869b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // dsll rt, rt, 16.
2870b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // ori rt rt, lower-16.
2871b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  *p = LUI | (rt_code << kRtShift) | ((itarget >> 32) & kImm16Mask);
2872b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  *(p + 1) = ORI | (rt_code << kRtShift) | (rt_code << kRsShift)
2873b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      | ((itarget >> 16) & kImm16Mask);
2874b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  *(p + 3) = ORI | (rt_code << kRsShift) | (rt_code << kRtShift)
2875b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      | (itarget & kImm16Mask);
2876b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2877b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (icache_flush_mode != SKIP_ICACHE_FLUSH) {
2878b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    CpuFeatures::FlushICache(pc, 4 * Assembler::kInstrSize);
2879b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
2880b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2881b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2882b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2883b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::JumpLabelToJumpRegister(Address pc) {
2884b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Address pc points to lui/ori instructions.
2885b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Jump to label may follow at pc + 2 * kInstrSize.
2886b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  uint32_t* p = reinterpret_cast<uint32_t*>(pc);
2887b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#ifdef DEBUG
2888b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Instr instr1 = instr_at(pc);
2889b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#endif
2890b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Instr instr2 = instr_at(pc + 1 * kInstrSize);
2891b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Instr instr3 = instr_at(pc + 6 * kInstrSize);
2892b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bool patched = false;
2893b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2894b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (IsJal(instr3)) {
2895b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(GetOpcodeField(instr1) == LUI);
2896b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(GetOpcodeField(instr2) == ORI);
2897b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2898b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    uint32_t rs_field = GetRt(instr2) << kRsShift;
2899b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    uint32_t rd_field = ra.code() << kRdShift;  // Return-address (ra) reg.
2900b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    *(p+6) = SPECIAL | rs_field | rd_field | JALR;
2901b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    patched = true;
2902b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } else if (IsJ(instr3)) {
2903b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(GetOpcodeField(instr1) == LUI);
2904b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(GetOpcodeField(instr2) == ORI);
2905b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2906b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    uint32_t rs_field = GetRt(instr2) << kRsShift;
2907b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    *(p+6) = SPECIAL | rs_field | JR;
2908b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    patched = true;
2909b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
2910b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2911b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (patched) {
2912b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      CpuFeatures::FlushICache(pc+6, sizeof(int32_t));
2913b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
2914b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2915b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2916b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2917b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochHandle<ConstantPoolArray> Assembler::NewConstantPool(Isolate* isolate) {
2918b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // No out-of-line constant pool support.
2919b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(!FLAG_enable_ool_constant_pool);
2920b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return isolate->factory()->empty_constant_pool_array();
2921b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2922b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2923b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2924b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::PopulateConstantPool(ConstantPoolArray* constant_pool) {
2925b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // No out-of-line constant pool support.
2926b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(!FLAG_enable_ool_constant_pool);
2927b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return;
2928b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2929b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2930b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2931b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} }  // namespace v8::internal
2932b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2933b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#endif  // V8_TARGET_ARCH_MIPS64
2934