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
35014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/mips64/assembler-mips64.h"
36b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
37b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#if V8_TARGET_ARCH_MIPS64
38b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
39b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/base/cpu.h"
40b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/mips64/assembler-mips64-inl.h"
41b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
42b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochnamespace v8 {
43b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochnamespace internal {
44b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
45b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
46b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Get the CPU features enabled by the build. For cross compilation the
47b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// preprocessor symbols CAN_USE_FPU_INSTRUCTIONS
48b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// can be defined to enable FPU instructions when building the
49b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// snapshot.
50b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochstatic unsigned CpuFeaturesImpliedByCompiler() {
51b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  unsigned answer = 0;
52b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#ifdef CAN_USE_FPU_INSTRUCTIONS
53b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  answer |= 1u << FPU;
54b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#endif  // def CAN_USE_FPU_INSTRUCTIONS
55b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
56b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // If the compiler is allowed to use FPU then we can use FPU too in our code
57b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // generation even when generating snapshots.  This won't work for cross
58b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // compilation.
59b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#if defined(__mips__) && defined(__mips_hard_float) && __mips_hard_float != 0
60b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  answer |= 1u << FPU;
61b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#endif
62b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
63b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return answer;
64b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
65b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
66b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
67b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid CpuFeatures::ProbeImpl(bool cross_compile) {
68b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  supported_ |= CpuFeaturesImpliedByCompiler();
69b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
70b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Only use statically determined features for cross compile (snapshot).
71b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (cross_compile) return;
72b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
73b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // If the compiler is allowed to use fpu then we can use fpu too in our
74b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // code generation.
75b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#ifndef __mips__
76b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // For the simulator build, use FPU.
77b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  supported_ |= 1u << FPU;
78b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#else
79b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Probe for additional features at runtime.
80b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  base::CPU cpu;
81b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (cpu.has_fpu()) supported_ |= 1u << FPU;
82b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#endif
83b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
84b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
85b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
86b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid CpuFeatures::PrintTarget() { }
87b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid CpuFeatures::PrintFeatures() { }
88b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
89b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
90b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochint ToNumber(Register reg) {
91b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(reg.is_valid());
92b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  const int kNumbers[] = {
93b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    0,    // zero_reg
94b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    1,    // at
95b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    2,    // v0
96b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    3,    // v1
97b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    4,    // a0
98b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    5,    // a1
99b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    6,    // a2
100b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    7,    // a3
101b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    8,    // a4
102b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    9,    // a5
103b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    10,   // a6
104b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    11,   // a7
105b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    12,   // t0
106b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    13,   // t1
107b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    14,   // t2
108b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    15,   // t3
109b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    16,   // s0
110b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    17,   // s1
111b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    18,   // s2
112b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    19,   // s3
113b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    20,   // s4
114b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    21,   // s5
115b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    22,   // s6
116b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    23,   // s7
117b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    24,   // t8
118b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    25,   // t9
119b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    26,   // k0
120b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    27,   // k1
121b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    28,   // gp
122b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    29,   // sp
123b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    30,   // fp
124b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    31,   // ra
125b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  };
126b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return kNumbers[reg.code()];
127b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
128b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
129b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
130b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochRegister ToRegister(int num) {
131b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(num >= 0 && num < kNumRegisters);
132b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  const Register kRegisters[] = {
133b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    zero_reg,
134b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    at,
135b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    v0, v1,
136b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    a0, a1, a2, a3, a4, a5, a6, a7,
137b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    t0, t1, t2, t3,
138b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    s0, s1, s2, s3, s4, s5, s6, s7,
139b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    t8, t9,
140b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    k0, k1,
141b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    gp,
142b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    sp,
143b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    fp,
144b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    ra
145b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  };
146b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return kRegisters[num];
147b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
148b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
149b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
150b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// -----------------------------------------------------------------------------
151b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Implementation of RelocInfo.
152b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
153b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochconst int RelocInfo::kApplyMask = RelocInfo::kCodeTargetMask |
154014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                  1 << RelocInfo::INTERNAL_REFERENCE |
155014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                  1 << RelocInfo::INTERNAL_REFERENCE_ENCODED;
156b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
157b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
158b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochbool RelocInfo::IsCodedSpecially() {
159b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // The deserializer needs to know whether a pointer is specially coded.  Being
160b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // specially coded on MIPS means that it is a lui/ori instruction, and that is
161b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // always the case inside code objects.
162b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return true;
163b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
164b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
165b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
166b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochbool RelocInfo::IsInConstantPool() {
167b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return false;
168b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
169b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
170bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben MurdochAddress RelocInfo::wasm_memory_reference() {
171bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  DCHECK(IsWasmMemoryReference(rmode_));
172bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  return Assembler::target_address_at(pc_, host_);
173bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch}
174bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch
17513e2dadd00298019ed862f2b2fc5068bba730bcfBen MurdochAddress RelocInfo::wasm_global_reference() {
17613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  DCHECK(IsWasmGlobalReference(rmode_));
17713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  return Assembler::target_address_at(pc_, host_);
17813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch}
17913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch
180bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdochuint32_t RelocInfo::wasm_memory_size_reference() {
181bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  DCHECK(IsWasmMemorySizeReference(rmode_));
182bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  return static_cast<uint32_t>(
183bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      reinterpret_cast<intptr_t>((Assembler::target_address_at(pc_, host_))));
184bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch}
185bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch
18662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdochuint32_t RelocInfo::wasm_function_table_size_reference() {
18762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  DCHECK(IsWasmFunctionTableSizeReference(rmode_));
18862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  return static_cast<uint32_t>(
18962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      reinterpret_cast<intptr_t>((Assembler::target_address_at(pc_, host_))));
19062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch}
19162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
19213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdochvoid RelocInfo::unchecked_update_wasm_memory_reference(
19313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    Address address, ICacheFlushMode flush_mode) {
19413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  Assembler::set_target_address_at(isolate_, pc_, host_, address, flush_mode);
19513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch}
19613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch
19762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdochvoid RelocInfo::unchecked_update_wasm_size(uint32_t size,
19862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                                           ICacheFlushMode flush_mode) {
19913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  Assembler::set_target_address_at(isolate_, pc_, host_,
20013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch                                   reinterpret_cast<Address>(size), flush_mode);
201bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch}
202b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
203b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// -----------------------------------------------------------------------------
204b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Implementation of Operand and MemOperand.
205b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// See assembler-mips-inl.h for inlined constructors.
206b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
207b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochOperand::Operand(Handle<Object> handle) {
208b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  AllowDeferredHandleDereference using_raw_address;
209b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  rm_ = no_reg;
210b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Verify all Objects referred by code are NOT in new space.
211b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Object* obj = *handle;
212b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (obj->IsHeapObject()) {
213b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    imm64_ = reinterpret_cast<intptr_t>(handle.location());
214b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    rmode_ = RelocInfo::EMBEDDED_OBJECT;
215b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } else {
216b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // No relocation needed.
217b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    imm64_ = reinterpret_cast<intptr_t>(obj);
218b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    rmode_ = RelocInfo::NONE64;
219b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
220b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
221b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
222b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
223014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochMemOperand::MemOperand(Register rm, int32_t offset) : Operand(rm) {
224b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  offset_ = offset;
225b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
226b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
227b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
228014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochMemOperand::MemOperand(Register rm, int32_t unit, int32_t multiplier,
229014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                       OffsetAddend offset_addend)
230014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    : Operand(rm) {
231b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  offset_ = unit * multiplier + offset_addend;
232b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
233b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
234b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
235b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// -----------------------------------------------------------------------------
236b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Specific instructions, constants, and masks.
237b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
238b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochstatic const int kNegOffset = 0x00008000;
239b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// daddiu(sp, sp, 8) aka Pop() operation or part of Pop(r)
240b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// operations as post-increment of sp.
241014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochconst Instr kPopInstruction = DADDIU | (Register::kCode_sp << kRsShift) |
242014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                              (Register::kCode_sp << kRtShift) |
243014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                              (kPointerSize & kImm16Mask);  // NOLINT
244b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// daddiu(sp, sp, -8) part of Push(r) operation as pre-decrement of sp.
245014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochconst Instr kPushInstruction = DADDIU | (Register::kCode_sp << kRsShift) |
246014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                               (Register::kCode_sp << kRtShift) |
247014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                               (-kPointerSize & kImm16Mask);  // NOLINT
248b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// sd(r, MemOperand(sp, 0))
249014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochconst Instr kPushRegPattern =
250014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    SD | (Register::kCode_sp << kRsShift) | (0 & kImm16Mask);  // NOLINT
251b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch//  ld(r, MemOperand(sp, 0))
252014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochconst Instr kPopRegPattern =
253014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    LD | (Register::kCode_sp << kRsShift) | (0 & kImm16Mask);  // NOLINT
254b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
255014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochconst Instr kLwRegFpOffsetPattern =
256014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    LW | (Register::kCode_fp << kRsShift) | (0 & kImm16Mask);  // NOLINT
257b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
258014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochconst Instr kSwRegFpOffsetPattern =
259014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    SW | (Register::kCode_fp << kRsShift) | (0 & kImm16Mask);  // NOLINT
260b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
261014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochconst Instr kLwRegFpNegOffsetPattern = LW | (Register::kCode_fp << kRsShift) |
262014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                       (kNegOffset & kImm16Mask);  // NOLINT
263b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
264014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochconst Instr kSwRegFpNegOffsetPattern = SW | (Register::kCode_fp << kRsShift) |
265014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                       (kNegOffset & kImm16Mask);  // NOLINT
266b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// A mask for the Rt register for push, pop, lw, sw instructions.
267b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochconst Instr kRtMask = kRtFieldMask;
268b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochconst Instr kLwSwInstrTypeMask = 0xffe00000;
269b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochconst Instr kLwSwInstrArgumentMask  = ~kLwSwInstrTypeMask;
270b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochconst Instr kLwSwOffsetMask = kImm16Mask;
271b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
272b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochAssembler::Assembler(Isolate* isolate, void* buffer, int buffer_size)
273b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    : AssemblerBase(isolate, buffer, buffer_size),
274f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      recorded_ast_id_(TypeFeedbackId::None()) {
275b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  reloc_info_writer.Reposition(buffer_ + buffer_size_, pc_);
276b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
277b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  last_trampoline_pool_end_ = 0;
278b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  no_trampoline_pool_before_ = 0;
279b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  trampoline_pool_blocked_nesting_ = 0;
280b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // We leave space (16 * kTrampolineSlotsSize)
281b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // for BlockTrampolinePoolScope buffer.
282b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  next_buffer_check_ = FLAG_force_long_branches
283b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      ? kMaxInt : kMaxBranchOffset - kTrampolineSlotsSize * 16;
284b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  internal_trampoline_exception_ = false;
285b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  last_bound_pos_ = 0;
286b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
287b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  trampoline_emitted_ = FLAG_force_long_branches;
288b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  unbound_labels_count_ = 0;
289b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  block_buffer_growth_ = false;
290b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
291b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  ClearRecordedAstId();
292b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
293b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
294b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
295b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::GetCode(CodeDesc* desc) {
296014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  EmitForbiddenSlotInstruction();
297b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(pc_ <= reloc_info_writer.pos());  // No overlap.
298b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Set up code descriptor.
299b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  desc->buffer = buffer_;
300b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  desc->buffer_size = buffer_size_;
301b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  desc->instr_size = pc_offset();
302014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  desc->reloc_size =
303014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      static_cast<int>((buffer_ + buffer_size_) - reloc_info_writer.pos());
304b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  desc->origin = this;
305014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  desc->constant_pool_size = 0;
30613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  desc->unwinding_info_size = 0;
30713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  desc->unwinding_info = nullptr;
308b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
309b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
310b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
311b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::Align(int m) {
312b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(m >= 4 && base::bits::IsPowerOfTwo32(m));
313014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  EmitForbiddenSlotInstruction();
314b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  while ((pc_offset() & (m - 1)) != 0) {
315b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    nop();
316b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
317b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
318b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
319b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
320b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::CodeTargetAlign() {
321b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // No advantage to aligning branch/call targets to more than
322b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // single instruction, that I am aware of.
323b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Align(4);
324b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
325b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
326b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
327b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochRegister Assembler::GetRtReg(Instr instr) {
328b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Register rt;
329014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  rt.reg_code = (instr & kRtFieldMask) >> kRtShift;
330b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return rt;
331b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
332b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
333b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
334b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochRegister Assembler::GetRsReg(Instr instr) {
335b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Register rs;
336014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  rs.reg_code = (instr & kRsFieldMask) >> kRsShift;
337b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return rs;
338b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
339b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
340b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
341b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochRegister Assembler::GetRdReg(Instr instr) {
342b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Register rd;
343014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  rd.reg_code = (instr & kRdFieldMask) >> kRdShift;
344b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return rd;
345b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
346b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
347b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
348b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochuint32_t Assembler::GetRt(Instr instr) {
349b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return (instr & kRtFieldMask) >> kRtShift;
350b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
351b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
352b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
353b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochuint32_t Assembler::GetRtField(Instr instr) {
354b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return instr & kRtFieldMask;
355b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
356b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
357b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
358b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochuint32_t Assembler::GetRs(Instr instr) {
359b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return (instr & kRsFieldMask) >> kRsShift;
360b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
361b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
362b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
363b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochuint32_t Assembler::GetRsField(Instr instr) {
364b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return instr & kRsFieldMask;
365b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
366b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
367b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
368b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochuint32_t Assembler::GetRd(Instr instr) {
369b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return  (instr & kRdFieldMask) >> kRdShift;
370b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
371b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
372b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
373b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochuint32_t Assembler::GetRdField(Instr instr) {
374b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return  instr & kRdFieldMask;
375b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
376b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
377b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
378b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochuint32_t Assembler::GetSa(Instr instr) {
379b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return (instr & kSaFieldMask) >> kSaShift;
380b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
381b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
382b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
383b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochuint32_t Assembler::GetSaField(Instr instr) {
384b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return instr & kSaFieldMask;
385b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
386b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
387b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
388b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochuint32_t Assembler::GetOpcodeField(Instr instr) {
389b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return instr & kOpcodeMask;
390b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
391b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
392b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
393b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochuint32_t Assembler::GetFunction(Instr instr) {
394b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return (instr & kFunctionFieldMask) >> kFunctionShift;
395b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
396b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
397b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
398b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochuint32_t Assembler::GetFunctionField(Instr instr) {
399b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return instr & kFunctionFieldMask;
400b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
401b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
402b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
403b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochuint32_t Assembler::GetImmediate16(Instr instr) {
404b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return instr & kImm16Mask;
405b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
406b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
407b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
408b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochuint32_t Assembler::GetLabelConst(Instr instr) {
409b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return instr & ~kImm16Mask;
410b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
411b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
412b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
413b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochbool Assembler::IsPop(Instr instr) {
414b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return (instr & ~kRtMask) == kPopRegPattern;
415b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
416b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
417b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
418b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochbool Assembler::IsPush(Instr instr) {
419b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return (instr & ~kRtMask) == kPushRegPattern;
420b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
421b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
422b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
423b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochbool Assembler::IsSwRegFpOffset(Instr instr) {
424b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return ((instr & kLwSwInstrTypeMask) == kSwRegFpOffsetPattern);
425b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
426b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
427b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
428b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochbool Assembler::IsLwRegFpOffset(Instr instr) {
429b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return ((instr & kLwSwInstrTypeMask) == kLwRegFpOffsetPattern);
430b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
431b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
432b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
433b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochbool Assembler::IsSwRegFpNegOffset(Instr instr) {
434b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return ((instr & (kLwSwInstrTypeMask | kNegOffset)) ==
435b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          kSwRegFpNegOffsetPattern);
436b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
437b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
438b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
439b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochbool Assembler::IsLwRegFpNegOffset(Instr instr) {
440b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return ((instr & (kLwSwInstrTypeMask | kNegOffset)) ==
441b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          kLwRegFpNegOffsetPattern);
442b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
443b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
444b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
445b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Labels refer to positions in the (to be) generated code.
446b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// There are bound, linked, and unused labels.
447b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch//
448b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Bound labels refer to known positions in the already
449b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// generated code. pos() is the position the label refers to.
450b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch//
451b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Linked labels refer to unknown positions in the code
452b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// to be generated; pos() is the position of the last
453b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// instruction using the label.
454b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
455b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// The link chain is terminated by a value in the instruction of -1,
456b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// which is an otherwise illegal value (branch -1 is inf loop).
457b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// The instruction 16-bit offset field addresses 32-bit words, but in
458b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// code is conv to an 18-bit value addressing bytes, hence the -4 value.
459b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
460b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochconst int kEndOfChain = -4;
461b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Determines the end of the Jump chain (a subset of the label link chain).
462b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochconst int kEndOfJumpChain = 0;
463b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
464b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
465b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochbool Assembler::IsBranch(Instr instr) {
466b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  uint32_t opcode   = GetOpcodeField(instr);
467b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  uint32_t rt_field = GetRtField(instr);
468b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  uint32_t rs_field = GetRsField(instr);
469b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Checks if the instruction is a branch.
470014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  bool isBranch =
471014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      opcode == BEQ || opcode == BNE || opcode == BLEZ || opcode == BGTZ ||
472014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      opcode == BEQL || opcode == BNEL || opcode == BLEZL || opcode == BGTZL ||
473b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      (opcode == REGIMM && (rt_field == BLTZ || rt_field == BGEZ ||
474b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                            rt_field == BLTZAL || rt_field == BGEZAL)) ||
475b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      (opcode == COP1 && rs_field == BC1) ||  // Coprocessor branch.
476b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      (opcode == COP1 && rs_field == BC1EQZ) ||
477b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      (opcode == COP1 && rs_field == BC1NEZ);
478014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (!isBranch && kArchVariant == kMips64r6) {
479014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // All the 3 variants of POP10 (BOVC, BEQC, BEQZALC) and
480014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // POP30 (BNVC, BNEC, BNEZALC) are branch ops.
481014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    isBranch |= opcode == POP10 || opcode == POP30 || opcode == BC ||
482014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                opcode == BALC ||
483014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                (opcode == POP66 && rs_field != 0) ||  // BEQZC
484014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                (opcode == POP76 && rs_field != 0);    // BNEZC
485014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
486014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return isBranch;
487014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
488014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
489014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
490014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochbool Assembler::IsBc(Instr instr) {
491014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  uint32_t opcode = GetOpcodeField(instr);
492014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Checks if the instruction is a BC or BALC.
493014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return opcode == BC || opcode == BALC;
494014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
495014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
496014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
497014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochbool Assembler::IsBzc(Instr instr) {
498014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  uint32_t opcode = GetOpcodeField(instr);
499014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Checks if the instruction is BEQZC or BNEZC.
500014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return (opcode == POP66 && GetRsField(instr) != 0) ||
501014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch         (opcode == POP76 && GetRsField(instr) != 0);
502b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
503b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
504b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
505b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochbool Assembler::IsEmittedConstant(Instr instr) {
506b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  uint32_t label_constant = GetLabelConst(instr);
507b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return label_constant == 0;  // Emitted label const in reg-exp engine.
508b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
509b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
510b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
511b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochbool Assembler::IsBeq(Instr instr) {
512b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return GetOpcodeField(instr) == BEQ;
513b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
514b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
515b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
516b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochbool Assembler::IsBne(Instr instr) {
517b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return GetOpcodeField(instr) == BNE;
518b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
519b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
520b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
521014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochbool Assembler::IsBeqzc(Instr instr) {
522014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  uint32_t opcode = GetOpcodeField(instr);
523014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return opcode == POP66 && GetRsField(instr) != 0;
524014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
525014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
526014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
527014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochbool Assembler::IsBnezc(Instr instr) {
528014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  uint32_t opcode = GetOpcodeField(instr);
529014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return opcode == POP76 && GetRsField(instr) != 0;
530014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
531014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
532014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
533014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochbool Assembler::IsBeqc(Instr instr) {
534014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  uint32_t opcode = GetOpcodeField(instr);
535014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  uint32_t rs = GetRsField(instr);
536014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  uint32_t rt = GetRtField(instr);
537014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return opcode == POP10 && rs != 0 && rs < rt;  // && rt != 0
538014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
539014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
540014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
541014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochbool Assembler::IsBnec(Instr instr) {
542014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  uint32_t opcode = GetOpcodeField(instr);
543014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  uint32_t rs = GetRsField(instr);
544014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  uint32_t rt = GetRtField(instr);
545014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return opcode == POP30 && rs != 0 && rs < rt;  // && rt != 0
546014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
547014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
548014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
549b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochbool Assembler::IsJump(Instr instr) {
550b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  uint32_t opcode   = GetOpcodeField(instr);
551b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  uint32_t rt_field = GetRtField(instr);
552b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  uint32_t rd_field = GetRdField(instr);
553b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  uint32_t function_field = GetFunctionField(instr);
554b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Checks if the instruction is a jump.
555b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return opcode == J || opcode == JAL ||
556b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      (opcode == SPECIAL && rt_field == 0 &&
557b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      ((function_field == JALR) || (rd_field == 0 && (function_field == JR))));
558b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
559b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
560b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
561b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochbool Assembler::IsJ(Instr instr) {
562b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  uint32_t opcode = GetOpcodeField(instr);
563b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Checks if the instruction is a jump.
564b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return opcode == J;
565b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
566b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
567b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
568b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochbool Assembler::IsJal(Instr instr) {
569b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return GetOpcodeField(instr) == JAL;
570b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
571b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
572b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
573b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochbool Assembler::IsJr(Instr instr) {
574b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return GetOpcodeField(instr) == SPECIAL && GetFunctionField(instr) == JR;
575b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
576b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
577b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
578b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochbool Assembler::IsJalr(Instr instr) {
579b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return GetOpcodeField(instr) == SPECIAL && GetFunctionField(instr) == JALR;
580b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
581b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
582b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
583b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochbool Assembler::IsLui(Instr instr) {
584b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  uint32_t opcode = GetOpcodeField(instr);
585b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Checks if the instruction is a load upper immediate.
586b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return opcode == LUI;
587b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
588b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
589b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
590b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochbool Assembler::IsOri(Instr instr) {
591b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  uint32_t opcode = GetOpcodeField(instr);
592b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Checks if the instruction is a load upper immediate.
593b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return opcode == ORI;
594b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
595b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
596b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
597b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochbool Assembler::IsNop(Instr instr, unsigned int type) {
598b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // See Assembler::nop(type).
599b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(type < 32);
600b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  uint32_t opcode = GetOpcodeField(instr);
601b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  uint32_t function = GetFunctionField(instr);
602b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  uint32_t rt = GetRt(instr);
603b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  uint32_t rd = GetRd(instr);
604b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  uint32_t sa = GetSa(instr);
605b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
606b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Traditional mips nop == sll(zero_reg, zero_reg, 0)
607b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // When marking non-zero type, use sll(zero_reg, at, type)
608b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // to avoid use of mips ssnop and ehb special encodings
609b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // of the sll instruction.
610b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
611b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Register nop_rt_reg = (type == 0) ? zero_reg : at;
612b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bool ret = (opcode == SPECIAL && function == SLL &&
613b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch              rd == static_cast<uint32_t>(ToNumber(zero_reg)) &&
614b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch              rt == static_cast<uint32_t>(ToNumber(nop_rt_reg)) &&
615b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch              sa == type);
616b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
617b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return ret;
618b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
619b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
620b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
621b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochint32_t Assembler::GetBranchOffset(Instr instr) {
622b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(IsBranch(instr));
623b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return (static_cast<int16_t>(instr & kImm16Mask)) << 2;
624b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
625b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
626b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
627b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochbool Assembler::IsLw(Instr instr) {
628014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return (static_cast<uint32_t>(instr & kOpcodeMask) == LW);
629b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
630b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
631b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
632b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochint16_t Assembler::GetLwOffset(Instr instr) {
633b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(IsLw(instr));
634b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return ((instr & kImm16Mask));
635b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
636b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
637b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
638b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochInstr Assembler::SetLwOffset(Instr instr, int16_t offset) {
639b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(IsLw(instr));
640b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
641b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // We actually create a new lw instruction based on the original one.
642b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Instr temp_instr = LW | (instr & kRsFieldMask) | (instr & kRtFieldMask)
643b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      | (offset & kImm16Mask);
644b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
645b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return temp_instr;
646b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
647b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
648b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
649b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochbool Assembler::IsSw(Instr instr) {
650014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return (static_cast<uint32_t>(instr & kOpcodeMask) == SW);
651b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
652b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
653b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
654b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochInstr Assembler::SetSwOffset(Instr instr, int16_t offset) {
655b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(IsSw(instr));
656b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return ((instr & ~kImm16Mask) | (offset & kImm16Mask));
657b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
658b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
659b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
660b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochbool Assembler::IsAddImmediate(Instr instr) {
661b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return ((instr & kOpcodeMask) == ADDIU || (instr & kOpcodeMask) == DADDIU);
662b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
663b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
664b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
665b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochInstr Assembler::SetAddImmediateOffset(Instr instr, int16_t offset) {
666b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(IsAddImmediate(instr));
667b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return ((instr & ~kImm16Mask) | (offset & kImm16Mask));
668b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
669b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
670b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
671b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochbool Assembler::IsAndImmediate(Instr instr) {
672b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return GetOpcodeField(instr) == ANDI;
673b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
674b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
675b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
676014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochstatic Assembler::OffsetSize OffsetSizeInBits(Instr instr) {
677014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (kArchVariant == kMips64r6) {
678014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (Assembler::IsBc(instr)) {
679014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return Assembler::OffsetSize::kOffset26;
680014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    } else if (Assembler::IsBzc(instr)) {
681014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return Assembler::OffsetSize::kOffset21;
682014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
683014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
684014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return Assembler::OffsetSize::kOffset16;
685014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
686014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
687014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
688014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochstatic inline int32_t AddBranchOffset(int pos, Instr instr) {
689014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  int bits = OffsetSizeInBits(instr);
690014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  const int32_t mask = (1 << bits) - 1;
691014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  bits = 32 - bits;
692014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
693014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Do NOT change this to <<2. We rely on arithmetic shifts here, assuming
694014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // the compiler uses arithmetic shifts for signed integers.
695014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  int32_t imm = ((instr & mask) << bits) >> (bits - 2);
696014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
697014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (imm == kEndOfChain) {
698014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // EndOfChain sentinel is returned directly, not relative to pc or pos.
699014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return kEndOfChain;
700014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  } else {
701014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return pos + Assembler::kBranchPCOffset + imm;
702014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
703014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
704014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
705014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
706014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochint Assembler::target_at(int pos, bool is_internal) {
707014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (is_internal) {
708014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    int64_t* p = reinterpret_cast<int64_t*>(buffer_ + pos);
709014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    int64_t address = *p;
710014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (address == kEndOfJumpChain) {
711014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return kEndOfChain;
712014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    } else {
713014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      int64_t instr_address = reinterpret_cast<int64_t>(p);
714014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      DCHECK(instr_address - address < INT_MAX);
715014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      int delta = static_cast<int>(instr_address - address);
716014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      DCHECK(pos > delta);
717014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return pos - delta;
718014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
719014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
720b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Instr instr = instr_at(pos);
721b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if ((instr & ~kImm16Mask) == 0) {
722b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Emitted label constant, not part of a branch.
723b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (instr == 0) {
724b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch       return kEndOfChain;
725b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch     } else {
726b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch       int32_t imm18 =((instr & static_cast<int32_t>(kImm16Mask)) << 16) >> 14;
727b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch       return (imm18 + pos);
728b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch     }
729b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
730b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Check we have a branch or jump instruction.
731014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(IsBranch(instr) || IsJ(instr) || IsJal(instr) || IsLui(instr));
732b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Do NOT change this to <<2. We rely on arithmetic shifts here, assuming
733b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // the compiler uses arithmetic shifts for signed integers.
734b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (IsBranch(instr)) {
735014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return AddBranchOffset(pos, instr);
736b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } else if (IsLui(instr)) {
737b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Instr instr_lui = instr_at(pos + 0 * Assembler::kInstrSize);
738b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Instr instr_ori = instr_at(pos + 1 * Assembler::kInstrSize);
739b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Instr instr_ori2 = instr_at(pos + 3 * Assembler::kInstrSize);
740b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(IsOri(instr_ori));
741b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(IsOri(instr_ori2));
742b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
743b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // TODO(plind) create named constants for shift values.
744b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    int64_t imm = static_cast<int64_t>(instr_lui & kImm16Mask) << 48;
745b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    imm |= static_cast<int64_t>(instr_ori & kImm16Mask) << 32;
746b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    imm |= static_cast<int64_t>(instr_ori2 & kImm16Mask) << 16;
747b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Sign extend address;
748b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    imm >>= 16;
749b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
750b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (imm == kEndOfJumpChain) {
751b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      // EndOfChain sentinel is returned directly, not relative to pc or pos.
752b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      return kEndOfChain;
753b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    } else {
754b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      uint64_t instr_address = reinterpret_cast<int64_t>(buffer_ + pos);
755014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      DCHECK(instr_address - imm < INT_MAX);
756014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      int delta = static_cast<int>(instr_address - imm);
757b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      DCHECK(pos > delta);
758b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      return pos - delta;
759b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
760b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } else {
761014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    DCHECK(IsJ(instr) || IsJal(instr));
762b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    int32_t imm28 = (instr & static_cast<int32_t>(kImm26Mask)) << 2;
763b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (imm28 == kEndOfJumpChain) {
764b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      // EndOfChain sentinel is returned directly, not relative to pc or pos.
765b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      return kEndOfChain;
766b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    } else {
767014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      // Sign extend 28-bit offset.
768014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      int32_t delta = static_cast<int32_t>((imm28 << 4) >> 4);
769014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return pos + delta;
770b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
771b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
772b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
773b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
774b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
775014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochstatic inline Instr SetBranchOffset(int32_t pos, int32_t target_pos,
776014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                    Instr instr) {
777014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  int32_t bits = OffsetSizeInBits(instr);
778014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  int32_t imm = target_pos - (pos + Assembler::kBranchPCOffset);
779014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK((imm & 3) == 0);
780014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  imm >>= 2;
781014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
782014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  const int32_t mask = (1 << bits) - 1;
783014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  instr &= ~mask;
784014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(is_intn(imm, bits));
785014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
786014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return instr | (imm & mask);
787014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
788014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
789014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
790014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid Assembler::target_at_put(int pos, int target_pos, bool is_internal) {
791014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (is_internal) {
792014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    uint64_t imm = reinterpret_cast<uint64_t>(buffer_) + target_pos;
793014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    *reinterpret_cast<uint64_t*>(buffer_ + pos) = imm;
794014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return;
795014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
796b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Instr instr = instr_at(pos);
797b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if ((instr & ~kImm16Mask) == 0) {
798b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(target_pos == kEndOfChain || target_pos >= 0);
799b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Emitted label constant, not part of a branch.
800b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Make label relative to Code* of generated Code object.
801b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    instr_at_put(pos, target_pos + (Code::kHeaderSize - kHeapObjectTag));
802b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return;
803b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
804b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
805b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (IsBranch(instr)) {
806014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    instr = SetBranchOffset(pos, target_pos, instr);
807014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    instr_at_put(pos, instr);
808b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } else if (IsLui(instr)) {
809b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Instr instr_lui = instr_at(pos + 0 * Assembler::kInstrSize);
810b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Instr instr_ori = instr_at(pos + 1 * Assembler::kInstrSize);
811b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Instr instr_ori2 = instr_at(pos + 3 * Assembler::kInstrSize);
812b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(IsOri(instr_ori));
813b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(IsOri(instr_ori2));
814b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
815b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    uint64_t imm = reinterpret_cast<uint64_t>(buffer_) + target_pos;
816b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK((imm & 3) == 0);
817b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
818b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    instr_lui &= ~kImm16Mask;
819b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    instr_ori &= ~kImm16Mask;
820b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    instr_ori2 &= ~kImm16Mask;
821b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
822b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    instr_at_put(pos + 0 * Assembler::kInstrSize,
823b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                 instr_lui | ((imm >> 32) & kImm16Mask));
824b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    instr_at_put(pos + 1 * Assembler::kInstrSize,
825b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                 instr_ori | ((imm >> 16) & kImm16Mask));
826b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    instr_at_put(pos + 3 * Assembler::kInstrSize,
827b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                 instr_ori2 | (imm & kImm16Mask));
828014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  } else if (IsJ(instr) || IsJal(instr)) {
829014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    int32_t imm28 = target_pos - pos;
830b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK((imm28 & 3) == 0);
831b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
832014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    uint32_t imm26 = static_cast<uint32_t>(imm28 >> 2);
833b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(is_uint26(imm26));
834014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // Place 26-bit signed offset with markings.
835014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // When code is committed it will be resolved to j/jal.
836014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    int32_t mark = IsJ(instr) ? kJRawMark : kJalRawMark;
837014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    instr_at_put(pos, mark | (imm26 & kImm26Mask));
838014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  } else {
839014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    int32_t imm28 = target_pos - pos;
840014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    DCHECK((imm28 & 3) == 0);
841b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
842014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    uint32_t imm26 = static_cast<uint32_t>(imm28 >> 2);
843014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    DCHECK(is_uint26(imm26));
844014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // Place raw 26-bit signed offset.
845014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // When code is committed it will be resolved to j/jal.
846014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    instr &= ~kImm26Mask;
847b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    instr_at_put(pos, instr | (imm26 & kImm26Mask));
848b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
849b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
850b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
851b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
852b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::print(Label* L) {
853b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (L->is_unused()) {
854b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    PrintF("unused label\n");
855b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } else if (L->is_bound()) {
856b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    PrintF("bound label to %d\n", L->pos());
857b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } else if (L->is_linked()) {
858b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Label l = *L;
859b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    PrintF("unbound label");
860b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    while (l.is_linked()) {
861b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      PrintF("@ %d ", l.pos());
862b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      Instr instr = instr_at(l.pos());
863b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      if ((instr & ~kImm16Mask) == 0) {
864b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        PrintF("value\n");
865b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      } else {
866b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        PrintF("%d\n", instr);
867b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
86862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      next(&l, is_internal_reference(&l));
869b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
870b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } else {
871b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    PrintF("label in inconsistent state (pos = %d)\n", L->pos_);
872b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
873b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
874b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
875b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
876b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::bind_to(Label* L, int pos) {
877b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(0 <= pos && pos <= pc_offset());  // Must have valid binding position.
878014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  int trampoline_pos = kInvalidSlotPos;
879014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  bool is_internal = false;
880b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (L->is_linked() && !trampoline_emitted_) {
881b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    unbound_labels_count_--;
88262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    if (!is_internal_reference(L)) {
88362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      next_buffer_check_ += kTrampolineSlotsSize;
88462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    }
885b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
886b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
887b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  while (L->is_linked()) {
888014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    int fixup_pos = L->pos();
889014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    int dist = pos - fixup_pos;
89062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    is_internal = is_internal_reference(L);
891014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    next(L, is_internal);  // Call next before overwriting link with target at
892014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                           // fixup_pos.
893b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Instr instr = instr_at(fixup_pos);
894014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (is_internal) {
895014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      target_at_put(fixup_pos, pos, is_internal);
896014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    } else {
897014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (IsBranch(instr)) {
898014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        int branch_offset = BranchOffset(instr);
899014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        if (dist > branch_offset) {
900014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          if (trampoline_pos == kInvalidSlotPos) {
901014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch            trampoline_pos = get_trampoline_entry(fixup_pos);
902014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch            CHECK(trampoline_pos != kInvalidSlotPos);
903014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          }
904014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          CHECK((trampoline_pos - fixup_pos) <= branch_offset);
905014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          target_at_put(fixup_pos, trampoline_pos, false);
906014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          fixup_pos = trampoline_pos;
907b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        }
908014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        target_at_put(fixup_pos, pos, false);
909014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      } else {
910014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        DCHECK(IsJ(instr) || IsJal(instr) || IsLui(instr) ||
911014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch               IsEmittedConstant(instr));
912014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        target_at_put(fixup_pos, pos, false);
913b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
914b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
915b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
916b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  L->bind_to(pos);
917b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
918b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Keep track of the last bound label so we don't eliminate any instructions
919b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // before a bound label.
920b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (pos > last_bound_pos_)
921b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    last_bound_pos_ = pos;
922b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
923b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
924b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
925b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::bind(Label* L) {
926b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(!L->is_bound());  // Label can only be bound once.
927b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bind_to(L, pc_offset());
928b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
929b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
930b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
931014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid Assembler::next(Label* L, bool is_internal) {
932b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(L->is_linked());
933014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  int link = target_at(L->pos(), is_internal);
934b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (link == kEndOfChain) {
935b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    L->Unuse();
936b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } else {
937b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(link >= 0);
938b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    L->link_to(link);
939b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
940b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
941b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
942b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
943b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochbool Assembler::is_near(Label* L) {
944014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(L->is_bound());
945014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return pc_offset() - L->pos() < kMaxBranchOffset - 4 * kInstrSize;
946014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
947014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
948014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
949014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochbool Assembler::is_near(Label* L, OffsetSize bits) {
950014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (L == nullptr || !L->is_bound()) return true;
951014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return ((pc_offset() - L->pos()) <
952014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          (1 << (bits + 2 - 1)) - 1 - 5 * kInstrSize);
953014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
954014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
955014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
956014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochbool Assembler::is_near_branch(Label* L) {
957014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(L->is_bound());
958014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return kArchVariant == kMips64r6 ? is_near_r6(L) : is_near_pre_r6(L);
959014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
960014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
961014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
962014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochint Assembler::BranchOffset(Instr instr) {
963014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // At pre-R6 and for other R6 branches the offset is 16 bits.
964014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  int bits = OffsetSize::kOffset16;
965014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
966014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (kArchVariant == kMips64r6) {
967014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    uint32_t opcode = GetOpcodeField(instr);
968014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    switch (opcode) {
969014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      // Checks BC or BALC.
970014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      case BC:
971014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      case BALC:
972014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        bits = OffsetSize::kOffset26;
973014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        break;
974014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
975014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      // Checks BEQZC or BNEZC.
976014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      case POP66:
977014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      case POP76:
978014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        if (GetRsField(instr) != 0) bits = OffsetSize::kOffset21;
979014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        break;
980014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      default:
981014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        break;
982014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
983b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
984014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
985014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return (1 << (bits + 2 - 1)) - 1;
986b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
987b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
988b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
989b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// We have to use a temporary register for things that can be relocated even
990b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// if they can be encoded in the MIPS's 16 bits of immediate-offset instruction
991b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// space.  There is no guarantee that the relocated location can be similarly
992b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// encoded.
993b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochbool Assembler::MustUseReg(RelocInfo::Mode rmode) {
994b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return !RelocInfo::IsNone(rmode);
995b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
996b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
997b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::GenInstrRegister(Opcode opcode,
998b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                 Register rs,
999b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                 Register rt,
1000b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                 Register rd,
1001b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                 uint16_t sa,
1002b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                 SecondaryField func) {
1003b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(rd.is_valid() && rs.is_valid() && rt.is_valid() && is_uint5(sa));
1004b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Instr instr = opcode | (rs.code() << kRsShift) | (rt.code() << kRtShift)
1005b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      | (rd.code() << kRdShift) | (sa << kSaShift) | func;
1006b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  emit(instr);
1007b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1008b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1009b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1010b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::GenInstrRegister(Opcode opcode,
1011b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                 Register rs,
1012b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                 Register rt,
1013b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                 uint16_t msb,
1014b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                 uint16_t lsb,
1015b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                 SecondaryField func) {
1016b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(rs.is_valid() && rt.is_valid() && is_uint5(msb) && is_uint5(lsb));
1017b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Instr instr = opcode | (rs.code() << kRsShift) | (rt.code() << kRtShift)
1018b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      | (msb << kRdShift) | (lsb << kSaShift) | func;
1019b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  emit(instr);
1020b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1021b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1022b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1023b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::GenInstrRegister(Opcode opcode,
1024b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                 SecondaryField fmt,
1025b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                 FPURegister ft,
1026b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                 FPURegister fs,
1027b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                 FPURegister fd,
1028b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                 SecondaryField func) {
1029b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(fd.is_valid() && fs.is_valid() && ft.is_valid());
1030b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Instr instr = opcode | fmt | (ft.code() << kFtShift) | (fs.code() << kFsShift)
1031b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      | (fd.code() << kFdShift) | func;
1032b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  emit(instr);
1033b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1034b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1035b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1036b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::GenInstrRegister(Opcode opcode,
1037b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                 FPURegister fr,
1038b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                 FPURegister ft,
1039b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                 FPURegister fs,
1040b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                 FPURegister fd,
1041b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                 SecondaryField func) {
1042b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(fd.is_valid() && fr.is_valid() && fs.is_valid() && ft.is_valid());
1043b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Instr instr = opcode | (fr.code() << kFrShift) | (ft.code() << kFtShift)
1044b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      | (fs.code() << kFsShift) | (fd.code() << kFdShift) | func;
1045b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  emit(instr);
1046b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1047b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1048b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1049b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::GenInstrRegister(Opcode opcode,
1050b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                 SecondaryField fmt,
1051b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                 Register rt,
1052b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                 FPURegister fs,
1053b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                 FPURegister fd,
1054b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                 SecondaryField func) {
1055b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(fd.is_valid() && fs.is_valid() && rt.is_valid());
1056b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Instr instr = opcode | fmt | (rt.code() << kRtShift)
1057b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      | (fs.code() << kFsShift) | (fd.code() << kFdShift) | func;
1058b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  emit(instr);
1059b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1060b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1061b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1062b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::GenInstrRegister(Opcode opcode,
1063b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                 SecondaryField fmt,
1064b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                 Register rt,
1065b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                 FPUControlRegister fs,
1066b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                 SecondaryField func) {
1067b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(fs.is_valid() && rt.is_valid());
1068b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Instr instr =
1069b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      opcode | fmt | (rt.code() << kRtShift) | (fs.code() << kFsShift) | func;
1070b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  emit(instr);
1071b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1072b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1073b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1074b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Instructions with immediate value.
1075b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Registers are in the order of the instruction encoding, from left to right.
1076014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid Assembler::GenInstrImmediate(Opcode opcode, Register rs, Register rt,
1077014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                  int32_t j,
1078014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                  CompactBranchType is_compact_branch) {
1079b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(rs.is_valid() && rt.is_valid() && (is_int16(j) || is_uint16(j)));
1080b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Instr instr = opcode | (rs.code() << kRsShift) | (rt.code() << kRtShift)
1081b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      | (j & kImm16Mask);
1082014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  emit(instr, is_compact_branch);
1083b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1084b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1085b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1086014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid Assembler::GenInstrImmediate(Opcode opcode, Register rs, SecondaryField SF,
1087014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                  int32_t j,
1088014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                  CompactBranchType is_compact_branch) {
1089b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(rs.is_valid() && (is_int16(j) || is_uint16(j)));
1090b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Instr instr = opcode | (rs.code() << kRsShift) | SF | (j & kImm16Mask);
1091014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  emit(instr, is_compact_branch);
1092b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1093b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1094b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1095014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid Assembler::GenInstrImmediate(Opcode opcode, Register rs, FPURegister ft,
1096014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                  int32_t j,
1097014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                  CompactBranchType is_compact_branch) {
1098b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(rs.is_valid() && ft.is_valid() && (is_int16(j) || is_uint16(j)));
1099b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Instr instr = opcode | (rs.code() << kRsShift) | (ft.code() << kFtShift)
1100b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      | (j & kImm16Mask);
1101014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  emit(instr, is_compact_branch);
1102014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
1103014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1104014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1105014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid Assembler::GenInstrImmediate(Opcode opcode, Register rs, int32_t offset21,
1106014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                  CompactBranchType is_compact_branch) {
1107014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(rs.is_valid() && (is_int21(offset21)));
1108014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Instr instr = opcode | (rs.code() << kRsShift) | (offset21 & kImm21Mask);
1109014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  emit(instr, is_compact_branch);
1110014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
1111014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1112014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1113014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid Assembler::GenInstrImmediate(Opcode opcode, Register rs,
1114014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                  uint32_t offset21) {
1115014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(rs.is_valid() && (is_uint21(offset21)));
1116014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Instr instr = opcode | (rs.code() << kRsShift) | (offset21 & kImm21Mask);
1117b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  emit(instr);
1118b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1119b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1120b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1121014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid Assembler::GenInstrImmediate(Opcode opcode, int32_t offset26,
1122014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                  CompactBranchType is_compact_branch) {
1123014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(is_int26(offset26));
1124014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Instr instr = opcode | (offset26 & kImm26Mask);
1125014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  emit(instr, is_compact_branch);
1126014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
1127014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1128014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1129b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::GenInstrJump(Opcode opcode,
1130b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                             uint32_t address) {
1131b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  BlockTrampolinePoolScope block_trampoline_pool(this);
1132b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(is_uint26(address));
1133b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Instr instr = opcode | address;
1134b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  emit(instr);
1135b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  BlockTrampolinePoolFor(1);  // For associated delay slot.
1136b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1137b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1138b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1139b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Returns the next free trampoline entry.
1140b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochint32_t Assembler::get_trampoline_entry(int32_t pos) {
1141b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int32_t trampoline_entry = kInvalidSlotPos;
1142b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (!internal_trampoline_exception_) {
1143b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (trampoline_.start() > pos) {
1144b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch     trampoline_entry = trampoline_.take_slot();
1145b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
1146b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1147b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (kInvalidSlotPos == trampoline_entry) {
1148b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      internal_trampoline_exception_ = true;
1149b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
1150b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1151b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return trampoline_entry;
1152b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1153b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1154b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1155b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochuint64_t Assembler::jump_address(Label* L) {
1156b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int64_t target_pos;
1157b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (L->is_bound()) {
1158b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    target_pos = L->pos();
1159b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } else {
1160b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (L->is_linked()) {
1161b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      target_pos = L->pos();  // L's link.
1162b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      L->link_to(pc_offset());
1163b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    } else {
1164b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      L->link_to(pc_offset());
1165b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      return kEndOfJumpChain;
1166b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
1167b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1168b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  uint64_t imm = reinterpret_cast<uint64_t>(buffer_) + target_pos;
1169b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK((imm & 3) == 0);
1170b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1171b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return imm;
1172b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1173b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1174b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1175014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochuint64_t Assembler::jump_offset(Label* L) {
1176014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  int64_t target_pos;
1177014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  int32_t pad = IsPrevInstrCompactBranch() ? kInstrSize : 0;
1178b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1179b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (L->is_bound()) {
1180b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    target_pos = L->pos();
1181b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } else {
1182b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (L->is_linked()) {
1183014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      target_pos = L->pos();  // L's link.
1184014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      L->link_to(pc_offset() + pad);
1185b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    } else {
1186014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      L->link_to(pc_offset() + pad);
1187014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return kEndOfJumpChain;
1188b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
1189b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1190014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  int64_t imm = target_pos - (pc_offset() + pad);
1191014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK((imm & 3) == 0);
1192b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1193014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return static_cast<uint64_t>(imm);
1194b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1195b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1196b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1197014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochint32_t Assembler::branch_offset_helper(Label* L, OffsetSize bits) {
1198b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int32_t target_pos;
1199014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  int32_t pad = IsPrevInstrCompactBranch() ? kInstrSize : 0;
1200b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1201b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (L->is_bound()) {
1202b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    target_pos = L->pos();
1203b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } else {
1204b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (L->is_linked()) {
1205b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      target_pos = L->pos();
1206014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      L->link_to(pc_offset() + pad);
1207b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    } else {
1208014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      L->link_to(pc_offset() + pad);
1209b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      if (!trampoline_emitted_) {
1210b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        unbound_labels_count_++;
1211b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        next_buffer_check_ -= kTrampolineSlotsSize;
1212b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
1213b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      return kEndOfChain;
1214b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
1215b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1216b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1217014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  int32_t offset = target_pos - (pc_offset() + kBranchPCOffset + pad);
1218014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(is_intn(offset, bits + 2));
1219b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK((offset & 3) == 0);
1220b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1221b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return offset;
1222b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1223b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1224b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1225b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::label_at_put(Label* L, int at_offset) {
1226b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int target_pos;
1227b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (L->is_bound()) {
1228b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    target_pos = L->pos();
1229b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    instr_at_put(at_offset, target_pos + (Code::kHeaderSize - kHeapObjectTag));
1230b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } else {
1231b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (L->is_linked()) {
1232b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      target_pos = L->pos();  // L's link.
1233b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      int32_t imm18 = target_pos - at_offset;
1234b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      DCHECK((imm18 & 3) == 0);
1235b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      int32_t imm16 = imm18 >> 2;
1236b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      DCHECK(is_int16(imm16));
1237b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      instr_at_put(at_offset, (imm16 & kImm16Mask));
1238b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    } else {
1239b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      target_pos = kEndOfChain;
1240b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      instr_at_put(at_offset, 0);
1241b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      if (!trampoline_emitted_) {
1242b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        unbound_labels_count_++;
1243b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        next_buffer_check_ -= kTrampolineSlotsSize;
1244b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
1245b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
1246b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    L->link_to(at_offset);
1247b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1248b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1249b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1250b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1251b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch//------- Branch and jump instructions --------
1252b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1253b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::b(int16_t offset) {
1254b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  beq(zero_reg, zero_reg, offset);
1255b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1256b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1257b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1258b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::bal(int16_t offset) {
1259b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bgezal(zero_reg, offset);
1260b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1261b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1262b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1263014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid Assembler::bc(int32_t offset) {
1264014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(kArchVariant == kMips64r6);
1265014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  GenInstrImmediate(BC, offset, CompactBranchType::COMPACT_BRANCH);
1266014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
1267014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1268014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1269014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid Assembler::balc(int32_t offset) {
1270014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(kArchVariant == kMips64r6);
1271014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  GenInstrImmediate(BALC, offset, CompactBranchType::COMPACT_BRANCH);
1272014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
1273014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1274014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1275b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::beq(Register rs, Register rt, int16_t offset) {
1276b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  BlockTrampolinePoolScope block_trampoline_pool(this);
1277b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  GenInstrImmediate(BEQ, rs, rt, offset);
1278b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  BlockTrampolinePoolFor(1);  // For associated delay slot.
1279b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1280b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1281b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1282b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::bgez(Register rs, int16_t offset) {
1283b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  BlockTrampolinePoolScope block_trampoline_pool(this);
1284b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  GenInstrImmediate(REGIMM, rs, BGEZ, offset);
1285b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  BlockTrampolinePoolFor(1);  // For associated delay slot.
1286b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1287b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1288b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1289b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::bgezc(Register rt, int16_t offset) {
1290b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(kArchVariant == kMips64r6);
1291b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(!(rt.is(zero_reg)));
1292014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  GenInstrImmediate(BLEZL, rt, rt, offset, CompactBranchType::COMPACT_BRANCH);
1293b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1294b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1295b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1296b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::bgeuc(Register rs, Register rt, int16_t offset) {
1297b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(kArchVariant == kMips64r6);
1298b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(!(rs.is(zero_reg)));
1299b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(!(rt.is(zero_reg)));
1300b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(rs.code() != rt.code());
1301014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  GenInstrImmediate(BLEZ, rs, rt, offset, CompactBranchType::COMPACT_BRANCH);
1302b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1303b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1304b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1305b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::bgec(Register rs, Register rt, int16_t offset) {
1306b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(kArchVariant == kMips64r6);
1307b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(!(rs.is(zero_reg)));
1308b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(!(rt.is(zero_reg)));
1309b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(rs.code() != rt.code());
1310014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  GenInstrImmediate(BLEZL, rs, rt, offset, CompactBranchType::COMPACT_BRANCH);
1311b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1312b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1313b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1314b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::bgezal(Register rs, int16_t offset) {
1315b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(kArchVariant != kMips64r6 || rs.is(zero_reg));
1316b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  BlockTrampolinePoolScope block_trampoline_pool(this);
1317b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  GenInstrImmediate(REGIMM, rs, BGEZAL, offset);
1318b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  BlockTrampolinePoolFor(1);  // For associated delay slot.
1319b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1320b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1321b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1322b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::bgtz(Register rs, int16_t offset) {
1323b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  BlockTrampolinePoolScope block_trampoline_pool(this);
1324b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  GenInstrImmediate(BGTZ, rs, zero_reg, offset);
1325b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  BlockTrampolinePoolFor(1);  // For associated delay slot.
1326b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1327b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1328b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1329b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::bgtzc(Register rt, int16_t offset) {
1330b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(kArchVariant == kMips64r6);
1331b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(!(rt.is(zero_reg)));
1332014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  GenInstrImmediate(BGTZL, zero_reg, rt, offset,
1333014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                    CompactBranchType::COMPACT_BRANCH);
1334b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1335b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1336b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1337b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::blez(Register rs, int16_t offset) {
1338b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  BlockTrampolinePoolScope block_trampoline_pool(this);
1339b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  GenInstrImmediate(BLEZ, rs, zero_reg, offset);
1340b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  BlockTrampolinePoolFor(1);  // For associated delay slot.
1341b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1342b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1343b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1344b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::blezc(Register rt, int16_t offset) {
1345b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(kArchVariant == kMips64r6);
1346b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(!(rt.is(zero_reg)));
1347014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  GenInstrImmediate(BLEZL, zero_reg, rt, offset,
1348014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                    CompactBranchType::COMPACT_BRANCH);
1349b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1350b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1351b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1352b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::bltzc(Register rt, int16_t offset) {
1353b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(kArchVariant == kMips64r6);
1354014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(!rt.is(zero_reg));
1355014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  GenInstrImmediate(BGTZL, rt, rt, offset, CompactBranchType::COMPACT_BRANCH);
1356b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1357b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1358b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1359b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::bltuc(Register rs, Register rt, int16_t offset) {
1360b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(kArchVariant == kMips64r6);
1361b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(!(rs.is(zero_reg)));
1362b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(!(rt.is(zero_reg)));
1363b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(rs.code() != rt.code());
1364014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  GenInstrImmediate(BGTZ, rs, rt, offset, CompactBranchType::COMPACT_BRANCH);
1365b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1366b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1367b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1368b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::bltc(Register rs, Register rt, int16_t offset) {
1369b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(kArchVariant == kMips64r6);
1370014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(!rs.is(zero_reg));
1371014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(!rt.is(zero_reg));
1372b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(rs.code() != rt.code());
1373014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  GenInstrImmediate(BGTZL, rs, rt, offset, CompactBranchType::COMPACT_BRANCH);
1374b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1375b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1376b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1377b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::bltz(Register rs, int16_t offset) {
1378b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  BlockTrampolinePoolScope block_trampoline_pool(this);
1379b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  GenInstrImmediate(REGIMM, rs, BLTZ, offset);
1380b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  BlockTrampolinePoolFor(1);  // For associated delay slot.
1381b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1382b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1383b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1384b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::bltzal(Register rs, int16_t offset) {
1385b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(kArchVariant != kMips64r6 || rs.is(zero_reg));
1386b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  BlockTrampolinePoolScope block_trampoline_pool(this);
1387b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  GenInstrImmediate(REGIMM, rs, BLTZAL, offset);
1388b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  BlockTrampolinePoolFor(1);  // For associated delay slot.
1389b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1390b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1391b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1392b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::bne(Register rs, Register rt, int16_t offset) {
1393b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  BlockTrampolinePoolScope block_trampoline_pool(this);
1394b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  GenInstrImmediate(BNE, rs, rt, offset);
1395b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  BlockTrampolinePoolFor(1);  // For associated delay slot.
1396b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1397b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1398b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1399b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::bovc(Register rs, Register rt, int16_t offset) {
1400b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(kArchVariant == kMips64r6);
14013b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  if (rs.code() >= rt.code()) {
14023b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    GenInstrImmediate(ADDI, rs, rt, offset, CompactBranchType::COMPACT_BRANCH);
14033b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  } else {
14043b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    GenInstrImmediate(ADDI, rt, rs, offset, CompactBranchType::COMPACT_BRANCH);
14053b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  }
1406b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1407b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1408b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1409b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::bnvc(Register rs, Register rt, int16_t offset) {
1410b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(kArchVariant == kMips64r6);
14113b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  if (rs.code() >= rt.code()) {
14123b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    GenInstrImmediate(DADDI, rs, rt, offset, CompactBranchType::COMPACT_BRANCH);
14133b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  } else {
14143b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    GenInstrImmediate(DADDI, rt, rs, offset, CompactBranchType::COMPACT_BRANCH);
14153b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  }
1416b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1417b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1418b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1419b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::blezalc(Register rt, int16_t offset) {
1420b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(kArchVariant == kMips64r6);
1421b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(!(rt.is(zero_reg)));
1422014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  GenInstrImmediate(BLEZ, zero_reg, rt, offset,
1423014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                    CompactBranchType::COMPACT_BRANCH);
1424b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1425b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1426b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1427b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::bgezalc(Register rt, int16_t offset) {
1428b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(kArchVariant == kMips64r6);
1429b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(!(rt.is(zero_reg)));
1430014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  GenInstrImmediate(BLEZ, rt, rt, offset, CompactBranchType::COMPACT_BRANCH);
1431b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1432b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1433b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1434b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::bgezall(Register rs, int16_t offset) {
1435014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(kArchVariant != kMips64r6);
1436b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(!(rs.is(zero_reg)));
1437014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  BlockTrampolinePoolScope block_trampoline_pool(this);
1438b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  GenInstrImmediate(REGIMM, rs, BGEZALL, offset);
1439014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  BlockTrampolinePoolFor(1);  // For associated delay slot.
1440b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1441b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1442b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1443b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::bltzalc(Register rt, int16_t offset) {
1444b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(kArchVariant == kMips64r6);
1445b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(!(rt.is(zero_reg)));
1446014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  GenInstrImmediate(BGTZ, rt, rt, offset, CompactBranchType::COMPACT_BRANCH);
1447b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1448b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1449b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1450b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::bgtzalc(Register rt, int16_t offset) {
1451b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(kArchVariant == kMips64r6);
1452b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(!(rt.is(zero_reg)));
1453014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  GenInstrImmediate(BGTZ, zero_reg, rt, offset,
1454014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                    CompactBranchType::COMPACT_BRANCH);
1455b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1456b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1457b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1458b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::beqzalc(Register rt, int16_t offset) {
1459b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(kArchVariant == kMips64r6);
1460b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(!(rt.is(zero_reg)));
1461014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  GenInstrImmediate(ADDI, zero_reg, rt, offset,
1462014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                    CompactBranchType::COMPACT_BRANCH);
1463b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1464b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1465b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1466b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::bnezalc(Register rt, int16_t offset) {
1467b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(kArchVariant == kMips64r6);
1468b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(!(rt.is(zero_reg)));
1469014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  GenInstrImmediate(DADDI, zero_reg, rt, offset,
1470014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                    CompactBranchType::COMPACT_BRANCH);
1471b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1472b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1473b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1474b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::beqc(Register rs, Register rt, int16_t offset) {
1475b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(kArchVariant == kMips64r6);
1476014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(rs.code() != rt.code() && rs.code() != 0 && rt.code() != 0);
1477014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (rs.code() < rt.code()) {
1478014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    GenInstrImmediate(ADDI, rs, rt, offset, CompactBranchType::COMPACT_BRANCH);
1479014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  } else {
1480014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    GenInstrImmediate(ADDI, rt, rs, offset, CompactBranchType::COMPACT_BRANCH);
1481014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1482b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1483b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1484b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1485b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::beqzc(Register rs, int32_t offset) {
1486b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(kArchVariant == kMips64r6);
1487b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(!(rs.is(zero_reg)));
1488014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  GenInstrImmediate(POP66, rs, offset, CompactBranchType::COMPACT_BRANCH);
1489b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1490b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1491b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1492b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::bnec(Register rs, Register rt, int16_t offset) {
1493b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(kArchVariant == kMips64r6);
1494014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(rs.code() != rt.code() && rs.code() != 0 && rt.code() != 0);
1495014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (rs.code() < rt.code()) {
1496014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    GenInstrImmediate(DADDI, rs, rt, offset, CompactBranchType::COMPACT_BRANCH);
1497014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  } else {
1498014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    GenInstrImmediate(DADDI, rt, rs, offset, CompactBranchType::COMPACT_BRANCH);
1499014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1500b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1501b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1502b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1503b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::bnezc(Register rs, int32_t offset) {
1504b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(kArchVariant == kMips64r6);
1505b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(!(rs.is(zero_reg)));
1506014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  GenInstrImmediate(POP76, rs, offset, CompactBranchType::COMPACT_BRANCH);
1507b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1508b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1509b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1510b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::j(int64_t target) {
1511014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  BlockTrampolinePoolScope block_trampoline_pool(this);
1512014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  GenInstrJump(J, static_cast<uint32_t>(target >> 2) & kImm26Mask);
1513014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  BlockTrampolinePoolFor(1);  // For associated delay slot.
1514014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
1515014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1516014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1517014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid Assembler::j(Label* target) {
1518014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  uint64_t imm = jump_offset(target);
1519014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (target->is_bound()) {
1520014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    BlockTrampolinePoolScope block_trampoline_pool(this);
1521014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    GenInstrJump(static_cast<Opcode>(kJRawMark),
1522014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                 static_cast<uint32_t>(imm >> 2) & kImm26Mask);
1523014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    BlockTrampolinePoolFor(1);  // For associated delay slot.
1524014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  } else {
1525014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    j(imm);
1526014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1527014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
1528014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1529014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1530014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid Assembler::jal(Label* target) {
1531014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  uint64_t imm = jump_offset(target);
1532014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (target->is_bound()) {
1533014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    BlockTrampolinePoolScope block_trampoline_pool(this);
1534014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    GenInstrJump(static_cast<Opcode>(kJalRawMark),
1535014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                 static_cast<uint32_t>(imm >> 2) & kImm26Mask);
1536014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    BlockTrampolinePoolFor(1);  // For associated delay slot.
1537014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  } else {
1538014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    jal(imm);
1539014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1540b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1541b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1542b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1543b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::jr(Register rs) {
1544b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (kArchVariant != kMips64r6) {
1545b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    BlockTrampolinePoolScope block_trampoline_pool(this);
1546b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    GenInstrRegister(SPECIAL, rs, zero_reg, zero_reg, 0, JR);
1547b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    BlockTrampolinePoolFor(1);  // For associated delay slot.
1548b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } else {
1549b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    jalr(rs, zero_reg);
1550b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1551b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1552b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1553b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1554b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::jal(int64_t target) {
1555014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  BlockTrampolinePoolScope block_trampoline_pool(this);
1556014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  GenInstrJump(JAL, static_cast<uint32_t>(target >> 2) & kImm26Mask);
1557014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  BlockTrampolinePoolFor(1);  // For associated delay slot.
1558b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1559b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1560b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1561b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::jalr(Register rs, Register rd) {
1562014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(rs.code() != rd.code());
1563b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  BlockTrampolinePoolScope block_trampoline_pool(this);
1564b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  GenInstrRegister(SPECIAL, rs, zero_reg, rd, 0, JALR);
1565b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  BlockTrampolinePoolFor(1);  // For associated delay slot.
1566b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1567b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1568b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1569014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid Assembler::jic(Register rt, int16_t offset) {
1570014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(kArchVariant == kMips64r6);
1571014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  GenInstrImmediate(POP66, zero_reg, rt, offset);
1572b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1573b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1574b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1575014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid Assembler::jialc(Register rt, int16_t offset) {
1576014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(kArchVariant == kMips64r6);
1577014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  GenInstrImmediate(POP76, zero_reg, rt, offset);
1578b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1579b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1580b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1581b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// -------Data-processing-instructions---------
1582b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1583b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Arithmetic.
1584b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1585b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::addu(Register rd, Register rs, Register rt) {
1586b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  GenInstrRegister(SPECIAL, rs, rt, rd, 0, ADDU);
1587b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1588b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1589b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1590b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::addiu(Register rd, Register rs, int32_t j) {
1591b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  GenInstrImmediate(ADDIU, rs, rd, j);
1592b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1593b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1594b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1595b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::subu(Register rd, Register rs, Register rt) {
1596b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  GenInstrRegister(SPECIAL, rs, rt, rd, 0, SUBU);
1597b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1598b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1599b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1600b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::mul(Register rd, Register rs, Register rt) {
1601b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (kArchVariant == kMips64r6) {
1602b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      GenInstrRegister(SPECIAL, rs, rt, rd, MUL_OP, MUL_MUH);
1603b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } else {
1604b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      GenInstrRegister(SPECIAL2, rs, rt, rd, 0, MUL);
1605b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1606b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1607b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1608b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1609b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::muh(Register rd, Register rs, Register rt) {
1610b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(kArchVariant == kMips64r6);
1611b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  GenInstrRegister(SPECIAL, rs, rt, rd, MUH_OP, MUL_MUH);
1612b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1613b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1614b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1615b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::mulu(Register rd, Register rs, Register rt) {
1616b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(kArchVariant == kMips64r6);
1617b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  GenInstrRegister(SPECIAL, rs, rt, rd, MUL_OP, MUL_MUH_U);
1618b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1619b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1620b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1621b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::muhu(Register rd, Register rs, Register rt) {
1622b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(kArchVariant == kMips64r6);
1623b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  GenInstrRegister(SPECIAL, rs, rt, rd, MUH_OP, MUL_MUH_U);
1624b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1625b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1626b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1627b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::dmul(Register rd, Register rs, Register rt) {
1628b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(kArchVariant == kMips64r6);
1629b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  GenInstrRegister(SPECIAL, rs, rt, rd, MUL_OP, D_MUL_MUH);
1630b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1631b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1632b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1633b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::dmuh(Register rd, Register rs, Register rt) {
1634b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(kArchVariant == kMips64r6);
1635b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  GenInstrRegister(SPECIAL, rs, rt, rd, MUH_OP, D_MUL_MUH);
1636b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1637b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1638b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1639b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::dmulu(Register rd, Register rs, Register rt) {
1640b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(kArchVariant == kMips64r6);
1641b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  GenInstrRegister(SPECIAL, rs, rt, rd, MUL_OP, D_MUL_MUH_U);
1642b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1643b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1644b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1645b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::dmuhu(Register rd, Register rs, Register rt) {
1646b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(kArchVariant == kMips64r6);
1647b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  GenInstrRegister(SPECIAL, rs, rt, rd, MUH_OP, D_MUL_MUH_U);
1648b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1649b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1650b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1651b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::mult(Register rs, Register rt) {
1652b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(kArchVariant != kMips64r6);
1653b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  GenInstrRegister(SPECIAL, rs, rt, zero_reg, 0, MULT);
1654b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1655b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1656b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1657b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::multu(Register rs, Register rt) {
1658b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(kArchVariant != kMips64r6);
1659b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  GenInstrRegister(SPECIAL, rs, rt, zero_reg, 0, MULTU);
1660b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1661b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1662b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1663b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::daddiu(Register rd, Register rs, int32_t j) {
1664b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  GenInstrImmediate(DADDIU, rs, rd, j);
1665b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1666b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1667b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1668b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::div(Register rs, Register rt) {
1669b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  GenInstrRegister(SPECIAL, rs, rt, zero_reg, 0, DIV);
1670b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1671b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1672b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1673b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::div(Register rd, Register rs, Register rt) {
1674b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(kArchVariant == kMips64r6);
1675b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  GenInstrRegister(SPECIAL, rs, rt, rd, DIV_OP, DIV_MOD);
1676b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1677b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1678b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1679b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::mod(Register rd, Register rs, Register rt) {
1680b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(kArchVariant == kMips64r6);
1681b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  GenInstrRegister(SPECIAL, rs, rt, rd, MOD_OP, DIV_MOD);
1682b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1683b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1684b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1685b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::divu(Register rs, Register rt) {
1686b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  GenInstrRegister(SPECIAL, rs, rt, zero_reg, 0, DIVU);
1687b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1688b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1689b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1690b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::divu(Register rd, Register rs, Register rt) {
1691b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(kArchVariant == kMips64r6);
1692b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  GenInstrRegister(SPECIAL, rs, rt, rd, DIV_OP, DIV_MOD_U);
1693b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1694b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1695b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1696b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::modu(Register rd, Register rs, Register rt) {
1697b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(kArchVariant == kMips64r6);
1698b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  GenInstrRegister(SPECIAL, rs, rt, rd, MOD_OP, DIV_MOD_U);
1699b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1700b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1701b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1702b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::daddu(Register rd, Register rs, Register rt) {
1703b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  GenInstrRegister(SPECIAL, rs, rt, rd, 0, DADDU);
1704b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1705b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1706b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1707b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::dsubu(Register rd, Register rs, Register rt) {
1708b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  GenInstrRegister(SPECIAL, rs, rt, rd, 0, DSUBU);
1709b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1710b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1711b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1712b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::dmult(Register rs, Register rt) {
1713b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  GenInstrRegister(SPECIAL, rs, rt, zero_reg, 0, DMULT);
1714b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1715b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1716b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1717b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::dmultu(Register rs, Register rt) {
1718b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  GenInstrRegister(SPECIAL, rs, rt, zero_reg, 0, DMULTU);
1719b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1720b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1721b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1722b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::ddiv(Register rs, Register rt) {
1723b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  GenInstrRegister(SPECIAL, rs, rt, zero_reg, 0, DDIV);
1724b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1725b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1726b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1727b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::ddiv(Register rd, Register rs, Register rt) {
1728b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(kArchVariant == kMips64r6);
1729b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  GenInstrRegister(SPECIAL, rs, rt, rd, DIV_OP, D_DIV_MOD);
1730b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1731b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1732b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1733b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::dmod(Register rd, Register rs, Register rt) {
1734b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(kArchVariant == kMips64r6);
1735b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  GenInstrRegister(SPECIAL, rs, rt, rd, MOD_OP, D_DIV_MOD);
1736b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1737b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1738b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1739b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::ddivu(Register rs, Register rt) {
1740b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  GenInstrRegister(SPECIAL, rs, rt, zero_reg, 0, DDIVU);
1741b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1742b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1743b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1744b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::ddivu(Register rd, Register rs, Register rt) {
1745b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(kArchVariant == kMips64r6);
1746b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  GenInstrRegister(SPECIAL, rs, rt, rd, DIV_OP, D_DIV_MOD_U);
1747b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1748b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1749b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1750b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::dmodu(Register rd, Register rs, Register rt) {
1751b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(kArchVariant == kMips64r6);
1752b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  GenInstrRegister(SPECIAL, rs, rt, rd, MOD_OP, D_DIV_MOD_U);
1753b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1754b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1755b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1756b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Logical.
1757b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1758b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::and_(Register rd, Register rs, Register rt) {
1759b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  GenInstrRegister(SPECIAL, rs, rt, rd, 0, AND);
1760b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1761b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1762b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1763b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::andi(Register rt, Register rs, int32_t j) {
1764b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(is_uint16(j));
1765b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  GenInstrImmediate(ANDI, rs, rt, j);
1766b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1767b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1768b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1769b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::or_(Register rd, Register rs, Register rt) {
1770b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  GenInstrRegister(SPECIAL, rs, rt, rd, 0, OR);
1771b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1772b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1773b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1774b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::ori(Register rt, Register rs, int32_t j) {
1775b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(is_uint16(j));
1776b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  GenInstrImmediate(ORI, rs, rt, j);
1777b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1778b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1779b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1780b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::xor_(Register rd, Register rs, Register rt) {
1781b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  GenInstrRegister(SPECIAL, rs, rt, rd, 0, XOR);
1782b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1783b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1784b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1785b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::xori(Register rt, Register rs, int32_t j) {
1786b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(is_uint16(j));
1787b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  GenInstrImmediate(XORI, rs, rt, j);
1788b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1789b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1790b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1791b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::nor(Register rd, Register rs, Register rt) {
1792b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  GenInstrRegister(SPECIAL, rs, rt, rd, 0, NOR);
1793b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1794b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1795b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1796b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Shifts.
1797b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::sll(Register rd,
1798b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                    Register rt,
1799b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                    uint16_t sa,
1800b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                    bool coming_from_nop) {
1801b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Don't allow nop instructions in the form sll zero_reg, zero_reg to be
1802b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // generated using the sll instruction. They must be generated using
1803b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // nop(int/NopMarkerTypes) or MarkCode(int/NopMarkerTypes) pseudo
1804b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // instructions.
1805b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(coming_from_nop || !(rd.is(zero_reg) && rt.is(zero_reg)));
1806014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  GenInstrRegister(SPECIAL, zero_reg, rt, rd, sa & 0x1F, SLL);
1807b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1808b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1809b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1810b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::sllv(Register rd, Register rt, Register rs) {
1811b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  GenInstrRegister(SPECIAL, rs, rt, rd, 0, SLLV);
1812b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1813b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1814b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1815b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::srl(Register rd, Register rt, uint16_t sa) {
1816014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  GenInstrRegister(SPECIAL, zero_reg, rt, rd, sa & 0x1F, SRL);
1817b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1818b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1819b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1820b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::srlv(Register rd, Register rt, Register rs) {
1821b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  GenInstrRegister(SPECIAL, rs, rt, rd, 0, SRLV);
1822b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1823b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1824b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1825b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::sra(Register rd, Register rt, uint16_t sa) {
1826014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  GenInstrRegister(SPECIAL, zero_reg, rt, rd, sa & 0x1F, SRA);
1827b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1828b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1829b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1830b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::srav(Register rd, Register rt, Register rs) {
1831b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  GenInstrRegister(SPECIAL, rs, rt, rd, 0, SRAV);
1832b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1833b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1834b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1835b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::rotr(Register rd, Register rt, uint16_t sa) {
1836b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Should be called via MacroAssembler::Ror.
1837b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(rd.is_valid() && rt.is_valid() && is_uint5(sa));
1838014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(kArchVariant == kMips64r2 || kArchVariant == kMips64r6);
1839b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Instr instr = SPECIAL | (1 << kRsShift) | (rt.code() << kRtShift)
1840b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      | (rd.code() << kRdShift) | (sa << kSaShift) | SRL;
1841b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  emit(instr);
1842b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1843b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1844b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1845b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::rotrv(Register rd, Register rt, Register rs) {
1846b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Should be called via MacroAssembler::Ror.
1847014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(rd.is_valid() && rt.is_valid() && rs.is_valid());
1848014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(kArchVariant == kMips64r2 || kArchVariant == kMips64r6);
1849b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Instr instr = SPECIAL | (rs.code() << kRsShift) | (rt.code() << kRtShift)
1850b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch     | (rd.code() << kRdShift) | (1 << kSaShift) | SRLV;
1851b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  emit(instr);
1852b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1853b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1854b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1855b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::dsll(Register rd, Register rt, uint16_t sa) {
1856014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  GenInstrRegister(SPECIAL, zero_reg, rt, rd, sa & 0x1F, DSLL);
1857b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1858b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1859b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1860b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::dsllv(Register rd, Register rt, Register rs) {
1861b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  GenInstrRegister(SPECIAL, rs, rt, rd, 0, DSLLV);
1862b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1863b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1864b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1865b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::dsrl(Register rd, Register rt, uint16_t sa) {
1866014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  GenInstrRegister(SPECIAL, zero_reg, rt, rd, sa & 0x1F, DSRL);
1867b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1868b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1869b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1870b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::dsrlv(Register rd, Register rt, Register rs) {
1871b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  GenInstrRegister(SPECIAL, rs, rt, rd, 0, DSRLV);
1872b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1873b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1874b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1875b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::drotr(Register rd, Register rt, uint16_t sa) {
1876b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(rd.is_valid() && rt.is_valid() && is_uint5(sa));
1877b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Instr instr = SPECIAL | (1 << kRsShift) | (rt.code() << kRtShift)
1878b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      | (rd.code() << kRdShift) | (sa << kSaShift) | DSRL;
1879b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  emit(instr);
1880b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1881b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
18823b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdochvoid Assembler::drotr32(Register rd, Register rt, uint16_t sa) {
18833b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  DCHECK(rd.is_valid() && rt.is_valid() && is_uint5(sa));
18843b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  Instr instr = SPECIAL | (1 << kRsShift) | (rt.code() << kRtShift) |
18853b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch                (rd.code() << kRdShift) | (sa << kSaShift) | DSRL32;
18863b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  emit(instr);
18873b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch}
1888b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1889b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::drotrv(Register rd, Register rt, Register rs) {
1890b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(rd.is_valid() && rt.is_valid() && rs.is_valid() );
1891b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Instr instr = SPECIAL | (rs.code() << kRsShift) | (rt.code() << kRtShift)
1892b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      | (rd.code() << kRdShift) | (1 << kSaShift) | DSRLV;
1893b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  emit(instr);
1894b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1895b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1896b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1897b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::dsra(Register rd, Register rt, uint16_t sa) {
1898014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  GenInstrRegister(SPECIAL, zero_reg, rt, rd, sa & 0x1F, DSRA);
1899b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1900b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1901b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1902b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::dsrav(Register rd, Register rt, Register rs) {
1903b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  GenInstrRegister(SPECIAL, rs, rt, rd, 0, DSRAV);
1904b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1905b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1906b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1907b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::dsll32(Register rd, Register rt, uint16_t sa) {
1908014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  GenInstrRegister(SPECIAL, zero_reg, rt, rd, sa & 0x1F, DSLL32);
1909b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1910b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1911b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1912b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::dsrl32(Register rd, Register rt, uint16_t sa) {
1913014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  GenInstrRegister(SPECIAL, zero_reg, rt, rd, sa & 0x1F, DSRL32);
1914b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1915b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1916b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1917b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::dsra32(Register rd, Register rt, uint16_t sa) {
1918014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  GenInstrRegister(SPECIAL, zero_reg, rt, rd, sa & 0x1F, DSRA32);
1919014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
1920014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1921014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1922014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid Assembler::lsa(Register rd, Register rt, Register rs, uint8_t sa) {
1923014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(rd.is_valid() && rt.is_valid() && rs.is_valid());
19243b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  DCHECK(sa <= 3);
1925014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(kArchVariant == kMips64r6);
19263b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  Instr instr = SPECIAL | rs.code() << kRsShift | rt.code() << kRtShift |
19273b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch                rd.code() << kRdShift | sa << kSaShift | LSA;
1928014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  emit(instr);
1929014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
1930014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1931014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1932014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid Assembler::dlsa(Register rd, Register rt, Register rs, uint8_t sa) {
1933014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(rd.is_valid() && rt.is_valid() && rs.is_valid());
19343b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  DCHECK(sa <= 3);
1935014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(kArchVariant == kMips64r6);
19363b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  Instr instr = SPECIAL | rs.code() << kRsShift | rt.code() << kRtShift |
19373b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch                rd.code() << kRdShift | sa << kSaShift | DLSA;
1938014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  emit(instr);
1939b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1940b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1941b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1942b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// ------------Memory-instructions-------------
1943b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1944b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Helper for base-reg + offset, when offset is larger than int16.
1945b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::LoadRegPlusOffsetToAt(const MemOperand& src) {
1946b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(!src.rm().is(at));
1947b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(is_int32(src.offset_));
194862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
194962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  if (kArchVariant == kMips64r6) {
195062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    int32_t hi = (src.offset_ >> kLuiShift) & kImm16Mask;
195162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    if (src.offset_ & kNegOffset) {
195262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      if ((hi & kNegOffset) != ((hi + 1) & kNegOffset)) {
195362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch        lui(at, (src.offset_ >> kLuiShift) & kImm16Mask);
195462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch        ori(at, at, src.offset_ & kImm16Mask);  // Load 32-bit offset.
195562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch        daddu(at, at, src.rm());                // Add base register.
195662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch        return;
195762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      }
195862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
195962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      hi += 1;
196062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    }
196162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
196262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    daui(at, src.rm(), hi);
196362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    daddiu(at, at, src.offset_ & kImm16Mask);
196462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  } else {
196562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    lui(at, (src.offset_ >> kLuiShift) & kImm16Mask);
196662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    ori(at, at, src.offset_ & kImm16Mask);  // Load 32-bit offset.
196762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    daddu(at, at, src.rm());                // Add base register.
196862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  }
1969b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1970b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
197162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch// Helper for base-reg + upper part of offset, when offset is larger than int16.
197262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch// Loads higher part of the offset to AT register.
197362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch// Returns lower part of the offset to be used as offset
197462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch// in Load/Store instructions
197562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdochint32_t Assembler::LoadRegPlusUpperOffsetPartToAt(const MemOperand& src) {
197662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  DCHECK(!src.rm().is(at));
197762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  DCHECK(is_int32(src.offset_));
197862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  int32_t hi = (src.offset_ >> kLuiShift) & kImm16Mask;
197962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  // If the highest bit of the lower part of the offset is 1, this would make
198062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  // the offset in the load/store instruction negative. We need to compensate
198162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  // for this by adding 1 to the upper part of the offset.
198262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  if (src.offset_ & kNegOffset) {
198362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    if ((hi & kNegOffset) != ((hi + 1) & kNegOffset)) {
198462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      LoadRegPlusOffsetToAt(src);
198562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      return 0;
198662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    }
198762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
198862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    hi += 1;
198962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  }
199062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
199162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  if (kArchVariant == kMips64r6) {
199262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    daui(at, src.rm(), hi);
199362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  } else {
199462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    lui(at, hi);
199562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    daddu(at, at, src.rm());
199662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  }
199762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  return (src.offset_ & kImm16Mask);
199862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch}
1999b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2000b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::lb(Register rd, const MemOperand& rs) {
2001b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (is_int16(rs.offset_)) {
2002b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    GenInstrImmediate(LB, rs.rm(), rd, rs.offset_);
2003b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } else {  // Offset > 16 bits, use multiple instructions to load.
200462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    int32_t off16 = LoadRegPlusUpperOffsetPartToAt(rs);
200562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    GenInstrImmediate(LB, at, rd, off16);
2006b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
2007b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2008b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2009b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2010b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::lbu(Register rd, const MemOperand& rs) {
2011b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (is_int16(rs.offset_)) {
2012b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    GenInstrImmediate(LBU, rs.rm(), rd, rs.offset_);
2013b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } else {  // Offset > 16 bits, use multiple instructions to load.
201462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    int32_t off16 = LoadRegPlusUpperOffsetPartToAt(rs);
201562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    GenInstrImmediate(LBU, at, rd, off16);
2016b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
2017b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2018b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2019b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2020b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::lh(Register rd, const MemOperand& rs) {
2021b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (is_int16(rs.offset_)) {
2022b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    GenInstrImmediate(LH, rs.rm(), rd, rs.offset_);
2023b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } else {  // Offset > 16 bits, use multiple instructions to load.
202462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    int32_t off16 = LoadRegPlusUpperOffsetPartToAt(rs);
202562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    GenInstrImmediate(LH, at, rd, off16);
2026b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
2027b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2028b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2029b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2030b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::lhu(Register rd, const MemOperand& rs) {
2031b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (is_int16(rs.offset_)) {
2032b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    GenInstrImmediate(LHU, rs.rm(), rd, rs.offset_);
2033b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } else {  // Offset > 16 bits, use multiple instructions to load.
203462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    int32_t off16 = LoadRegPlusUpperOffsetPartToAt(rs);
203562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    GenInstrImmediate(LHU, at, rd, off16);
2036b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
2037b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2038b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2039b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2040b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::lw(Register rd, const MemOperand& rs) {
2041b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (is_int16(rs.offset_)) {
2042b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    GenInstrImmediate(LW, rs.rm(), rd, rs.offset_);
2043b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } else {  // Offset > 16 bits, use multiple instructions to load.
204462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    int32_t off16 = LoadRegPlusUpperOffsetPartToAt(rs);
204562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    GenInstrImmediate(LW, at, rd, off16);
2046b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
2047b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2048b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2049b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2050b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::lwu(Register rd, const MemOperand& rs) {
2051b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (is_int16(rs.offset_)) {
2052b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    GenInstrImmediate(LWU, rs.rm(), rd, rs.offset_);
2053b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } else {  // Offset > 16 bits, use multiple instructions to load.
205462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    int32_t off16 = LoadRegPlusUpperOffsetPartToAt(rs);
205562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    GenInstrImmediate(LWU, at, rd, off16);
2056b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
2057b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2058b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2059b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2060b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::lwl(Register rd, const MemOperand& rs) {
2061bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  DCHECK(is_int16(rs.offset_));
2062bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  DCHECK(kArchVariant == kMips64r2);
2063b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  GenInstrImmediate(LWL, rs.rm(), rd, rs.offset_);
2064b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2065b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2066b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2067b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::lwr(Register rd, const MemOperand& rs) {
2068bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  DCHECK(is_int16(rs.offset_));
2069bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  DCHECK(kArchVariant == kMips64r2);
2070b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  GenInstrImmediate(LWR, rs.rm(), rd, rs.offset_);
2071b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2072b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2073b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2074b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::sb(Register rd, const MemOperand& rs) {
2075b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (is_int16(rs.offset_)) {
2076b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    GenInstrImmediate(SB, rs.rm(), rd, rs.offset_);
2077b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } else {  // Offset > 16 bits, use multiple instructions to store.
207862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    int32_t off16 = LoadRegPlusUpperOffsetPartToAt(rs);
207962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    GenInstrImmediate(SB, at, rd, off16);
2080b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
2081b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2082b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2083b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2084b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::sh(Register rd, const MemOperand& rs) {
2085b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (is_int16(rs.offset_)) {
2086b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    GenInstrImmediate(SH, rs.rm(), rd, rs.offset_);
2087b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } else {  // Offset > 16 bits, use multiple instructions to store.
208862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    int32_t off16 = LoadRegPlusUpperOffsetPartToAt(rs);
208962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    GenInstrImmediate(SH, at, rd, off16);
2090b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
2091b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2092b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2093b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2094b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::sw(Register rd, const MemOperand& rs) {
2095b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (is_int16(rs.offset_)) {
2096b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    GenInstrImmediate(SW, rs.rm(), rd, rs.offset_);
2097b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } else {  // Offset > 16 bits, use multiple instructions to store.
209862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    int32_t off16 = LoadRegPlusUpperOffsetPartToAt(rs);
209962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    GenInstrImmediate(SW, at, rd, off16);
2100b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
2101b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2102b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2103b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2104b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::swl(Register rd, const MemOperand& rs) {
2105bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  DCHECK(is_int16(rs.offset_));
2106bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  DCHECK(kArchVariant == kMips64r2);
2107b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  GenInstrImmediate(SWL, rs.rm(), rd, rs.offset_);
2108b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2109b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2110b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2111b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::swr(Register rd, const MemOperand& rs) {
2112bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  DCHECK(is_int16(rs.offset_));
2113bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  DCHECK(kArchVariant == kMips64r2);
2114b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  GenInstrImmediate(SWR, rs.rm(), rd, rs.offset_);
2115b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2116b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2117b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2118b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::lui(Register rd, int32_t j) {
2119b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(is_uint16(j));
2120b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  GenInstrImmediate(LUI, zero_reg, rd, j);
2121b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2122b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2123b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2124014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid Assembler::aui(Register rt, Register rs, int32_t j) {
2125b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // This instruction uses same opcode as 'lui'. The difference in encoding is
2126b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // 'lui' has zero reg. for rs field.
2127b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(is_uint16(j));
2128b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  GenInstrImmediate(LUI, rs, rt, j);
2129b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2130b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2131b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2132014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid Assembler::daui(Register rt, Register rs, int32_t j) {
2133b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(is_uint16(j));
2134014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(!rs.is(zero_reg));
2135b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  GenInstrImmediate(DAUI, rs, rt, j);
2136b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2137b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2138b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2139b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::dahi(Register rs, int32_t j) {
2140b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(is_uint16(j));
2141b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  GenInstrImmediate(REGIMM, rs, DAHI, j);
2142b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2143b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2144b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2145b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::dati(Register rs, int32_t j) {
2146b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(is_uint16(j));
2147b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  GenInstrImmediate(REGIMM, rs, DATI, j);
2148b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2149b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2150b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2151b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::ldl(Register rd, const MemOperand& rs) {
2152bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  DCHECK(is_int16(rs.offset_));
2153bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  DCHECK(kArchVariant == kMips64r2);
2154b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  GenInstrImmediate(LDL, rs.rm(), rd, rs.offset_);
2155b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2156b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2157b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2158b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::ldr(Register rd, const MemOperand& rs) {
2159bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  DCHECK(is_int16(rs.offset_));
2160bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  DCHECK(kArchVariant == kMips64r2);
2161b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  GenInstrImmediate(LDR, rs.rm(), rd, rs.offset_);
2162b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2163b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2164b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2165b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::sdl(Register rd, const MemOperand& rs) {
2166bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  DCHECK(is_int16(rs.offset_));
2167bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  DCHECK(kArchVariant == kMips64r2);
2168b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  GenInstrImmediate(SDL, rs.rm(), rd, rs.offset_);
2169b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2170b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2171b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2172b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::sdr(Register rd, const MemOperand& rs) {
2173bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  DCHECK(is_int16(rs.offset_));
2174bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  DCHECK(kArchVariant == kMips64r2);
2175b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  GenInstrImmediate(SDR, rs.rm(), rd, rs.offset_);
2176b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2177b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2178b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2179b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::ld(Register rd, const MemOperand& rs) {
2180b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (is_int16(rs.offset_)) {
2181b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    GenInstrImmediate(LD, rs.rm(), rd, rs.offset_);
2182b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } else {  // Offset > 16 bits, use multiple instructions to load.
218362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    int32_t off16 = LoadRegPlusUpperOffsetPartToAt(rs);
218462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    GenInstrImmediate(LD, at, rd, off16);
2185b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
2186b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2187b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2188b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2189b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::sd(Register rd, const MemOperand& rs) {
2190b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (is_int16(rs.offset_)) {
2191b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    GenInstrImmediate(SD, rs.rm(), rd, rs.offset_);
2192b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } else {  // Offset > 16 bits, use multiple instructions to store.
219362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    int32_t off16 = LoadRegPlusUpperOffsetPartToAt(rs);
219462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    GenInstrImmediate(SD, at, rd, off16);
2195b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
2196b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2197b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2198b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2199014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// ---------PC-Relative instructions-----------
2200b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2201014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid Assembler::addiupc(Register rs, int32_t imm19) {
2202014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(kArchVariant == kMips64r6);
2203014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(rs.is_valid() && is_int19(imm19));
2204014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  uint32_t imm21 = ADDIUPC << kImm19Bits | (imm19 & kImm19Mask);
2205014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  GenInstrImmediate(PCREL, rs, imm21);
2206014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
2207014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2208014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2209014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid Assembler::lwpc(Register rs, int32_t offset19) {
2210014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(kArchVariant == kMips64r6);
2211014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(rs.is_valid() && is_int19(offset19));
2212014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  uint32_t imm21 = LWPC << kImm19Bits | (offset19 & kImm19Mask);
2213014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  GenInstrImmediate(PCREL, rs, imm21);
2214014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
2215014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2216014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2217014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid Assembler::lwupc(Register rs, int32_t offset19) {
2218014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(kArchVariant == kMips64r6);
2219014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(rs.is_valid() && is_int19(offset19));
2220014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  uint32_t imm21 = LWUPC << kImm19Bits | (offset19 & kImm19Mask);
2221014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  GenInstrImmediate(PCREL, rs, imm21);
2222014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
2223014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2224014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2225014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid Assembler::ldpc(Register rs, int32_t offset18) {
2226014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(kArchVariant == kMips64r6);
2227014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(rs.is_valid() && is_int18(offset18));
2228014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  uint32_t imm21 = LDPC << kImm18Bits | (offset18 & kImm18Mask);
2229014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  GenInstrImmediate(PCREL, rs, imm21);
2230014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
2231014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2232014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2233014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid Assembler::auipc(Register rs, int16_t imm16) {
2234014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(kArchVariant == kMips64r6);
2235014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(rs.is_valid());
2236014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  uint32_t imm21 = AUIPC << kImm16Bits | (imm16 & kImm16Mask);
2237014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  GenInstrImmediate(PCREL, rs, imm21);
2238014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
2239014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2240014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2241014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid Assembler::aluipc(Register rs, int16_t imm16) {
2242014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(kArchVariant == kMips64r6);
2243014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(rs.is_valid());
2244014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  uint32_t imm21 = ALUIPC << kImm16Bits | (imm16 & kImm16Mask);
2245014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  GenInstrImmediate(PCREL, rs, imm21);
2246014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
2247014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2248014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2249014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// -------------Misc-instructions--------------
2250014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2251014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// Break / Trap instructions.
2252014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid Assembler::break_(uint32_t code, bool break_as_stop) {
2253014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK((code & ~0xfffff) == 0);
2254014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // We need to invalidate breaks that could be stops as well because the
2255014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // simulator expects a char pointer after the stop instruction.
2256014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // See constants-mips.h for explanation.
2257014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK((break_as_stop &&
2258b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          code <= kMaxStopCode &&
2259b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          code > kMaxWatchpointCode) ||
2260b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch         (!break_as_stop &&
2261b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          (code > kMaxStopCode ||
2262b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch           code <= kMaxWatchpointCode)));
2263b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Instr break_instr = SPECIAL | BREAK | (code << 6);
2264b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  emit(break_instr);
2265b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2266b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2267b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2268b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::stop(const char* msg, uint32_t code) {
2269b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(code > kMaxWatchpointCode);
2270b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(code <= kMaxStopCode);
2271b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#if defined(V8_HOST_ARCH_MIPS) || defined(V8_HOST_ARCH_MIPS64)
2272b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  break_(0x54321);
2273b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#else  // V8_HOST_ARCH_MIPS
2274b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  BlockTrampolinePoolFor(3);
2275b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // The Simulator will handle the stop instruction and get the message address.
2276b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // On MIPS stop() is just a special kind of break_().
2277b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  break_(code, true);
2278f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  // Do not embed the message string address! We used to do this, but that
2279f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  // made snapshots created from position-independent executable builds
2280f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  // non-deterministic.
2281f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  // TODO(yangguo): remove this field entirely.
2282f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  nop();
2283b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#endif
2284b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2285b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2286b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2287b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::tge(Register rs, Register rt, uint16_t code) {
2288b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(is_uint10(code));
2289b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Instr instr = SPECIAL | TGE | rs.code() << kRsShift
2290b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      | rt.code() << kRtShift | code << 6;
2291b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  emit(instr);
2292b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2293b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2294b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2295b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::tgeu(Register rs, Register rt, uint16_t code) {
2296b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(is_uint10(code));
2297b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Instr instr = SPECIAL | TGEU | rs.code() << kRsShift
2298b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      | rt.code() << kRtShift | code << 6;
2299b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  emit(instr);
2300b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2301b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2302b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2303b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::tlt(Register rs, Register rt, uint16_t code) {
2304b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(is_uint10(code));
2305b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Instr instr =
2306b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      SPECIAL | TLT | rs.code() << kRsShift | rt.code() << kRtShift | code << 6;
2307b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  emit(instr);
2308b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2309b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2310b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2311b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::tltu(Register rs, Register rt, uint16_t code) {
2312b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(is_uint10(code));
2313b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Instr instr =
2314b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      SPECIAL | TLTU | rs.code() << kRsShift
2315b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      | rt.code() << kRtShift | code << 6;
2316b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  emit(instr);
2317b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2318b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2319b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2320b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::teq(Register rs, Register rt, uint16_t code) {
2321b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(is_uint10(code));
2322b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Instr instr =
2323b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      SPECIAL | TEQ | rs.code() << kRsShift | rt.code() << kRtShift | code << 6;
2324b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  emit(instr);
2325b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2326b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2327b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2328b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::tne(Register rs, Register rt, uint16_t code) {
2329b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(is_uint10(code));
2330b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Instr instr =
2331b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      SPECIAL | TNE | rs.code() << kRsShift | rt.code() << kRtShift | code << 6;
2332b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  emit(instr);
2333b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2334b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2335bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdochvoid Assembler::sync() {
2336bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  Instr sync_instr = SPECIAL | SYNC;
2337bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  emit(sync_instr);
2338bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch}
2339b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2340b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Move from HI/LO register.
2341b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2342b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::mfhi(Register rd) {
2343b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  GenInstrRegister(SPECIAL, zero_reg, zero_reg, rd, 0, MFHI);
2344b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2345b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2346b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2347b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::mflo(Register rd) {
2348b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  GenInstrRegister(SPECIAL, zero_reg, zero_reg, rd, 0, MFLO);
2349b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2350b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2351b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2352b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Set on less than instructions.
2353b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::slt(Register rd, Register rs, Register rt) {
2354b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  GenInstrRegister(SPECIAL, rs, rt, rd, 0, SLT);
2355b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2356b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2357b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2358b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::sltu(Register rd, Register rs, Register rt) {
2359b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  GenInstrRegister(SPECIAL, rs, rt, rd, 0, SLTU);
2360b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2361b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2362b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2363b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::slti(Register rt, Register rs, int32_t j) {
2364b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  GenInstrImmediate(SLTI, rs, rt, j);
2365b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2366b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2367b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2368b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::sltiu(Register rt, Register rs, int32_t j) {
2369b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  GenInstrImmediate(SLTIU, rs, rt, j);
2370b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2371b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2372b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2373b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Conditional move.
2374b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::movz(Register rd, Register rs, Register rt) {
2375b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  GenInstrRegister(SPECIAL, rs, rt, rd, 0, MOVZ);
2376b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2377b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2378b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2379b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::movn(Register rd, Register rs, Register rt) {
2380b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  GenInstrRegister(SPECIAL, rs, rt, rd, 0, MOVN);
2381b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2382b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2383b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2384b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::movt(Register rd, Register rs, uint16_t cc) {
2385b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Register rt;
2386014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  rt.reg_code = (cc & 0x0007) << 2 | 1;
2387b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  GenInstrRegister(SPECIAL, rs, rt, rd, 0, MOVCI);
2388b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2389b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2390b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2391b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::movf(Register rd, Register rs, uint16_t cc) {
2392b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Register rt;
2393014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  rt.reg_code = (cc & 0x0007) << 2 | 0;
2394b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  GenInstrRegister(SPECIAL, rs, rt, rd, 0, MOVCI);
2395b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2396b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2397b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2398014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid Assembler::min_s(FPURegister fd, FPURegister fs, FPURegister ft) {
2399014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  min(S, fd, fs, ft);
2400014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
2401b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2402014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2403014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid Assembler::min_d(FPURegister fd, FPURegister fs, FPURegister ft) {
2404014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  min(D, fd, fs, ft);
2405b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2406b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2407b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2408014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid Assembler::max_s(FPURegister fd, FPURegister fs, FPURegister ft) {
2409014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  max(S, fd, fs, ft);
2410b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2411b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2412b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2413014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid Assembler::max_d(FPURegister fd, FPURegister fs, FPURegister ft) {
2414014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  max(D, fd, fs, ft);
2415014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
2416014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2417014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2418014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid Assembler::mina_s(FPURegister fd, FPURegister fs, FPURegister ft) {
2419014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  mina(S, fd, fs, ft);
2420014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
2421014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2422014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2423014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid Assembler::mina_d(FPURegister fd, FPURegister fs, FPURegister ft) {
2424014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  mina(D, fd, fs, ft);
2425014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
2426014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2427014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2428014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid Assembler::maxa_s(FPURegister fd, FPURegister fs, FPURegister ft) {
2429014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  maxa(S, fd, fs, ft);
2430014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
2431014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2432014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2433014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid Assembler::maxa_d(FPURegister fd, FPURegister fs, FPURegister ft) {
2434014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  maxa(D, fd, fs, ft);
2435014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
2436014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2437014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2438014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid Assembler::max(SecondaryField fmt, FPURegister fd, FPURegister fs,
2439014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                    FPURegister ft) {
2440b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(kArchVariant == kMips64r6);
2441014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK((fmt == D) || (fmt == S));
2442014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  GenInstrRegister(COP1, fmt, ft, fs, fd, MAX);
2443014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
2444b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2445014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2446014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid Assembler::min(SecondaryField fmt, FPURegister fd, FPURegister fs,
2447014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                    FPURegister ft) {
2448014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(kArchVariant == kMips64r6);
2449014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK((fmt == D) || (fmt == S));
2450014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  GenInstrRegister(COP1, fmt, ft, fs, fd, MIN);
2451b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2452b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2453b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2454b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// GPR.
2455014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid Assembler::seleqz(Register rd, Register rs, Register rt) {
2456b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(kArchVariant == kMips64r6);
2457014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  GenInstrRegister(SPECIAL, rs, rt, rd, 0, SELEQZ_S);
2458b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2459b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2460b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2461014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// GPR.
2462014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid Assembler::selnez(Register rd, Register rs, Register rt) {
2463b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(kArchVariant == kMips64r6);
2464014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  GenInstrRegister(SPECIAL, rs, rt, rd, 0, SELNEZ_S);
2465b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2466b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2467b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2468b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Bit twiddling.
2469b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::clz(Register rd, Register rs) {
2470b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (kArchVariant != kMips64r6) {
2471b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Clz instr requires same GPR number in 'rd' and 'rt' fields.
2472b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    GenInstrRegister(SPECIAL2, rs, rd, rd, 0, CLZ);
2473b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } else {
2474b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    GenInstrRegister(SPECIAL, rs, zero_reg, rd, 1, CLZ_R6);
2475b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
2476b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2477b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2478b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2479014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid Assembler::dclz(Register rd, Register rs) {
2480014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (kArchVariant != kMips64r6) {
2481014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // dclz instr requires same GPR number in 'rd' and 'rt' fields.
2482014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    GenInstrRegister(SPECIAL2, rs, rd, rd, 0, DCLZ);
2483014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  } else {
2484014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    GenInstrRegister(SPECIAL, rs, zero_reg, rd, 1, DCLZ_R6);
2485014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
2486014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
2487014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2488014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2489b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::ins_(Register rt, Register rs, uint16_t pos, uint16_t size) {
2490b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Should be called via MacroAssembler::Ins.
2491b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Ins instr has 'rt' field as dest, and two uint5: msb, lsb.
2492b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK((kArchVariant == kMips64r2) || (kArchVariant == kMips64r6));
2493b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  GenInstrRegister(SPECIAL3, rs, rt, pos + size - 1, pos, INS);
2494b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2495b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2496b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2497014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid Assembler::dins_(Register rt, Register rs, uint16_t pos, uint16_t size) {
2498014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Should be called via MacroAssembler::Dins.
2499014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Dext instr has 'rt' field as dest, and two uint5: msb, lsb.
2500014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(kArchVariant == kMips64r2 || kArchVariant == kMips64r6);
2501014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  GenInstrRegister(SPECIAL3, rs, rt, pos + size - 1, pos, DINS);
2502014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
2503014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2504014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2505b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::ext_(Register rt, Register rs, uint16_t pos, uint16_t size) {
2506b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Should be called via MacroAssembler::Ext.
2507b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Ext instr has 'rt' field as dest, and two uint5: msb, lsb.
2508b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(kArchVariant == kMips64r2 || kArchVariant == kMips64r6);
2509b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  GenInstrRegister(SPECIAL3, rs, rt, size - 1, pos, EXT);
2510b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2511b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2512b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2513958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniervoid Assembler::dext_(Register rt, Register rs, uint16_t pos, uint16_t size) {
2514014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Should be called via MacroAssembler::Dext.
2515958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  // Dext instr has 'rt' field as dest, and two uint5: msb, lsb.
2516958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  DCHECK(kArchVariant == kMips64r2 || kArchVariant == kMips64r6);
2517958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  GenInstrRegister(SPECIAL3, rs, rt, size - 1, pos, DEXT);
2518958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier}
2519958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
2520958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
2521014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid Assembler::dextm(Register rt, Register rs, uint16_t pos, uint16_t size) {
2522014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Should be called via MacroAssembler::Dextm.
2523014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Dextm instr has 'rt' field as dest, and two uint5: msb, lsb.
2524014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(kArchVariant == kMips64r2 || kArchVariant == kMips64r6);
2525014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  GenInstrRegister(SPECIAL3, rs, rt, size - 1 - 32, pos, DEXTM);
2526014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
2527014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2528014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2529014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid Assembler::dextu(Register rt, Register rs, uint16_t pos, uint16_t size) {
2530014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Should be called via MacroAssembler::Dextu.
2531014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Dext instr has 'rt' field as dest, and two uint5: msb, lsb.
2532014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(kArchVariant == kMips64r2 || kArchVariant == kMips64r6);
2533014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  GenInstrRegister(SPECIAL3, rs, rt, size - 1, pos - 32, DEXTU);
2534014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
2535014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2536014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2537014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid Assembler::bitswap(Register rd, Register rt) {
2538014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(kArchVariant == kMips64r6);
2539014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  GenInstrRegister(SPECIAL3, zero_reg, rt, rd, 0, BSHFL);
2540014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
2541014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2542014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2543014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid Assembler::dbitswap(Register rd, Register rt) {
2544014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(kArchVariant == kMips64r6);
2545014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  GenInstrRegister(SPECIAL3, zero_reg, rt, rd, 0, DBSHFL);
2546014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
2547014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2548014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2549b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::pref(int32_t hint, const MemOperand& rs) {
2550b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(is_uint5(hint) && is_uint16(rs.offset_));
2551b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Instr instr = PREF | (rs.rm().code() << kRsShift) | (hint << kRtShift)
2552b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      | (rs.offset_);
2553b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  emit(instr);
2554b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2555b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2556b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2557014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid Assembler::align(Register rd, Register rs, Register rt, uint8_t bp) {
2558014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(kArchVariant == kMips64r6);
2559014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(is_uint3(bp));
2560014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  uint16_t sa = (ALIGN << kBp2Bits) | bp;
2561014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  GenInstrRegister(SPECIAL3, rs, rt, rd, sa, BSHFL);
2562014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
2563014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2564014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2565014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid Assembler::dalign(Register rd, Register rs, Register rt, uint8_t bp) {
2566014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(kArchVariant == kMips64r6);
2567014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(is_uint3(bp));
2568014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  uint16_t sa = (DALIGN << kBp3Bits) | bp;
2569014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  GenInstrRegister(SPECIAL3, rs, rt, rd, sa, DBSHFL);
2570014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
2571014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
257213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdochvoid Assembler::wsbh(Register rd, Register rt) {
257313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  DCHECK(kArchVariant == kMips64r2 || kArchVariant == kMips64r6);
257413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  GenInstrRegister(SPECIAL3, zero_reg, rt, rd, WSBH, BSHFL);
257513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch}
257613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch
257713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdochvoid Assembler::dsbh(Register rd, Register rt) {
257813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  DCHECK(kArchVariant == kMips64r2 || kArchVariant == kMips64r6);
257913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  GenInstrRegister(SPECIAL3, zero_reg, rt, rd, DSBH, DBSHFL);
258013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch}
258113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch
258213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdochvoid Assembler::dshd(Register rd, Register rt) {
258313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  DCHECK(kArchVariant == kMips64r2 || kArchVariant == kMips64r6);
258413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  GenInstrRegister(SPECIAL3, zero_reg, rt, rd, DSHD, DBSHFL);
258513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch}
258613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch
258713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdochvoid Assembler::seh(Register rd, Register rt) {
258813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  DCHECK(kArchVariant == kMips64r2 || kArchVariant == kMips64r6);
258913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  GenInstrRegister(SPECIAL3, zero_reg, rt, rd, SEH, BSHFL);
259013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch}
259113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch
259213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdochvoid Assembler::seb(Register rd, Register rt) {
259313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  DCHECK(kArchVariant == kMips64r2 || kArchVariant == kMips64r6);
259413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  GenInstrRegister(SPECIAL3, zero_reg, rt, rd, SEB, BSHFL);
259513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch}
2596014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2597b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// --------Coprocessor-instructions----------------
2598b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2599b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Load, store, move.
2600b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::lwc1(FPURegister fd, const MemOperand& src) {
2601014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (is_int16(src.offset_)) {
2602014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    GenInstrImmediate(LWC1, src.rm(), fd, src.offset_);
2603014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  } else {  // Offset > 16 bits, use multiple instructions to load.
260462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    int32_t off16 = LoadRegPlusUpperOffsetPartToAt(src);
260562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    GenInstrImmediate(LWC1, at, fd, off16);
2606014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
2607b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2608b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2609b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2610b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::ldc1(FPURegister fd, const MemOperand& src) {
2611014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (is_int16(src.offset_)) {
2612014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    GenInstrImmediate(LDC1, src.rm(), fd, src.offset_);
2613014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  } else {  // Offset > 16 bits, use multiple instructions to load.
261462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    int32_t off16 = LoadRegPlusUpperOffsetPartToAt(src);
261562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    GenInstrImmediate(LDC1, at, fd, off16);
2616014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
2617b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2618b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2619b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2620b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::swc1(FPURegister fd, const MemOperand& src) {
2621014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (is_int16(src.offset_)) {
2622014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    GenInstrImmediate(SWC1, src.rm(), fd, src.offset_);
2623014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  } else {  // Offset > 16 bits, use multiple instructions to load.
262462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    int32_t off16 = LoadRegPlusUpperOffsetPartToAt(src);
262562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    GenInstrImmediate(SWC1, at, fd, off16);
2626014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
2627b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2628b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2629b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2630b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::sdc1(FPURegister fd, const MemOperand& src) {
2631014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(!src.rm().is(at));
2632014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (is_int16(src.offset_)) {
2633014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    GenInstrImmediate(SDC1, src.rm(), fd, src.offset_);
2634014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  } else {  // Offset > 16 bits, use multiple instructions to load.
263562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    int32_t off16 = LoadRegPlusUpperOffsetPartToAt(src);
263662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    GenInstrImmediate(SDC1, at, fd, off16);
2637014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
2638b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2639b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2640b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2641b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::mtc1(Register rt, FPURegister fs) {
2642b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  GenInstrRegister(COP1, MTC1, rt, fs, f0);
2643b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2644b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2645b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2646b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::mthc1(Register rt, FPURegister fs) {
2647b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  GenInstrRegister(COP1, MTHC1, rt, fs, f0);
2648b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2649b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2650b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2651b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::dmtc1(Register rt, FPURegister fs) {
2652b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  GenInstrRegister(COP1, DMTC1, rt, fs, f0);
2653b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2654b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2655b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2656b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::mfc1(Register rt, FPURegister fs) {
2657b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  GenInstrRegister(COP1, MFC1, rt, fs, f0);
2658b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2659b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2660b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2661b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::mfhc1(Register rt, FPURegister fs) {
2662b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  GenInstrRegister(COP1, MFHC1, rt, fs, f0);
2663b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2664b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2665b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2666b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::dmfc1(Register rt, FPURegister fs) {
2667b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  GenInstrRegister(COP1, DMFC1, rt, fs, f0);
2668b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2669b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2670b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2671b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::ctc1(Register rt, FPUControlRegister fs) {
2672b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  GenInstrRegister(COP1, CTC1, rt, fs);
2673b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2674b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2675b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2676b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::cfc1(Register rt, FPUControlRegister fs) {
2677b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  GenInstrRegister(COP1, CFC1, rt, fs);
2678b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2679b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2680b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2681b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::DoubleAsTwoUInt32(double d, uint32_t* lo, uint32_t* hi) {
2682b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  uint64_t i;
2683b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  memcpy(&i, &d, 8);
2684b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2685b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  *lo = i & 0xffffffff;
2686b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  *hi = i >> 32;
2687b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2688b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2689b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2690014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid Assembler::sel(SecondaryField fmt, FPURegister fd, FPURegister fs,
2691014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                    FPURegister ft) {
2692014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(kArchVariant == kMips64r6);
2693014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK((fmt == D) || (fmt == S));
2694014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2695014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  GenInstrRegister(COP1, fmt, ft, fs, fd, SEL);
2696014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
2697014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2698014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2699014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid Assembler::sel_s(FPURegister fd, FPURegister fs, FPURegister ft) {
2700014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  sel(S, fd, fs, ft);
2701014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
2702014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2703014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2704014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid Assembler::sel_d(FPURegister fd, FPURegister fs, FPURegister ft) {
2705014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  sel(D, fd, fs, ft);
2706014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
2707014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2708014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2709014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// FPR.
2710014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid Assembler::seleqz(SecondaryField fmt, FPURegister fd, FPURegister fs,
2711014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                       FPURegister ft) {
2712014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK((fmt == D) || (fmt == S));
2713014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  GenInstrRegister(COP1, fmt, ft, fs, fd, SELEQZ_C);
2714014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
2715014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2716014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2717014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid Assembler::seleqz_d(FPURegister fd, FPURegister fs, FPURegister ft) {
2718014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  seleqz(D, fd, fs, ft);
2719014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
2720014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2721014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2722014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid Assembler::seleqz_s(FPURegister fd, FPURegister fs, FPURegister ft) {
2723014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  seleqz(S, fd, fs, ft);
2724014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
2725014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2726014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2727014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid Assembler::selnez_d(FPURegister fd, FPURegister fs, FPURegister ft) {
2728014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  selnez(D, fd, fs, ft);
2729014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
2730014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2731014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2732014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid Assembler::selnez_s(FPURegister fd, FPURegister fs, FPURegister ft) {
2733014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  selnez(S, fd, fs, ft);
2734014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
2735014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2736014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2737014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid Assembler::movz_s(FPURegister fd, FPURegister fs, Register rt) {
2738014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(kArchVariant == kMips64r2);
2739014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  GenInstrRegister(COP1, S, rt, fs, fd, MOVZ_C);
2740014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
2741014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2742014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2743014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid Assembler::movz_d(FPURegister fd, FPURegister fs, Register rt) {
2744014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(kArchVariant == kMips64r2);
2745014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  GenInstrRegister(COP1, D, rt, fs, fd, MOVZ_C);
2746014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
2747014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2748014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2749014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid Assembler::movt_s(FPURegister fd, FPURegister fs, uint16_t cc) {
2750014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(kArchVariant == kMips64r2);
2751014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  FPURegister ft;
2752014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  ft.reg_code = (cc & 0x0007) << 2 | 1;
2753014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  GenInstrRegister(COP1, S, ft, fs, fd, MOVF);
2754014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
2755014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2756014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2757014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid Assembler::movt_d(FPURegister fd, FPURegister fs, uint16_t cc) {
2758014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(kArchVariant == kMips64r2);
2759014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  FPURegister ft;
2760014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  ft.reg_code = (cc & 0x0007) << 2 | 1;
2761014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  GenInstrRegister(COP1, D, ft, fs, fd, MOVF);
2762014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
2763014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2764014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2765014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid Assembler::movf_s(FPURegister fd, FPURegister fs, uint16_t cc) {
2766014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(kArchVariant == kMips64r2);
2767014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  FPURegister ft;
2768014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  ft.reg_code = (cc & 0x0007) << 2 | 0;
2769014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  GenInstrRegister(COP1, S, ft, fs, fd, MOVF);
2770014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
2771014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2772014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2773014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid Assembler::movf_d(FPURegister fd, FPURegister fs, uint16_t cc) {
2774014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(kArchVariant == kMips64r2);
2775014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  FPURegister ft;
2776014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  ft.reg_code = (cc & 0x0007) << 2 | 0;
2777014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  GenInstrRegister(COP1, D, ft, fs, fd, MOVF);
2778014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
2779014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2780014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2781014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid Assembler::movn_s(FPURegister fd, FPURegister fs, Register rt) {
2782014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(kArchVariant == kMips64r2);
2783014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  GenInstrRegister(COP1, S, rt, fs, fd, MOVN_C);
2784014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
2785014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2786014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2787014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid Assembler::movn_d(FPURegister fd, FPURegister fs, Register rt) {
2788014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(kArchVariant == kMips64r2);
2789014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  GenInstrRegister(COP1, D, rt, fs, fd, MOVN_C);
2790014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
2791014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2792014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2793014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// FPR.
2794014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid Assembler::selnez(SecondaryField fmt, FPURegister fd, FPURegister fs,
2795014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                       FPURegister ft) {
2796014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(kArchVariant == kMips64r6);
2797014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK((fmt == D) || (fmt == S));
2798014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  GenInstrRegister(COP1, fmt, ft, fs, fd, SELNEZ_C);
2799014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
2800014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2801014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2802b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Arithmetic.
2803b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2804014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid Assembler::add_s(FPURegister fd, FPURegister fs, FPURegister ft) {
2805014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  GenInstrRegister(COP1, S, ft, fs, fd, ADD_D);
2806014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
2807014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2808014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2809b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::add_d(FPURegister fd, FPURegister fs, FPURegister ft) {
2810b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  GenInstrRegister(COP1, D, ft, fs, fd, ADD_D);
2811b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2812b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2813b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2814014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid Assembler::sub_s(FPURegister fd, FPURegister fs, FPURegister ft) {
2815014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  GenInstrRegister(COP1, S, ft, fs, fd, SUB_D);
2816014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
2817014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2818014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2819b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::sub_d(FPURegister fd, FPURegister fs, FPURegister ft) {
2820b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  GenInstrRegister(COP1, D, ft, fs, fd, SUB_D);
2821b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2822b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2823b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2824014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid Assembler::mul_s(FPURegister fd, FPURegister fs, FPURegister ft) {
2825014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  GenInstrRegister(COP1, S, ft, fs, fd, MUL_D);
2826014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
2827014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2828014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2829b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::mul_d(FPURegister fd, FPURegister fs, FPURegister ft) {
2830b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  GenInstrRegister(COP1, D, ft, fs, fd, MUL_D);
2831b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2832b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2833f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochvoid Assembler::madd_s(FPURegister fd, FPURegister fr, FPURegister fs,
2834f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                       FPURegister ft) {
2835f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  DCHECK(kArchVariant == kMips64r2);
2836f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  GenInstrRegister(COP1X, fr, ft, fs, fd, MADD_S);
2837f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch}
2838b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2839b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::madd_d(FPURegister fd, FPURegister fr, FPURegister fs,
2840b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    FPURegister ft) {
2841f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  DCHECK(kArchVariant == kMips64r2);
2842b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  GenInstrRegister(COP1X, fr, ft, fs, fd, MADD_D);
2843b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2844b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2845f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochvoid Assembler::msub_s(FPURegister fd, FPURegister fr, FPURegister fs,
2846f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                       FPURegister ft) {
2847f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  DCHECK(kArchVariant == kMips64r2);
2848f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  GenInstrRegister(COP1X, fr, ft, fs, fd, MSUB_S);
2849f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch}
2850f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
2851f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochvoid Assembler::msub_d(FPURegister fd, FPURegister fr, FPURegister fs,
2852f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                       FPURegister ft) {
2853f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  DCHECK(kArchVariant == kMips64r2);
2854f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  GenInstrRegister(COP1X, fr, ft, fs, fd, MSUB_D);
2855f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch}
2856f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
2857f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochvoid Assembler::maddf_s(FPURegister fd, FPURegister fs, FPURegister ft) {
2858f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  DCHECK(kArchVariant == kMips64r6);
2859f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  GenInstrRegister(COP1, S, ft, fs, fd, MADDF_S);
2860f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch}
2861f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
2862f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochvoid Assembler::maddf_d(FPURegister fd, FPURegister fs, FPURegister ft) {
2863f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  DCHECK(kArchVariant == kMips64r6);
2864f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  GenInstrRegister(COP1, D, ft, fs, fd, MADDF_D);
2865f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch}
2866f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
2867f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochvoid Assembler::msubf_s(FPURegister fd, FPURegister fs, FPURegister ft) {
2868f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  DCHECK(kArchVariant == kMips64r6);
2869f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  GenInstrRegister(COP1, S, ft, fs, fd, MSUBF_S);
2870f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch}
2871f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
2872f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochvoid Assembler::msubf_d(FPURegister fd, FPURegister fs, FPURegister ft) {
2873f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  DCHECK(kArchVariant == kMips64r6);
2874f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  GenInstrRegister(COP1, D, ft, fs, fd, MSUBF_D);
2875f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch}
2876b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2877014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid Assembler::div_s(FPURegister fd, FPURegister fs, FPURegister ft) {
2878014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  GenInstrRegister(COP1, S, ft, fs, fd, DIV_D);
2879014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
2880014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2881014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2882b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::div_d(FPURegister fd, FPURegister fs, FPURegister ft) {
2883b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  GenInstrRegister(COP1, D, ft, fs, fd, DIV_D);
2884b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2885b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2886b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2887014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid Assembler::abs_s(FPURegister fd, FPURegister fs) {
2888014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  GenInstrRegister(COP1, S, f0, fs, fd, ABS_D);
2889014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
2890014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2891014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2892b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::abs_d(FPURegister fd, FPURegister fs) {
2893b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  GenInstrRegister(COP1, D, f0, fs, fd, ABS_D);
2894b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2895b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2896b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2897b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::mov_d(FPURegister fd, FPURegister fs) {
2898b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  GenInstrRegister(COP1, D, f0, fs, fd, MOV_D);
2899b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2900b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2901b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2902014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid Assembler::mov_s(FPURegister fd, FPURegister fs) {
2903014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  GenInstrRegister(COP1, S, f0, fs, fd, MOV_S);
2904014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
2905014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2906014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2907014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid Assembler::neg_s(FPURegister fd, FPURegister fs) {
2908014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  GenInstrRegister(COP1, S, f0, fs, fd, NEG_D);
2909014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
2910014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2911014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2912b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::neg_d(FPURegister fd, FPURegister fs) {
2913b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  GenInstrRegister(COP1, D, f0, fs, fd, NEG_D);
2914b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2915b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2916b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2917014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid Assembler::sqrt_s(FPURegister fd, FPURegister fs) {
2918014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  GenInstrRegister(COP1, S, f0, fs, fd, SQRT_D);
2919014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
2920014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2921014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2922b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::sqrt_d(FPURegister fd, FPURegister fs) {
2923b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  GenInstrRegister(COP1, D, f0, fs, fd, SQRT_D);
2924b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2925b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2926b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2927014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid Assembler::rsqrt_s(FPURegister fd, FPURegister fs) {
2928014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  GenInstrRegister(COP1, S, f0, fs, fd, RSQRT_S);
2929014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
2930014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2931014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2932014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid Assembler::rsqrt_d(FPURegister fd, FPURegister fs) {
2933014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  GenInstrRegister(COP1, D, f0, fs, fd, RSQRT_D);
2934014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
2935b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2936014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2937014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid Assembler::recip_d(FPURegister fd, FPURegister fs) {
2938014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  GenInstrRegister(COP1, D, f0, fs, fd, RECIP_D);
2939014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
2940014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2941014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2942014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid Assembler::recip_s(FPURegister fd, FPURegister fs) {
2943014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  GenInstrRegister(COP1, S, f0, fs, fd, RECIP_S);
2944014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
2945014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2946014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2947014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// Conversions.
2948b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::cvt_w_s(FPURegister fd, FPURegister fs) {
2949b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  GenInstrRegister(COP1, S, f0, fs, fd, CVT_W_S);
2950b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2951b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2952b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2953b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::cvt_w_d(FPURegister fd, FPURegister fs) {
2954b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  GenInstrRegister(COP1, D, f0, fs, fd, CVT_W_D);
2955b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2956b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2957b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2958b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::trunc_w_s(FPURegister fd, FPURegister fs) {
2959b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  GenInstrRegister(COP1, S, f0, fs, fd, TRUNC_W_S);
2960b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2961b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2962b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2963b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::trunc_w_d(FPURegister fd, FPURegister fs) {
2964b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  GenInstrRegister(COP1, D, f0, fs, fd, TRUNC_W_D);
2965b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2966b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2967b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2968b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::round_w_s(FPURegister fd, FPURegister fs) {
2969b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  GenInstrRegister(COP1, S, f0, fs, fd, ROUND_W_S);
2970b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2971b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2972b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2973b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::round_w_d(FPURegister fd, FPURegister fs) {
2974b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  GenInstrRegister(COP1, D, f0, fs, fd, ROUND_W_D);
2975b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2976b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2977b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2978b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::floor_w_s(FPURegister fd, FPURegister fs) {
2979b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  GenInstrRegister(COP1, S, f0, fs, fd, FLOOR_W_S);
2980b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2981b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2982b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2983b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::floor_w_d(FPURegister fd, FPURegister fs) {
2984b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  GenInstrRegister(COP1, D, f0, fs, fd, FLOOR_W_D);
2985b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2986b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2987b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2988b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::ceil_w_s(FPURegister fd, FPURegister fs) {
2989b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  GenInstrRegister(COP1, S, f0, fs, fd, CEIL_W_S);
2990b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2991b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2992b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2993b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::ceil_w_d(FPURegister fd, FPURegister fs) {
2994b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  GenInstrRegister(COP1, D, f0, fs, fd, CEIL_W_D);
2995b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2996b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2997b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2998014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid Assembler::rint_s(FPURegister fd, FPURegister fs) { rint(S, fd, fs); }
2999014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3000014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3001014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid Assembler::rint_d(FPURegister fd, FPURegister fs) { rint(D, fd, fs); }
3002014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3003014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3004014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid Assembler::rint(SecondaryField fmt, FPURegister fd, FPURegister fs) {
3005014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(kArchVariant == kMips64r6);
3006014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  GenInstrRegister(COP1, fmt, f0, fs, fd, RINT);
3007014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
3008014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3009014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3010b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::cvt_l_s(FPURegister fd, FPURegister fs) {
3011014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(kArchVariant == kMips64r2 || kArchVariant == kMips64r6);
3012b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  GenInstrRegister(COP1, S, f0, fs, fd, CVT_L_S);
3013b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
3014b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3015b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3016b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::cvt_l_d(FPURegister fd, FPURegister fs) {
3017014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(kArchVariant == kMips64r2 || kArchVariant == kMips64r6);
3018b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  GenInstrRegister(COP1, D, f0, fs, fd, CVT_L_D);
3019b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
3020b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3021b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3022b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::trunc_l_s(FPURegister fd, FPURegister fs) {
3023014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(kArchVariant == kMips64r2 || kArchVariant == kMips64r6);
3024b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  GenInstrRegister(COP1, S, f0, fs, fd, TRUNC_L_S);
3025b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
3026b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3027b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3028b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::trunc_l_d(FPURegister fd, FPURegister fs) {
3029014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(kArchVariant == kMips64r2 || kArchVariant == kMips64r6);
3030b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  GenInstrRegister(COP1, D, f0, fs, fd, TRUNC_L_D);
3031b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
3032b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3033b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3034b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::round_l_s(FPURegister fd, FPURegister fs) {
3035b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  GenInstrRegister(COP1, S, f0, fs, fd, ROUND_L_S);
3036b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
3037b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3038b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3039b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::round_l_d(FPURegister fd, FPURegister fs) {
3040b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  GenInstrRegister(COP1, D, f0, fs, fd, ROUND_L_D);
3041b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
3042b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3043b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3044b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::floor_l_s(FPURegister fd, FPURegister fs) {
3045b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  GenInstrRegister(COP1, S, f0, fs, fd, FLOOR_L_S);
3046b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
3047b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3048b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3049b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::floor_l_d(FPURegister fd, FPURegister fs) {
3050b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  GenInstrRegister(COP1, D, f0, fs, fd, FLOOR_L_D);
3051b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
3052b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3053b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3054b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::ceil_l_s(FPURegister fd, FPURegister fs) {
3055b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  GenInstrRegister(COP1, S, f0, fs, fd, CEIL_L_S);
3056b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
3057b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3058b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3059b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::ceil_l_d(FPURegister fd, FPURegister fs) {
3060b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  GenInstrRegister(COP1, D, f0, fs, fd, CEIL_L_D);
3061b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
3062b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3063b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3064014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid Assembler::class_s(FPURegister fd, FPURegister fs) {
3065b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(kArchVariant == kMips64r6);
3066014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  GenInstrRegister(COP1, S, f0, fs, fd, CLASS_S);
3067b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
3068b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3069b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3070014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid Assembler::class_d(FPURegister fd, FPURegister fs) {
3071b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(kArchVariant == kMips64r6);
3072014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  GenInstrRegister(COP1, D, f0, fs, fd, CLASS_D);
3073b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
3074b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3075b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3076014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid Assembler::mina(SecondaryField fmt, FPURegister fd, FPURegister fs,
3077014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                     FPURegister ft) {
3078b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(kArchVariant == kMips64r6);
3079b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK((fmt == D) || (fmt == S));
3080014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  GenInstrRegister(COP1, fmt, ft, fs, fd, MINA);
3081b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
3082b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3083b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3084014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid Assembler::maxa(SecondaryField fmt, FPURegister fd, FPURegister fs,
3085014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                     FPURegister ft) {
3086b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(kArchVariant == kMips64r6);
3087b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK((fmt == D) || (fmt == S));
3088b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  GenInstrRegister(COP1, fmt, ft, fs, fd, MAXA);
3089b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
3090b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3091b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3092b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::cvt_s_w(FPURegister fd, FPURegister fs) {
3093b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  GenInstrRegister(COP1, W, f0, fs, fd, CVT_S_W);
3094b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
3095b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3096b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3097b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::cvt_s_l(FPURegister fd, FPURegister fs) {
3098014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(kArchVariant == kMips64r2 || kArchVariant == kMips64r6);
3099b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  GenInstrRegister(COP1, L, f0, fs, fd, CVT_S_L);
3100b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
3101b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3102b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3103b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::cvt_s_d(FPURegister fd, FPURegister fs) {
3104b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  GenInstrRegister(COP1, D, f0, fs, fd, CVT_S_D);
3105b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
3106b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3107b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3108b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::cvt_d_w(FPURegister fd, FPURegister fs) {
3109b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  GenInstrRegister(COP1, W, f0, fs, fd, CVT_D_W);
3110b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
3111b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3112b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3113b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::cvt_d_l(FPURegister fd, FPURegister fs) {
3114014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(kArchVariant == kMips64r2 || kArchVariant == kMips64r6);
3115b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  GenInstrRegister(COP1, L, f0, fs, fd, CVT_D_L);
3116b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
3117b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3118b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3119b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::cvt_d_s(FPURegister fd, FPURegister fs) {
3120b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  GenInstrRegister(COP1, S, f0, fs, fd, CVT_D_S);
3121b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
3122b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3123b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3124b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Conditions for >= MIPSr6.
3125b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::cmp(FPUCondition cond, SecondaryField fmt,
3126b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    FPURegister fd, FPURegister fs, FPURegister ft) {
3127b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(kArchVariant == kMips64r6);
3128b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK((fmt & ~(31 << kRsShift)) == 0);
3129b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Instr instr = COP1 | fmt | ft.code() << kFtShift |
3130b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      fs.code() << kFsShift | fd.code() << kFdShift | (0 << 5) | cond;
3131b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  emit(instr);
3132b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
3133b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3134b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3135014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid Assembler::cmp_s(FPUCondition cond, FPURegister fd, FPURegister fs,
3136014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                      FPURegister ft) {
3137014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  cmp(cond, W, fd, fs, ft);
3138014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
3139014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3140014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid Assembler::cmp_d(FPUCondition cond, FPURegister fd, FPURegister fs,
3141014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                      FPURegister ft) {
3142014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  cmp(cond, L, fd, fs, ft);
3143014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
3144014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3145014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3146b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::bc1eqz(int16_t offset, FPURegister ft) {
3147b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(kArchVariant == kMips64r6);
3148b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Instr instr = COP1 | BC1EQZ | ft.code() << kFtShift | (offset & kImm16Mask);
3149b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  emit(instr);
3150b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
3151b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3152b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3153b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::bc1nez(int16_t offset, FPURegister ft) {
3154b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(kArchVariant == kMips64r6);
3155b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Instr instr = COP1 | BC1NEZ | ft.code() << kFtShift | (offset & kImm16Mask);
3156b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  emit(instr);
3157b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
3158b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3159b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3160b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Conditions for < MIPSr6.
3161b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::c(FPUCondition cond, SecondaryField fmt,
3162b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    FPURegister fs, FPURegister ft, uint16_t cc) {
3163b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(kArchVariant != kMips64r6);
3164b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(is_uint3(cc));
3165014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(fmt == S || fmt == D);
3166b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK((fmt & ~(31 << kRsShift)) == 0);
3167b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Instr instr = COP1 | fmt | ft.code() << kFtShift | fs.code() << kFsShift
3168b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      | cc << 8 | 3 << 4 | cond;
3169b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  emit(instr);
3170b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
3171b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3172b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3173014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid Assembler::c_s(FPUCondition cond, FPURegister fs, FPURegister ft,
3174014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                    uint16_t cc) {
3175014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  c(cond, S, fs, ft, cc);
3176014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
3177014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3178014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3179014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid Assembler::c_d(FPUCondition cond, FPURegister fs, FPURegister ft,
3180014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                    uint16_t cc) {
3181014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  c(cond, D, fs, ft, cc);
3182014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
3183014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3184014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3185b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::fcmp(FPURegister src1, const double src2,
3186b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      FPUCondition cond) {
3187b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(src2 == 0.0);
3188b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  mtc1(zero_reg, f14);
3189b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  cvt_d_w(f14, f14);
3190b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  c(cond, D, src1, f14, 0);
3191b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
3192b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3193b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3194b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::bc1f(int16_t offset, uint16_t cc) {
3195b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(is_uint3(cc));
3196b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Instr instr = COP1 | BC1 | cc << 18 | 0 << 16 | (offset & kImm16Mask);
3197b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  emit(instr);
3198b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
3199b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3200b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3201b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::bc1t(int16_t offset, uint16_t cc) {
3202b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(is_uint3(cc));
3203b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Instr instr = COP1 | BC1 | cc << 18 | 1 << 16 | (offset & kImm16Mask);
3204b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  emit(instr);
3205b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
3206b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3207b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3208014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochint Assembler::RelocateInternalReference(RelocInfo::Mode rmode, byte* pc,
3209014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                         intptr_t pc_delta) {
3210014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (RelocInfo::IsInternalReference(rmode)) {
3211014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    int64_t* p = reinterpret_cast<int64_t*>(pc);
3212014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (*p == kEndOfJumpChain) {
3213014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return 0;  // Number of instructions patched.
3214014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
3215014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    *p += pc_delta;
3216014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return 2;  // Number of instructions patched.
3217b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
3218b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Instr instr = instr_at(pc);
3219014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(RelocInfo::IsInternalReferenceEncoded(rmode));
3220b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (IsLui(instr)) {
3221b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Instr instr_lui = instr_at(pc + 0 * Assembler::kInstrSize);
3222b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Instr instr_ori = instr_at(pc + 1 * Assembler::kInstrSize);
3223b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Instr instr_ori2 = instr_at(pc + 3 * Assembler::kInstrSize);
3224b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(IsOri(instr_ori));
3225b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(IsOri(instr_ori2));
3226b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // TODO(plind): symbolic names for the shifts.
3227b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    int64_t imm = (instr_lui & static_cast<int64_t>(kImm16Mask)) << 48;
3228b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    imm |= (instr_ori & static_cast<int64_t>(kImm16Mask)) << 32;
3229b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    imm |= (instr_ori2 & static_cast<int64_t>(kImm16Mask)) << 16;
3230b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Sign extend address.
3231b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    imm >>= 16;
3232b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3233b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (imm == kEndOfJumpChain) {
3234b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      return 0;  // Number of instructions patched.
3235b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
3236b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    imm += pc_delta;
3237b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK((imm & 3) == 0);
3238b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3239b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    instr_lui &= ~kImm16Mask;
3240b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    instr_ori &= ~kImm16Mask;
3241b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    instr_ori2 &= ~kImm16Mask;
3242b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3243b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    instr_at_put(pc + 0 * Assembler::kInstrSize,
3244b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                 instr_lui | ((imm >> 32) & kImm16Mask));
3245b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    instr_at_put(pc + 1 * Assembler::kInstrSize,
3246b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                 instr_ori | (imm >> 16 & kImm16Mask));
3247b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    instr_at_put(pc + 3 * Assembler::kInstrSize,
3248b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                 instr_ori2 | (imm & kImm16Mask));
3249b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return 4;  // Number of instructions patched.
3250014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  } else if (IsJ(instr) || IsJal(instr)) {
3251014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // Regular j/jal relocation.
3252b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    uint32_t imm28 = (instr & static_cast<int32_t>(kImm26Mask)) << 2;
3253b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    imm28 += pc_delta;
3254b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    imm28 &= kImm28Mask;
3255b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    instr &= ~kImm26Mask;
3256014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    DCHECK((imm28 & 3) == 0);
3257014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    uint32_t imm26 = static_cast<uint32_t>(imm28 >> 2);
3258b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    instr_at_put(pc, instr | (imm26 & kImm26Mask));
3259b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return 1;  // Number of instructions patched.
3260014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  } else {
3261014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    DCHECK(((instr & kJumpRawMask) == kJRawMark) ||
3262014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch           ((instr & kJumpRawMask) == kJalRawMark));
3263014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // Unbox raw offset and emit j/jal.
3264014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    int32_t imm28 = (instr & static_cast<int32_t>(kImm26Mask)) << 2;
3265014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // Sign extend 28-bit offset to 32-bit.
3266014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    imm28 = (imm28 << 4) >> 4;
3267014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    uint64_t target =
3268014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        static_cast<int64_t>(imm28) + reinterpret_cast<uint64_t>(pc);
3269014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    target &= kImm28Mask;
3270014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    DCHECK((imm28 & 3) == 0);
3271014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    uint32_t imm26 = static_cast<uint32_t>(target >> 2);
3272014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // Check markings whether to emit j or jal.
3273014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    uint32_t unbox = (instr & kJRawMark) ? J : JAL;
3274014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    instr_at_put(pc, unbox | (imm26 & kImm26Mask));
3275014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return 1;  // Number of instructions patched.
3276b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
3277b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
3278b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3279b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3280b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::GrowBuffer() {
3281b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (!own_buffer_) FATAL("external code buffer is too small");
3282b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3283b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Compute new buffer size.
3284b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  CodeDesc desc;  // The new buffer.
3285b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (buffer_size_ < 1 * MB) {
3286b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    desc.buffer_size = 2*buffer_size_;
3287b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } else {
3288b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    desc.buffer_size = buffer_size_ + 1*MB;
3289b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
3290b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  CHECK_GT(desc.buffer_size, 0);  // No overflow.
3291b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3292b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Set up new buffer.
3293b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  desc.buffer = NewArray<byte>(desc.buffer_size);
3294014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  desc.origin = this;
3295b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3296b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  desc.instr_size = pc_offset();
3297014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  desc.reloc_size =
3298014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      static_cast<int>((buffer_ + buffer_size_) - reloc_info_writer.pos());
3299b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3300b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Copy the data.
3301b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  intptr_t pc_delta = desc.buffer - buffer_;
3302b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  intptr_t rc_delta = (desc.buffer + desc.buffer_size) -
3303b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      (buffer_ + buffer_size_);
3304b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  MemMove(desc.buffer, buffer_, desc.instr_size);
3305b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  MemMove(reloc_info_writer.pos() + rc_delta,
3306b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch              reloc_info_writer.pos(), desc.reloc_size);
3307b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3308b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Switch buffers.
3309b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DeleteArray(buffer_);
3310b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  buffer_ = desc.buffer;
3311b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  buffer_size_ = desc.buffer_size;
3312b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  pc_ += pc_delta;
3313b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  reloc_info_writer.Reposition(reloc_info_writer.pos() + rc_delta,
3314b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                               reloc_info_writer.last_pc() + pc_delta);
3315b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3316b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Relocate runtime entries.
3317b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  for (RelocIterator it(desc); !it.done(); it.next()) {
3318b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    RelocInfo::Mode rmode = it.rinfo()->rmode();
3319b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (rmode == RelocInfo::INTERNAL_REFERENCE) {
3320b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      byte* p = reinterpret_cast<byte*>(it.rinfo()->pc());
3321014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      RelocateInternalReference(rmode, p, pc_delta);
3322b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
3323b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
3324b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(!overflow());
3325b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
3326b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3327b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3328b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::db(uint8_t data) {
3329014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  CheckForEmitInForbiddenSlot();
3330014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  EmitHelper(data);
3331b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
3332b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3333b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3334b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::dd(uint32_t data) {
3335014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  CheckForEmitInForbiddenSlot();
3336014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  EmitHelper(data);
3337b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
3338b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3339b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3340014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid Assembler::dq(uint64_t data) {
3341014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  CheckForEmitInForbiddenSlot();
3342014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  EmitHelper(data);
3343014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
3344014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3345014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3346014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid Assembler::dd(Label* label) {
3347014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  uint64_t data;
3348014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  CheckForEmitInForbiddenSlot();
3349014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (label->is_bound()) {
3350014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    data = reinterpret_cast<uint64_t>(buffer_ + label->pos());
3351014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  } else {
3352014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    data = jump_address(label);
3353bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    unbound_labels_count_++;
3354014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    internal_reference_positions_.insert(label->pos());
3355014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
3356014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  RecordRelocInfo(RelocInfo::INTERNAL_REFERENCE);
3357014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  EmitHelper(data);
3358b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
3359b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3360b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3361b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::RecordRelocInfo(RelocInfo::Mode rmode, intptr_t data) {
3362b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // We do not try to reuse pool constants.
3363014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  RelocInfo rinfo(isolate(), pc_, rmode, data, NULL);
3364014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (rmode >= RelocInfo::COMMENT &&
33653b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      rmode <= RelocInfo::DEBUG_BREAK_SLOT_AT_TAIL_CALL) {
3366b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Adjust code for new modes.
3367f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    DCHECK(RelocInfo::IsDebugBreakSlot(rmode) || RelocInfo::IsComment(rmode));
3368b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // These modes do not need an entry in the constant pool.
3369b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
3370b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (!RelocInfo::IsNone(rinfo.rmode())) {
3371b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Don't record external references unless the heap will be serialized.
3372b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (rmode == RelocInfo::EXTERNAL_REFERENCE &&
3373b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        !serializer_enabled() && !emit_debug_code()) {
3374b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      return;
3375b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
3376b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(buffer_space() >= kMaxRelocSize);  // Too late to grow buffer here.
3377b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (rmode == RelocInfo::CODE_TARGET_WITH_ID) {
3378014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      RelocInfo reloc_info_with_ast_id(isolate(), pc_, rmode,
3379014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                       RecordedAstId().ToInt(), NULL);
3380b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      ClearRecordedAstId();
3381b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      reloc_info_writer.Write(&reloc_info_with_ast_id);
3382b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    } else {
3383b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      reloc_info_writer.Write(&rinfo);
3384b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
3385b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
3386b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
3387b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3388b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3389b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::BlockTrampolinePoolFor(int instructions) {
3390014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  CheckTrampolinePoolQuick(instructions);
3391b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  BlockTrampolinePoolBefore(pc_offset() + instructions * kInstrSize);
3392b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
3393b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3394b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3395b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::CheckTrampolinePool() {
3396b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Some small sequences of instructions must not be broken up by the
3397b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // insertion of a trampoline pool; such sequences are protected by setting
3398b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // either trampoline_pool_blocked_nesting_ or no_trampoline_pool_before_,
3399b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // which are both checked here. Also, recursive calls to CheckTrampolinePool
3400b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // are blocked by trampoline_pool_blocked_nesting_.
3401b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if ((trampoline_pool_blocked_nesting_ > 0) ||
3402b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      (pc_offset() < no_trampoline_pool_before_)) {
3403b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Emission is currently blocked; make sure we try again as soon as
3404b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // possible.
3405b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (trampoline_pool_blocked_nesting_ > 0) {
3406b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      next_buffer_check_ = pc_offset() + kInstrSize;
3407b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    } else {
3408b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      next_buffer_check_ = no_trampoline_pool_before_;
3409b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
3410b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return;
3411b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
3412b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3413b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(!trampoline_emitted_);
3414b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(unbound_labels_count_ >= 0);
3415b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (unbound_labels_count_ > 0) {
3416b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // First we emit jump (2 instructions), then we emit trampoline pool.
3417b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    { BlockTrampolinePoolScope block_trampoline_pool(this);
3418b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      Label after_pool;
3419014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (kArchVariant == kMips64r6) {
3420014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        bc(&after_pool);
3421014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      } else {
3422014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        b(&after_pool);
3423014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
3424109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      nop();
3425b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3426b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      int pool_start = pc_offset();
3427b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      for (int i = 0; i < unbound_labels_count_; i++) {
3428b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        { BlockGrowBufferScope block_buf_growth(this);
3429b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          // Buffer growth (and relocation) must be blocked for internal
3430b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          // references until associated instructions are emitted and available
3431b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          // to be patched.
3432014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          RecordRelocInfo(RelocInfo::INTERNAL_REFERENCE_ENCODED);
3433014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          j(&after_pool);
3434b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        }
3435b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        nop();
3436b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
3437b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      bind(&after_pool);
3438b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      trampoline_ = Trampoline(pool_start, unbound_labels_count_);
3439b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3440b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      trampoline_emitted_ = true;
3441b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      // As we are only going to emit trampoline once, we need to prevent any
3442b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      // further emission.
3443b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      next_buffer_check_ = kMaxInt;
3444b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
3445b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } else {
3446b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Number of branches to unbound label at this point is zero, so we can
3447b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // move next buffer check to maximum.
3448b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    next_buffer_check_ = pc_offset() +
3449b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        kMaxBranchOffset - kTrampolineSlotsSize * 16;
3450b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
3451b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return;
3452b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
3453b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3454b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3455b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochAddress Assembler::target_address_at(Address pc) {
3456b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Instr instr0 = instr_at(pc);
3457b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Instr instr1 = instr_at(pc + 1 * kInstrSize);
3458b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Instr instr3 = instr_at(pc + 3 * kInstrSize);
3459b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3460b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Interpret 4 instructions for address generated by li: See listing in
3461b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Assembler::set_target_address_at() just below.
3462b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if ((GetOpcodeField(instr0) == LUI) && (GetOpcodeField(instr1) == ORI) &&
3463b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      (GetOpcodeField(instr3) == ORI)) {
3464b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Assemble the 48 bit value.
3465b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch     int64_t addr  = static_cast<int64_t>(
3466b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          ((uint64_t)(GetImmediate16(instr0)) << 32) |
3467b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          ((uint64_t)(GetImmediate16(instr1)) << 16) |
3468b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          ((uint64_t)(GetImmediate16(instr3))));
3469b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3470b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Sign extend to get canonical address.
3471b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    addr = (addr << 16) >> 16;
3472b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return reinterpret_cast<Address>(addr);
3473b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
3474b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // We should never get here, force a bad address if we do.
3475b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  UNREACHABLE();
3476b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return (Address)0x0;
3477b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
3478b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3479b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3480b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// MIPS and ia32 use opposite encoding for qNaN and sNaN, such that ia32
3481b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// qNaN is a MIPS sNaN, and ia32 sNaN is MIPS qNaN. If running from a heap
3482b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// snapshot generated on ia32, the resulting MIPS sNaN must be quieted.
3483b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// OS::nan_value() returns a qNaN.
3484b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::QuietNaN(HeapObject* object) {
3485014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  HeapNumber::cast(object)->set_value(std::numeric_limits<double>::quiet_NaN());
3486b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
3487b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3488b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3489b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// On Mips64, a target address is stored in a 4-instruction sequence:
3490b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch//    0: lui(rd, (j.imm64_ >> 32) & kImm16Mask);
3491b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch//    1: ori(rd, rd, (j.imm64_ >> 16) & kImm16Mask);
3492b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch//    2: dsll(rd, rd, 16);
3493b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch//    3: ori(rd, rd, j.imm32_ & kImm16Mask);
3494b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch//
3495b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Patching the address must replace all the lui & ori instructions,
3496b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// and flush the i-cache.
3497b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch//
3498b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// There is an optimization below, which emits a nop when the address
3499b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// fits in just 16 bits. This is unlikely to help, and should be benchmarked,
3500b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// and possibly removed.
3501014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid Assembler::set_target_address_at(Isolate* isolate, Address pc,
3502b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                      Address target,
3503b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                      ICacheFlushMode icache_flush_mode) {
3504b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// There is an optimization where only 4 instructions are used to load address
3505b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// in code on MIP64 because only 48-bits of address is effectively used.
3506b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// It relies on fact the upper [63:48] bits are not used for virtual address
3507b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// translation and they have to be set according to value of bit 47 in order
3508b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// get canonical address.
3509b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Instr instr1 = instr_at(pc + kInstrSize);
3510b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  uint32_t rt_code = GetRt(instr1);
3511b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  uint32_t* p = reinterpret_cast<uint32_t*>(pc);
3512b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  uint64_t itarget = reinterpret_cast<uint64_t>(target);
3513b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3514b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#ifdef DEBUG
3515b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Check we have the result from a li macro-instruction.
3516b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Instr instr0 = instr_at(pc);
3517b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Instr instr3 = instr_at(pc + kInstrSize * 3);
3518b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  CHECK((GetOpcodeField(instr0) == LUI && GetOpcodeField(instr1) == ORI &&
3519b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch         GetOpcodeField(instr3) == ORI));
3520b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#endif
3521b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3522b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Must use 4 instructions to insure patchable code.
3523b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // lui rt, upper-16.
3524b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // ori rt, rt, lower-16.
3525b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // dsll rt, rt, 16.
3526b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // ori rt rt, lower-16.
3527b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  *p = LUI | (rt_code << kRtShift) | ((itarget >> 32) & kImm16Mask);
3528b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  *(p + 1) = ORI | (rt_code << kRtShift) | (rt_code << kRsShift)
3529b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      | ((itarget >> 16) & kImm16Mask);
3530b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  *(p + 3) = ORI | (rt_code << kRsShift) | (rt_code << kRtShift)
3531b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      | (itarget & kImm16Mask);
3532b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3533b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (icache_flush_mode != SKIP_ICACHE_FLUSH) {
3534014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    Assembler::FlushICache(isolate, pc, 4 * Assembler::kInstrSize);
3535b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
3536b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
3537b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3538014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}  // namespace internal
3539014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}  // namespace v8
3540b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3541b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#endif  // V8_TARGET_ARCH_MIPS64
3542