• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright (c) 1994-2006 Sun Microsystems Inc.
2 // All Rights Reserved.
3 //
4 // Redistribution and use in source and binary forms, with or without
5 // modification, are permitted provided that the following conditions are
6 // met:
7 //
8 // - Redistributions of source code must retain the above copyright notice,
9 // this list of conditions and the following disclaimer.
10 //
11 // - Redistribution in binary form must reproduce the above copyright
12 // notice, this list of conditions and the following disclaimer in the
13 // documentation and/or other materials provided with the distribution.
14 //
15 // - Neither the name of Sun Microsystems or the names of contributors may
16 // be used to endorse or promote products derived from this software without
17 // specific prior written permission.
18 //
19 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
20 // IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
21 // THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
23 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
24 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
25 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
26 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
27 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
28 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
29 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 
31 // The original source code covered by the above license above has been
32 // modified significantly by Google Inc.
33 // Copyright 2012 the V8 project authors. All rights reserved.
34 
35 #ifndef V8_MIPS64_ASSEMBLER_MIPS64_H_
36 #define V8_MIPS64_ASSEMBLER_MIPS64_H_
37 
38 #include <stdio.h>
39 
40 #include <set>
41 
42 #include "src/assembler.h"
43 #include "src/mips64/constants-mips64.h"
44 
45 namespace v8 {
46 namespace internal {
47 
48 // clang-format off
49 #define GENERAL_REGISTERS(V)                              \
50   V(zero_reg)  V(at)  V(v0)  V(v1)  V(a0)  V(a1)  V(a2)  V(a3)  \
51   V(a4)  V(a5)  V(a6)  V(a7)  V(t0)  V(t1)  V(t2)  V(t3)  \
52   V(s0)  V(s1)  V(s2)  V(s3)  V(s4)  V(s5)  V(s6)  V(s7)  V(t8)  V(t9) \
53   V(k0)  V(k1)  V(gp)  V(sp)  V(fp)  V(ra)
54 
55 #define ALLOCATABLE_GENERAL_REGISTERS(V) \
56   V(a0)  V(a1)  V(a2)  V(a3) \
57   V(a4)  V(a5)  V(a6)  V(a7)  V(t0)  V(t1)  V(t2) V(s7) \
58   V(v0)  V(v1)
59 
60 #define DOUBLE_REGISTERS(V)                               \
61   V(f0)  V(f1)  V(f2)  V(f3)  V(f4)  V(f5)  V(f6)  V(f7)  \
62   V(f8)  V(f9)  V(f10) V(f11) V(f12) V(f13) V(f14) V(f15) \
63   V(f16) V(f17) V(f18) V(f19) V(f20) V(f21) V(f22) V(f23) \
64   V(f24) V(f25) V(f26) V(f27) V(f28) V(f29) V(f30) V(f31)
65 
66 #define FLOAT_REGISTERS DOUBLE_REGISTERS
67 #define SIMD128_REGISTERS(V)                              \
68   V(w0)  V(w1)  V(w2)  V(w3)  V(w4)  V(w5)  V(w6)  V(w7)  \
69   V(w8)  V(w9)  V(w10) V(w11) V(w12) V(w13) V(w14) V(w15) \
70   V(w16) V(w17) V(w18) V(w19) V(w20) V(w21) V(w22) V(w23) \
71   V(w24) V(w25) V(w26) V(w27) V(w28) V(w29) V(w30) V(w31)
72 
73 #define ALLOCATABLE_DOUBLE_REGISTERS(V)                   \
74   V(f0)  V(f2)  V(f4)  V(f6)  V(f8)  V(f10) V(f12) V(f14) \
75   V(f16) V(f18) V(f20) V(f22) V(f24) V(f26)
76 // clang-format on
77 
78 // Note that the bit values must match those used in actual instruction
79 // encoding.
80 const int kNumRegs = 32;
81 
82 const RegList kJSCallerSaved = 1 << 2 |   // v0
83                                1 << 3 |   // v1
84                                1 << 4 |   // a0
85                                1 << 5 |   // a1
86                                1 << 6 |   // a2
87                                1 << 7 |   // a3
88                                1 << 8 |   // a4
89                                1 << 9 |   // a5
90                                1 << 10 |  // a6
91                                1 << 11 |  // a7
92                                1 << 12 |  // t0
93                                1 << 13 |  // t1
94                                1 << 14 |  // t2
95                                1 << 15;   // t3
96 
97 const int kNumJSCallerSaved = 14;
98 
99 // Callee-saved registers preserved when switching from C to JavaScript.
100 const RegList kCalleeSaved = 1 << 16 |  // s0
101                              1 << 17 |  // s1
102                              1 << 18 |  // s2
103                              1 << 19 |  // s3
104                              1 << 20 |  // s4
105                              1 << 21 |  // s5
106                              1 << 22 |  // s6 (roots in Javascript code)
107                              1 << 23 |  // s7 (cp in Javascript code)
108                              1 << 30;   // fp/s8
109 
110 const int kNumCalleeSaved = 9;
111 
112 const RegList kCalleeSavedFPU = 1 << 20 |  // f20
113                                 1 << 22 |  // f22
114                                 1 << 24 |  // f24
115                                 1 << 26 |  // f26
116                                 1 << 28 |  // f28
117                                 1 << 30;   // f30
118 
119 const int kNumCalleeSavedFPU = 6;
120 
121 const RegList kCallerSavedFPU = 1 << 0 |   // f0
122                                 1 << 2 |   // f2
123                                 1 << 4 |   // f4
124                                 1 << 6 |   // f6
125                                 1 << 8 |   // f8
126                                 1 << 10 |  // f10
127                                 1 << 12 |  // f12
128                                 1 << 14 |  // f14
129                                 1 << 16 |  // f16
130                                 1 << 18;   // f18
131 
132 // Number of registers for which space is reserved in safepoints. Must be a
133 // multiple of 8.
134 const int kNumSafepointRegisters = 24;
135 
136 // Define the list of registers actually saved at safepoints.
137 // Note that the number of saved registers may be smaller than the reserved
138 // space, i.e. kNumSafepointSavedRegisters <= kNumSafepointRegisters.
139 const RegList kSafepointSavedRegisters = kJSCallerSaved | kCalleeSaved;
140 const int kNumSafepointSavedRegisters = kNumJSCallerSaved + kNumCalleeSaved;
141 
142 const int kUndefIndex = -1;
143 // Map with indexes on stack that corresponds to codes of saved registers.
144 const int kSafepointRegisterStackIndexMap[kNumRegs] = {kUndefIndex,  // zero_reg
145                                                        kUndefIndex,  // at
146                                                        0,            // v0
147                                                        1,            // v1
148                                                        2,            // a0
149                                                        3,            // a1
150                                                        4,            // a2
151                                                        5,            // a3
152                                                        6,            // a4
153                                                        7,            // a5
154                                                        8,            // a6
155                                                        9,            // a7
156                                                        10,           // t0
157                                                        11,           // t1
158                                                        12,           // t2
159                                                        13,           // t3
160                                                        14,           // s0
161                                                        15,           // s1
162                                                        16,           // s2
163                                                        17,           // s3
164                                                        18,           // s4
165                                                        19,           // s5
166                                                        20,           // s6
167                                                        21,           // s7
168                                                        kUndefIndex,  // t8
169                                                        kUndefIndex,  // t9
170                                                        kUndefIndex,  // k0
171                                                        kUndefIndex,  // k1
172                                                        kUndefIndex,  // gp
173                                                        kUndefIndex,  // sp
174                                                        22,           // fp
175                                                        kUndefIndex};
176 
177 // CPU Registers.
178 //
179 // 1) We would prefer to use an enum, but enum values are assignment-
180 // compatible with int, which has caused code-generation bugs.
181 //
182 // 2) We would prefer to use a class instead of a struct but we don't like
183 // the register initialization to depend on the particular initialization
184 // order (which appears to be different on OS X, Linux, and Windows for the
185 // installed versions of C++ we tried). Using a struct permits C-style
186 // "initialization". Also, the Register objects cannot be const as this
187 // forces initialization stubs in MSVC, making us dependent on initialization
188 // order.
189 //
190 // 3) By not using an enum, we are possibly preventing the compiler from
191 // doing certain constant folds, which may significantly reduce the
192 // code generated for some assembly instructions (because they boil down
193 // to a few constants). If this is a problem, we could change the code
194 // such that we use an enum in optimized mode, and the struct in debug
195 // mode. This way we get the compile-time error checking in debug mode
196 // and best performance in optimized code.
197 
198 
199 // -----------------------------------------------------------------------------
200 // Implementation of Register and FPURegister.
201 
202 enum RegisterCode {
203 #define REGISTER_CODE(R) kRegCode_##R,
204   GENERAL_REGISTERS(REGISTER_CODE)
205 #undef REGISTER_CODE
206       kRegAfterLast
207 };
208 
209 class Register : public RegisterBase<Register, kRegAfterLast> {
210  public:
211 #if defined(V8_TARGET_LITTLE_ENDIAN)
212   static constexpr int kMantissaOffset = 0;
213   static constexpr int kExponentOffset = 4;
214 #elif defined(V8_TARGET_BIG_ENDIAN)
215   static constexpr int kMantissaOffset = 4;
216   static constexpr int kExponentOffset = 0;
217 #else
218 #error Unknown endianness
219 #endif
220 
221  private:
222   friend class RegisterBase;
Register(int code)223   explicit constexpr Register(int code) : RegisterBase(code) {}
224 };
225 
226 // s7: context register
227 // s3: scratch register
228 // s4: scratch register 2
229 #define DECLARE_REGISTER(R) \
230   constexpr Register R = Register::from_code<kRegCode_##R>();
231 GENERAL_REGISTERS(DECLARE_REGISTER)
232 #undef DECLARE_REGISTER
233 
234 constexpr Register no_reg = Register::no_reg();
235 
236 int ToNumber(Register reg);
237 
238 Register ToRegister(int num);
239 
240 constexpr bool kPadArguments = false;
241 constexpr bool kSimpleFPAliasing = true;
242 constexpr bool kSimdMaskRegisters = false;
243 
244 enum DoubleRegisterCode {
245 #define REGISTER_CODE(R) kDoubleCode_##R,
246   DOUBLE_REGISTERS(REGISTER_CODE)
247 #undef REGISTER_CODE
248       kDoubleAfterLast
249 };
250 
251 // Coprocessor register.
252 class FPURegister : public RegisterBase<FPURegister, kDoubleAfterLast> {
253  public:
254   // TODO(plind): Warning, inconsistent numbering here. kNumFPURegisters refers
255   // to number of 32-bit FPU regs, but kNumAllocatableRegisters refers to
256   // number of Double regs (64-bit regs, or FPU-reg-pairs).
257 
low()258   FPURegister low() const {
259     // TODO(plind): Create DCHECK for FR=0 mode. This usage suspect for FR=1.
260     // Find low reg of a Double-reg pair, which is the reg itself.
261     DCHECK_EQ(code() % 2, 0);  // Specified Double reg must be even.
262     return FPURegister::from_code(code());
263   }
high()264   FPURegister high() const {
265     // TODO(plind): Create DCHECK for FR=0 mode. This usage illegal in FR=1.
266     // Find high reg of a Doubel-reg pair, which is reg + 1.
267     DCHECK_EQ(code() % 2, 0);  // Specified Double reg must be even.
268     return FPURegister::from_code(code() + 1);
269   }
270 
271  private:
272   friend class RegisterBase;
FPURegister(int code)273   explicit constexpr FPURegister(int code) : RegisterBase(code) {}
274 };
275 
276 enum MSARegisterCode {
277 #define REGISTER_CODE(R) kMsaCode_##R,
278   SIMD128_REGISTERS(REGISTER_CODE)
279 #undef REGISTER_CODE
280       kMsaAfterLast
281 };
282 
283 // MIPS SIMD (MSA) register
284 class MSARegister : public RegisterBase<MSARegister, kMsaAfterLast> {
285   friend class RegisterBase;
MSARegister(int code)286   explicit constexpr MSARegister(int code) : RegisterBase(code) {}
287 };
288 
289 // A few double registers are reserved: one as a scratch register and one to
290 // hold 0.0.
291 //  f28: 0.0
292 //  f30: scratch register.
293 
294 // V8 now supports the O32 ABI, and the FPU Registers are organized as 32
295 // 32-bit registers, f0 through f31. When used as 'double' they are used
296 // in pairs, starting with the even numbered register. So a double operation
297 // on f0 really uses f0 and f1.
298 // (Modern mips hardware also supports 32 64-bit registers, via setting
299 // (privileged) Status Register FR bit to 1. This is used by the N32 ABI,
300 // but it is not in common use. Someday we will want to support this in v8.)
301 
302 // For O32 ABI, Floats and Doubles refer to same set of 32 32-bit registers.
303 typedef FPURegister FloatRegister;
304 
305 typedef FPURegister DoubleRegister;
306 
307 #define DECLARE_DOUBLE_REGISTER(R) \
308   constexpr DoubleRegister R = DoubleRegister::from_code<kDoubleCode_##R>();
309 DOUBLE_REGISTERS(DECLARE_DOUBLE_REGISTER)
310 #undef DECLARE_DOUBLE_REGISTER
311 
312 constexpr DoubleRegister no_freg = DoubleRegister::no_reg();
313 constexpr DoubleRegister no_dreg = DoubleRegister::no_reg();
314 
315 // SIMD registers.
316 typedef MSARegister Simd128Register;
317 
318 #define DECLARE_SIMD128_REGISTER(R) \
319   constexpr Simd128Register R = Simd128Register::from_code<kMsaCode_##R>();
320 SIMD128_REGISTERS(DECLARE_SIMD128_REGISTER)
321 #undef DECLARE_SIMD128_REGISTER
322 
323 const Simd128Register no_msareg = Simd128Register::no_reg();
324 
325 // Register aliases.
326 // cp is assumed to be a callee saved register.
327 constexpr Register kRootRegister = s6;
328 constexpr Register cp = s7;
329 constexpr Register kScratchReg = s3;
330 constexpr Register kScratchReg2 = s4;
331 constexpr DoubleRegister kScratchDoubleReg = f30;
332 constexpr DoubleRegister kDoubleRegZero = f28;
333 // Used on mips64r6 for compare operations.
334 // We use the last non-callee saved odd register for N64 ABI
335 constexpr DoubleRegister kDoubleCompareReg = f23;
336 // MSA zero and scratch regs must have the same numbers as FPU zero and scratch
337 constexpr Simd128Register kSimd128RegZero = w28;
338 constexpr Simd128Register kSimd128ScratchReg = w30;
339 
340 // FPU (coprocessor 1) control registers.
341 // Currently only FCSR (#31) is implemented.
342 struct FPUControlRegister {
is_validFPUControlRegister343   bool is_valid() const { return reg_code == kFCSRRegister; }
isFPUControlRegister344   bool is(FPUControlRegister creg) const { return reg_code == creg.reg_code; }
codeFPUControlRegister345   int code() const {
346     DCHECK(is_valid());
347     return reg_code;
348   }
bitFPUControlRegister349   int bit() const {
350     DCHECK(is_valid());
351     return 1 << reg_code;
352   }
setcodeFPUControlRegister353   void setcode(int f) {
354     reg_code = f;
355     DCHECK(is_valid());
356   }
357   // Unfortunately we can't make this private in a struct.
358   int reg_code;
359 };
360 
361 constexpr FPUControlRegister no_fpucreg = {kInvalidFPUControlRegister};
362 constexpr FPUControlRegister FCSR = {kFCSRRegister};
363 
364 // MSA control registers
365 struct MSAControlRegister {
is_validMSAControlRegister366   bool is_valid() const {
367     return (reg_code == kMSAIRRegister) || (reg_code == kMSACSRRegister);
368   }
isMSAControlRegister369   bool is(MSAControlRegister creg) const { return reg_code == creg.reg_code; }
codeMSAControlRegister370   int code() const {
371     DCHECK(is_valid());
372     return reg_code;
373   }
bitMSAControlRegister374   int bit() const {
375     DCHECK(is_valid());
376     return 1 << reg_code;
377   }
setcodeMSAControlRegister378   void setcode(int f) {
379     reg_code = f;
380     DCHECK(is_valid());
381   }
382   // Unfortunately we can't make this private in a struct.
383   int reg_code;
384 };
385 
386 constexpr MSAControlRegister no_msacreg = {kInvalidMSAControlRegister};
387 constexpr MSAControlRegister MSAIR = {kMSAIRRegister};
388 constexpr MSAControlRegister MSACSR = {kMSACSRRegister};
389 
390 // -----------------------------------------------------------------------------
391 // Machine instruction Operands.
392 constexpr int kSmiShift = kSmiTagSize + kSmiShiftSize;
393 constexpr uint64_t kSmiShiftMask = (1UL << kSmiShift) - 1;
394 // Class Operand represents a shifter operand in data processing instructions.
395 class Operand BASE_EMBEDDED {
396  public:
397   // Immediate.
398   V8_INLINE explicit Operand(int64_t immediate,
399                              RelocInfo::Mode rmode = RelocInfo::NONE)
rm_(no_reg)400       : rm_(no_reg), rmode_(rmode) {
401     value_.immediate = immediate;
402   }
Operand(const ExternalReference & f)403   V8_INLINE explicit Operand(const ExternalReference& f)
404       : rm_(no_reg), rmode_(RelocInfo::EXTERNAL_REFERENCE) {
405     value_.immediate = static_cast<int64_t>(f.address());
406   }
407   V8_INLINE explicit Operand(const char* s);
408   V8_INLINE explicit Operand(Object** opp);
409   V8_INLINE explicit Operand(Context** cpp);
410   explicit Operand(Handle<HeapObject> handle);
Operand(Smi * value)411   V8_INLINE explicit Operand(Smi* value)
412       : rm_(no_reg), rmode_(RelocInfo::NONE) {
413     value_.immediate = reinterpret_cast<intptr_t>(value);
414   }
415 
416   static Operand EmbeddedNumber(double number);  // Smi or HeapNumber.
417   static Operand EmbeddedCode(CodeStub* stub);
418 
419   // Register.
Operand(Register rm)420   V8_INLINE explicit Operand(Register rm) : rm_(rm) {}
421 
422   // Return true if this is a register operand.
423   V8_INLINE bool is_reg() const;
424 
425   inline int64_t immediate() const;
426 
IsImmediate()427   bool IsImmediate() const { return !rm_.is_valid(); }
428 
heap_object_request()429   HeapObjectRequest heap_object_request() const {
430     DCHECK(IsHeapObjectRequest());
431     return value_.heap_object_request;
432   }
433 
IsHeapObjectRequest()434   bool IsHeapObjectRequest() const {
435     DCHECK_IMPLIES(is_heap_object_request_, IsImmediate());
436     DCHECK_IMPLIES(is_heap_object_request_,
437                    rmode_ == RelocInfo::EMBEDDED_OBJECT ||
438                        rmode_ == RelocInfo::CODE_TARGET);
439     return is_heap_object_request_;
440   }
441 
rm()442   Register rm() const { return rm_; }
443 
rmode()444   RelocInfo::Mode rmode() const { return rmode_; }
445 
446  private:
447   Register rm_;
448   union Value {
Value()449     Value() {}
450     HeapObjectRequest heap_object_request;  // if is_heap_object_request_
451     int64_t immediate;                      // otherwise
452   } value_;                                 // valid if rm_ == no_reg
453   bool is_heap_object_request_ = false;
454   RelocInfo::Mode rmode_;
455 
456   friend class Assembler;
457   friend class MacroAssembler;
458 };
459 
460 
461 // On MIPS we have only one addressing mode with base_reg + offset.
462 // Class MemOperand represents a memory operand in load and store instructions.
463 class MemOperand : public Operand {
464  public:
465   // Immediate value attached to offset.
466   enum OffsetAddend {
467     offset_minus_one = -1,
468     offset_zero = 0
469   };
470 
471   explicit MemOperand(Register rn, int32_t offset = 0);
472   explicit MemOperand(Register rn, int32_t unit, int32_t multiplier,
473                       OffsetAddend offset_addend = offset_zero);
offset()474   int32_t offset() const { return offset_; }
475 
OffsetIsInt16Encodable()476   bool OffsetIsInt16Encodable() const {
477     return is_int16(offset_);
478   }
479 
480  private:
481   int32_t offset_;
482 
483   friend class Assembler;
484 };
485 
486 class V8_EXPORT_PRIVATE Assembler : public AssemblerBase {
487  public:
488   // Create an assembler. Instructions and relocation information are emitted
489   // into a buffer, with the instructions starting from the beginning and the
490   // relocation information starting from the end of the buffer. See CodeDesc
491   // for a detailed comment on the layout (globals.h).
492   //
493   // If the provided buffer is nullptr, the assembler allocates and grows its
494   // own buffer, and buffer_size determines the initial buffer size. The buffer
495   // is owned by the assembler and deallocated upon destruction of the
496   // assembler.
497   //
498   // If the provided buffer is not nullptr, the assembler uses the provided
499   // buffer for code generation and assumes its size to be buffer_size. If the
500   // buffer is too small, a fatal error occurs. No deallocation of the buffer is
501   // done upon destruction of the assembler.
502   Assembler(const AssemblerOptions& options, void* buffer, int buffer_size);
~Assembler()503   virtual ~Assembler() { }
504 
505   // GetCode emits any pending (non-emitted) code and fills the descriptor
506   // desc. GetCode() is idempotent; it returns the same result if no other
507   // Assembler functions are invoked in between GetCode() calls.
508   void GetCode(Isolate* isolate, CodeDesc* desc);
509 
510   // Label operations & relative jumps (PPUM Appendix D).
511   //
512   // Takes a branch opcode (cc) and a label (L) and generates
513   // either a backward branch or a forward branch and links it
514   // to the label fixup chain. Usage:
515   //
516   // Label L;    // unbound label
517   // j(cc, &L);  // forward branch to unbound label
518   // bind(&L);   // bind label to the current pc
519   // j(cc, &L);  // backward branch to bound label
520   // bind(&L);   // illegal: a label may be bound only once
521   //
522   // Note: The same Label can be used for forward and backward branches
523   // but it may be bound only once.
524   void bind(Label* L);  // Binds an unbound label L to current code position.
525 
526   enum OffsetSize : int { kOffset26 = 26, kOffset21 = 21, kOffset16 = 16 };
527 
528   // Determines if Label is bound and near enough so that branch instruction
529   // can be used to reach it, instead of jump instruction.
530   bool is_near(Label* L);
531   bool is_near(Label* L, OffsetSize bits);
532   bool is_near_branch(Label* L);
is_near_pre_r6(Label * L)533   inline bool is_near_pre_r6(Label* L) {
534     DCHECK(!(kArchVariant == kMips64r6));
535     return pc_offset() - L->pos() < kMaxBranchOffset - 4 * kInstrSize;
536   }
is_near_r6(Label * L)537   inline bool is_near_r6(Label* L) {
538     DCHECK_EQ(kArchVariant, kMips64r6);
539     return pc_offset() - L->pos() < kMaxCompactBranchOffset - 4 * kInstrSize;
540   }
541 
542   int BranchOffset(Instr instr);
543 
544   // Returns the branch offset to the given label from the current code
545   // position. Links the label to the current position if it is still unbound.
546   // Manages the jump elimination optimization if the second parameter is true.
547   int32_t branch_offset_helper(Label* L, OffsetSize bits);
branch_offset(Label * L)548   inline int32_t branch_offset(Label* L) {
549     return branch_offset_helper(L, OffsetSize::kOffset16);
550   }
branch_offset21(Label * L)551   inline int32_t branch_offset21(Label* L) {
552     return branch_offset_helper(L, OffsetSize::kOffset21);
553   }
branch_offset26(Label * L)554   inline int32_t branch_offset26(Label* L) {
555     return branch_offset_helper(L, OffsetSize::kOffset26);
556   }
shifted_branch_offset(Label * L)557   inline int32_t shifted_branch_offset(Label* L) {
558     return branch_offset(L) >> 2;
559   }
shifted_branch_offset21(Label * L)560   inline int32_t shifted_branch_offset21(Label* L) {
561     return branch_offset21(L) >> 2;
562   }
shifted_branch_offset26(Label * L)563   inline int32_t shifted_branch_offset26(Label* L) {
564     return branch_offset26(L) >> 2;
565   }
566   uint64_t jump_address(Label* L);
567   uint64_t jump_offset(Label* L);
568   uint64_t branch_long_offset(Label* L);
569 
570   // Puts a labels target address at the given position.
571   // The high 8 bits are set to zero.
572   void label_at_put(Label* L, int at_offset);
573 
574   // Read/Modify the code target address in the branch/call instruction at pc.
575   // The isolate argument is unused (and may be nullptr) when skipping flushing.
576   static Address target_address_at(Address pc);
577   V8_INLINE static void set_target_address_at(
578       Address pc, Address target,
579       ICacheFlushMode icache_flush_mode = FLUSH_ICACHE_IF_NEEDED) {
580     set_target_value_at(pc, target, icache_flush_mode);
581   }
582   // On MIPS there is no Constant Pool so we skip that parameter.
target_address_at(Address pc,Address constant_pool)583   V8_INLINE static Address target_address_at(Address pc,
584                                              Address constant_pool) {
585     return target_address_at(pc);
586   }
587   V8_INLINE static void set_target_address_at(
588       Address pc, Address constant_pool, Address target,
589       ICacheFlushMode icache_flush_mode = FLUSH_ICACHE_IF_NEEDED) {
590     set_target_address_at(pc, target, icache_flush_mode);
591   }
592 
593   static void set_target_value_at(
594       Address pc, uint64_t target,
595       ICacheFlushMode icache_flush_mode = FLUSH_ICACHE_IF_NEEDED);
596 
597   // Return the code target address at a call site from the return address
598   // of that call in the instruction stream.
599   inline static Address target_address_from_return_address(Address pc);
600 
601   static void JumpLabelToJumpRegister(Address pc);
602 
603   static void QuietNaN(HeapObject* nan);
604 
605   // This sets the branch destination (which gets loaded at the call address).
606   // This is for calls and branches within generated code.  The serializer
607   // has already deserialized the lui/ori instructions etc.
608   inline static void deserialization_set_special_target_at(
609       Address instruction_payload, Code* code, Address target);
610 
611   // Get the size of the special target encoded at 'instruction_payload'.
612   inline static int deserialization_special_target_size(
613       Address instruction_payload);
614 
615   // This sets the internal reference at the pc.
616   inline static void deserialization_set_target_internal_reference_at(
617       Address pc, Address target,
618       RelocInfo::Mode mode = RelocInfo::INTERNAL_REFERENCE);
619 
620   // Difference between address of current opcode and target address offset.
621   static constexpr int kBranchPCOffset = kInstrSize;
622 
623   // Difference between address of current opcode and target address offset,
624   // when we are generatinga sequence of instructions for long relative PC
625   // branches
626   static constexpr int kLongBranchPCOffset = 3 * kInstrSize;
627 
628   // Adjust ra register in branch delay slot of bal instruction so to skip
629   // instructions not needed after optimization of PIC in
630   // TurboAssembler::BranchAndLink method.
631 
632   static constexpr int kOptimizedBranchAndLinkLongReturnOffset = 4 * kInstrSize;
633 
634   // Here we are patching the address in the LUI/ORI instruction pair.
635   // These values are used in the serialization process and must be zero for
636   // MIPS platform, as Code, Embedded Object or External-reference pointers
637   // are split across two consecutive instructions and don't exist separately
638   // in the code, so the serializer should not step forwards in memory after
639   // a target is resolved and written.
640   static constexpr int kSpecialTargetSize = 0;
641 
642   // Number of consecutive instructions used to store 32bit/64bit constant.
643   // This constant was used in RelocInfo::target_address_address() function
644   // to tell serializer address of the instruction that follows
645   // LUI/ORI instruction pair.
646   static constexpr int kInstructionsFor32BitConstant = 2;
647   static constexpr int kInstructionsFor64BitConstant = 4;
648 
649   // Distance between the instruction referring to the address of the call
650   // target and the return address.
651 #ifdef _MIPS_ARCH_MIPS64R6
652   static constexpr int kCallTargetAddressOffset = 5 * kInstrSize;
653 #else
654   static constexpr int kCallTargetAddressOffset = 6 * kInstrSize;
655 #endif
656 
657   // Difference between address of current opcode and value read from pc
658   // register.
659   static constexpr int kPcLoadDelta = 4;
660 
661   // Max offset for instructions with 16-bit offset field
662   static constexpr int kMaxBranchOffset = (1 << (18 - 1)) - 1;
663 
664   // Max offset for compact branch instructions with 26-bit offset field
665   static constexpr int kMaxCompactBranchOffset = (1 << (28 - 1)) - 1;
666 
667   static constexpr int kTrampolineSlotsSize =
668       kArchVariant == kMips64r6 ? 2 * kInstrSize : 7 * kInstrSize;
669 
GetScratchRegisterList()670   RegList* GetScratchRegisterList() { return &scratch_register_list_; }
671 
672   // ---------------------------------------------------------------------------
673   // Code generation.
674 
675   // Insert the smallest number of nop instructions
676   // possible to align the pc offset to a multiple
677   // of m. m must be a power of 2 (>= 4).
678   void Align(int m);
679   // Insert the smallest number of zero bytes possible to align the pc offset
680   // to a mulitple of m. m must be a power of 2 (>= 2).
681   void DataAlign(int m);
682   // Aligns code to something that's optimal for a jump target for the platform.
683   void CodeTargetAlign();
684 
685   // Different nop operations are used by the code generator to detect certain
686   // states of the generated code.
687   enum NopMarkerTypes {
688     NON_MARKING_NOP = 0,
689     DEBUG_BREAK_NOP,
690     // IC markers.
691     PROPERTY_ACCESS_INLINED,
692     PROPERTY_ACCESS_INLINED_CONTEXT,
693     PROPERTY_ACCESS_INLINED_CONTEXT_DONT_DELETE,
694     // Helper values.
695     LAST_CODE_MARKER,
696     FIRST_IC_MARKER = PROPERTY_ACCESS_INLINED,
697   };
698 
699   // Type == 0 is the default non-marking nop. For mips this is a
700   // sll(zero_reg, zero_reg, 0). We use rt_reg == at for non-zero
701   // marking, to avoid conflict with ssnop and ehb instructions.
702   void nop(unsigned int type = 0) {
703     DCHECK_LT(type, 32);
704     Register nop_rt_reg = (type == 0) ? zero_reg : at;
705     sll(zero_reg, nop_rt_reg, type, true);
706   }
707 
708 
709   // --------Branch-and-jump-instructions----------
710   // We don't use likely variant of instructions.
711   void b(int16_t offset);
b(Label * L)712   inline void b(Label* L) { b(shifted_branch_offset(L)); }
713   void bal(int16_t offset);
bal(Label * L)714   inline void bal(Label* L) { bal(shifted_branch_offset(L)); }
715   void bc(int32_t offset);
bc(Label * L)716   inline void bc(Label* L) { bc(shifted_branch_offset26(L)); }
717   void balc(int32_t offset);
balc(Label * L)718   inline void balc(Label* L) { balc(shifted_branch_offset26(L)); }
719 
720   void beq(Register rs, Register rt, int16_t offset);
beq(Register rs,Register rt,Label * L)721   inline void beq(Register rs, Register rt, Label* L) {
722     beq(rs, rt, shifted_branch_offset(L));
723   }
724   void bgez(Register rs, int16_t offset);
725   void bgezc(Register rt, int16_t offset);
bgezc(Register rt,Label * L)726   inline void bgezc(Register rt, Label* L) {
727     bgezc(rt, shifted_branch_offset(L));
728   }
729   void bgeuc(Register rs, Register rt, int16_t offset);
bgeuc(Register rs,Register rt,Label * L)730   inline void bgeuc(Register rs, Register rt, Label* L) {
731     bgeuc(rs, rt, shifted_branch_offset(L));
732   }
733   void bgec(Register rs, Register rt, int16_t offset);
bgec(Register rs,Register rt,Label * L)734   inline void bgec(Register rs, Register rt, Label* L) {
735     bgec(rs, rt, shifted_branch_offset(L));
736   }
737   void bgezal(Register rs, int16_t offset);
738   void bgezalc(Register rt, int16_t offset);
bgezalc(Register rt,Label * L)739   inline void bgezalc(Register rt, Label* L) {
740     bgezalc(rt, shifted_branch_offset(L));
741   }
742   void bgezall(Register rs, int16_t offset);
bgezall(Register rs,Label * L)743   inline void bgezall(Register rs, Label* L) {
744     bgezall(rs, branch_offset(L) >> 2);
745   }
746   void bgtz(Register rs, int16_t offset);
747   void bgtzc(Register rt, int16_t offset);
bgtzc(Register rt,Label * L)748   inline void bgtzc(Register rt, Label* L) {
749     bgtzc(rt, shifted_branch_offset(L));
750   }
751   void blez(Register rs, int16_t offset);
752   void blezc(Register rt, int16_t offset);
blezc(Register rt,Label * L)753   inline void blezc(Register rt, Label* L) {
754     blezc(rt, shifted_branch_offset(L));
755   }
756   void bltz(Register rs, int16_t offset);
757   void bltzc(Register rt, int16_t offset);
bltzc(Register rt,Label * L)758   inline void bltzc(Register rt, Label* L) {
759     bltzc(rt, shifted_branch_offset(L));
760   }
761   void bltuc(Register rs, Register rt, int16_t offset);
bltuc(Register rs,Register rt,Label * L)762   inline void bltuc(Register rs, Register rt, Label* L) {
763     bltuc(rs, rt, shifted_branch_offset(L));
764   }
765   void bltc(Register rs, Register rt, int16_t offset);
bltc(Register rs,Register rt,Label * L)766   inline void bltc(Register rs, Register rt, Label* L) {
767     bltc(rs, rt, shifted_branch_offset(L));
768   }
769   void bltzal(Register rs, int16_t offset);
nal()770   void nal() { bltzal(zero_reg, 0); }
771   void blezalc(Register rt, int16_t offset);
blezalc(Register rt,Label * L)772   inline void blezalc(Register rt, Label* L) {
773     blezalc(rt, shifted_branch_offset(L));
774   }
775   void bltzalc(Register rt, int16_t offset);
bltzalc(Register rt,Label * L)776   inline void bltzalc(Register rt, Label* L) {
777     bltzalc(rt, shifted_branch_offset(L));
778   }
779   void bgtzalc(Register rt, int16_t offset);
bgtzalc(Register rt,Label * L)780   inline void bgtzalc(Register rt, Label* L) {
781     bgtzalc(rt, shifted_branch_offset(L));
782   }
783   void beqzalc(Register rt, int16_t offset);
beqzalc(Register rt,Label * L)784   inline void beqzalc(Register rt, Label* L) {
785     beqzalc(rt, shifted_branch_offset(L));
786   }
787   void beqc(Register rs, Register rt, int16_t offset);
beqc(Register rs,Register rt,Label * L)788   inline void beqc(Register rs, Register rt, Label* L) {
789     beqc(rs, rt, shifted_branch_offset(L));
790   }
791   void beqzc(Register rs, int32_t offset);
beqzc(Register rs,Label * L)792   inline void beqzc(Register rs, Label* L) {
793     beqzc(rs, shifted_branch_offset21(L));
794   }
795   void bnezalc(Register rt, int16_t offset);
bnezalc(Register rt,Label * L)796   inline void bnezalc(Register rt, Label* L) {
797     bnezalc(rt, shifted_branch_offset(L));
798   }
799   void bnec(Register rs, Register rt, int16_t offset);
bnec(Register rs,Register rt,Label * L)800   inline void bnec(Register rs, Register rt, Label* L) {
801     bnec(rs, rt, shifted_branch_offset(L));
802   }
803   void bnezc(Register rt, int32_t offset);
bnezc(Register rt,Label * L)804   inline void bnezc(Register rt, Label* L) {
805     bnezc(rt, shifted_branch_offset21(L));
806   }
807   void bne(Register rs, Register rt, int16_t offset);
bne(Register rs,Register rt,Label * L)808   inline void bne(Register rs, Register rt, Label* L) {
809     bne(rs, rt, shifted_branch_offset(L));
810   }
811   void bovc(Register rs, Register rt, int16_t offset);
bovc(Register rs,Register rt,Label * L)812   inline void bovc(Register rs, Register rt, Label* L) {
813     bovc(rs, rt, shifted_branch_offset(L));
814   }
815   void bnvc(Register rs, Register rt, int16_t offset);
bnvc(Register rs,Register rt,Label * L)816   inline void bnvc(Register rs, Register rt, Label* L) {
817     bnvc(rs, rt, shifted_branch_offset(L));
818   }
819 
820   // Never use the int16_t b(l)cond version with a branch offset
821   // instead of using the Label* version.
822 
823   // Jump targets must be in the current 256 MB-aligned region. i.e. 28 bits.
824   void j(int64_t target);
825   void jal(int64_t target);
826   void j(Label* target);
827   void jal(Label* target);
828   void jalr(Register rs, Register rd = ra);
829   void jr(Register target);
830   void jic(Register rt, int16_t offset);
831   void jialc(Register rt, int16_t offset);
832 
833 
834   // -------Data-processing-instructions---------
835 
836   // Arithmetic.
837   void addu(Register rd, Register rs, Register rt);
838   void subu(Register rd, Register rs, Register rt);
839 
840   void div(Register rs, Register rt);
841   void divu(Register rs, Register rt);
842   void ddiv(Register rs, Register rt);
843   void ddivu(Register rs, Register rt);
844   void div(Register rd, Register rs, Register rt);
845   void divu(Register rd, Register rs, Register rt);
846   void ddiv(Register rd, Register rs, Register rt);
847   void ddivu(Register rd, Register rs, Register rt);
848   void mod(Register rd, Register rs, Register rt);
849   void modu(Register rd, Register rs, Register rt);
850   void dmod(Register rd, Register rs, Register rt);
851   void dmodu(Register rd, Register rs, Register rt);
852 
853   void mul(Register rd, Register rs, Register rt);
854   void muh(Register rd, Register rs, Register rt);
855   void mulu(Register rd, Register rs, Register rt);
856   void muhu(Register rd, Register rs, Register rt);
857   void mult(Register rs, Register rt);
858   void multu(Register rs, Register rt);
859   void dmul(Register rd, Register rs, Register rt);
860   void dmuh(Register rd, Register rs, Register rt);
861   void dmulu(Register rd, Register rs, Register rt);
862   void dmuhu(Register rd, Register rs, Register rt);
863   void daddu(Register rd, Register rs, Register rt);
864   void dsubu(Register rd, Register rs, Register rt);
865   void dmult(Register rs, Register rt);
866   void dmultu(Register rs, Register rt);
867 
868   void addiu(Register rd, Register rs, int32_t j);
869   void daddiu(Register rd, Register rs, int32_t j);
870 
871   // Logical.
872   void and_(Register rd, Register rs, Register rt);
873   void or_(Register rd, Register rs, Register rt);
874   void xor_(Register rd, Register rs, Register rt);
875   void nor(Register rd, Register rs, Register rt);
876 
877   void andi(Register rd, Register rs, int32_t j);
878   void ori(Register rd, Register rs, int32_t j);
879   void xori(Register rd, Register rs, int32_t j);
880   void lui(Register rd, int32_t j);
881   void aui(Register rt, Register rs, int32_t j);
882   void daui(Register rt, Register rs, int32_t j);
883   void dahi(Register rs, int32_t j);
884   void dati(Register rs, int32_t j);
885 
886   // Shifts.
887   // Please note: sll(zero_reg, zero_reg, x) instructions are reserved as nop
888   // and may cause problems in normal code. coming_from_nop makes sure this
889   // doesn't happen.
890   void sll(Register rd, Register rt, uint16_t sa, bool coming_from_nop = false);
891   void sllv(Register rd, Register rt, Register rs);
892   void srl(Register rd, Register rt, uint16_t sa);
893   void srlv(Register rd, Register rt, Register rs);
894   void sra(Register rt, Register rd, uint16_t sa);
895   void srav(Register rt, Register rd, Register rs);
896   void rotr(Register rd, Register rt, uint16_t sa);
897   void rotrv(Register rd, Register rt, Register rs);
898   void dsll(Register rd, Register rt, uint16_t sa);
899   void dsllv(Register rd, Register rt, Register rs);
900   void dsrl(Register rd, Register rt, uint16_t sa);
901   void dsrlv(Register rd, Register rt, Register rs);
902   void drotr(Register rd, Register rt, uint16_t sa);
903   void drotr32(Register rd, Register rt, uint16_t sa);
904   void drotrv(Register rd, Register rt, Register rs);
905   void dsra(Register rt, Register rd, uint16_t sa);
906   void dsrav(Register rd, Register rt, Register rs);
907   void dsll32(Register rt, Register rd, uint16_t sa);
908   void dsrl32(Register rt, Register rd, uint16_t sa);
909   void dsra32(Register rt, Register rd, uint16_t sa);
910 
911   // ------------Memory-instructions-------------
912 
913   void lb(Register rd, const MemOperand& rs);
914   void lbu(Register rd, const MemOperand& rs);
915   void lh(Register rd, const MemOperand& rs);
916   void lhu(Register rd, const MemOperand& rs);
917   void lw(Register rd, const MemOperand& rs);
918   void lwu(Register rd, const MemOperand& rs);
919   void lwl(Register rd, const MemOperand& rs);
920   void lwr(Register rd, const MemOperand& rs);
921   void sb(Register rd, const MemOperand& rs);
922   void sh(Register rd, const MemOperand& rs);
923   void sw(Register rd, const MemOperand& rs);
924   void swl(Register rd, const MemOperand& rs);
925   void swr(Register rd, const MemOperand& rs);
926   void ldl(Register rd, const MemOperand& rs);
927   void ldr(Register rd, const MemOperand& rs);
928   void sdl(Register rd, const MemOperand& rs);
929   void sdr(Register rd, const MemOperand& rs);
930   void ld(Register rd, const MemOperand& rs);
931   void sd(Register rd, const MemOperand& rs);
932 
933   // ----------Atomic instructions--------------
934 
935   void ll(Register rd, const MemOperand& rs);
936   void sc(Register rd, const MemOperand& rs);
937   void lld(Register rd, const MemOperand& rs);
938   void scd(Register rd, const MemOperand& rs);
939 
940   // ---------PC-Relative-instructions-----------
941 
942   void addiupc(Register rs, int32_t imm19);
943   void lwpc(Register rs, int32_t offset19);
944   void lwupc(Register rs, int32_t offset19);
945   void ldpc(Register rs, int32_t offset18);
946   void auipc(Register rs, int16_t imm16);
947   void aluipc(Register rs, int16_t imm16);
948 
949 
950   // ----------------Prefetch--------------------
951 
952   void pref(int32_t hint, const MemOperand& rs);
953 
954 
955   // -------------Misc-instructions--------------
956 
957   // Break / Trap instructions.
958   void break_(uint32_t code, bool break_as_stop = false);
959   void stop(const char* msg, uint32_t code = kMaxStopCode);
960   void tge(Register rs, Register rt, uint16_t code);
961   void tgeu(Register rs, Register rt, uint16_t code);
962   void tlt(Register rs, Register rt, uint16_t code);
963   void tltu(Register rs, Register rt, uint16_t code);
964   void teq(Register rs, Register rt, uint16_t code);
965   void tne(Register rs, Register rt, uint16_t code);
966 
967   // Memory barrier instruction.
968   void sync();
969 
970   // Move from HI/LO register.
971   void mfhi(Register rd);
972   void mflo(Register rd);
973 
974   // Set on less than.
975   void slt(Register rd, Register rs, Register rt);
976   void sltu(Register rd, Register rs, Register rt);
977   void slti(Register rd, Register rs, int32_t j);
978   void sltiu(Register rd, Register rs, int32_t j);
979 
980   // Conditional move.
981   void movz(Register rd, Register rs, Register rt);
982   void movn(Register rd, Register rs, Register rt);
983   void movt(Register rd, Register rs, uint16_t cc = 0);
984   void movf(Register rd, Register rs, uint16_t cc = 0);
985 
986   void sel(SecondaryField fmt, FPURegister fd, FPURegister fs, FPURegister ft);
987   void sel_s(FPURegister fd, FPURegister fs, FPURegister ft);
988   void sel_d(FPURegister fd, FPURegister fs, FPURegister ft);
989   void seleqz(Register rd, Register rs, Register rt);
990   void seleqz(SecondaryField fmt, FPURegister fd, FPURegister fs,
991               FPURegister ft);
992   void selnez(Register rs, Register rt, Register rd);
993   void selnez(SecondaryField fmt, FPURegister fd, FPURegister fs,
994               FPURegister ft);
995   void seleqz_d(FPURegister fd, FPURegister fs, FPURegister ft);
996   void seleqz_s(FPURegister fd, FPURegister fs, FPURegister ft);
997   void selnez_d(FPURegister fd, FPURegister fs, FPURegister ft);
998   void selnez_s(FPURegister fd, FPURegister fs, FPURegister ft);
999 
1000   void movz_s(FPURegister fd, FPURegister fs, Register rt);
1001   void movz_d(FPURegister fd, FPURegister fs, Register rt);
1002   void movt_s(FPURegister fd, FPURegister fs, uint16_t cc = 0);
1003   void movt_d(FPURegister fd, FPURegister fs, uint16_t cc = 0);
1004   void movf_s(FPURegister fd, FPURegister fs, uint16_t cc = 0);
1005   void movf_d(FPURegister fd, FPURegister fs, uint16_t cc = 0);
1006   void movn_s(FPURegister fd, FPURegister fs, Register rt);
1007   void movn_d(FPURegister fd, FPURegister fs, Register rt);
1008   // Bit twiddling.
1009   void clz(Register rd, Register rs);
1010   void dclz(Register rd, Register rs);
1011   void ins_(Register rt, Register rs, uint16_t pos, uint16_t size);
1012   void ext_(Register rt, Register rs, uint16_t pos, uint16_t size);
1013   void dext_(Register rt, Register rs, uint16_t pos, uint16_t size);
1014   void dextm_(Register rt, Register rs, uint16_t pos, uint16_t size);
1015   void dextu_(Register rt, Register rs, uint16_t pos, uint16_t size);
1016   void dins_(Register rt, Register rs, uint16_t pos, uint16_t size);
1017   void dinsm_(Register rt, Register rs, uint16_t pos, uint16_t size);
1018   void dinsu_(Register rt, Register rs, uint16_t pos, uint16_t size);
1019   void bitswap(Register rd, Register rt);
1020   void dbitswap(Register rd, Register rt);
1021   void align(Register rd, Register rs, Register rt, uint8_t bp);
1022   void dalign(Register rd, Register rs, Register rt, uint8_t bp);
1023 
1024   void wsbh(Register rd, Register rt);
1025   void dsbh(Register rd, Register rt);
1026   void dshd(Register rd, Register rt);
1027   void seh(Register rd, Register rt);
1028   void seb(Register rd, Register rt);
1029 
1030   // --------Coprocessor-instructions----------------
1031 
1032   // Load, store, and move.
1033   void lwc1(FPURegister fd, const MemOperand& src);
1034   void ldc1(FPURegister fd, const MemOperand& src);
1035 
1036   void swc1(FPURegister fs, const MemOperand& dst);
1037   void sdc1(FPURegister fs, const MemOperand& dst);
1038 
1039   void mtc1(Register rt, FPURegister fs);
1040   void mthc1(Register rt, FPURegister fs);
1041   void dmtc1(Register rt, FPURegister fs);
1042 
1043   void mfc1(Register rt, FPURegister fs);
1044   void mfhc1(Register rt, FPURegister fs);
1045   void dmfc1(Register rt, FPURegister fs);
1046 
1047   void ctc1(Register rt, FPUControlRegister fs);
1048   void cfc1(Register rt, FPUControlRegister fs);
1049 
1050   // Arithmetic.
1051   void add_s(FPURegister fd, FPURegister fs, FPURegister ft);
1052   void add_d(FPURegister fd, FPURegister fs, FPURegister ft);
1053   void sub_s(FPURegister fd, FPURegister fs, FPURegister ft);
1054   void sub_d(FPURegister fd, FPURegister fs, FPURegister ft);
1055   void mul_s(FPURegister fd, FPURegister fs, FPURegister ft);
1056   void mul_d(FPURegister fd, FPURegister fs, FPURegister ft);
1057   void madd_s(FPURegister fd, FPURegister fr, FPURegister fs, FPURegister ft);
1058   void madd_d(FPURegister fd, FPURegister fr, FPURegister fs, FPURegister ft);
1059   void msub_s(FPURegister fd, FPURegister fr, FPURegister fs, FPURegister ft);
1060   void msub_d(FPURegister fd, FPURegister fr, FPURegister fs, FPURegister ft);
1061   void maddf_s(FPURegister fd, FPURegister fs, FPURegister ft);
1062   void maddf_d(FPURegister fd, FPURegister fs, FPURegister ft);
1063   void msubf_s(FPURegister fd, FPURegister fs, FPURegister ft);
1064   void msubf_d(FPURegister fd, FPURegister fs, FPURegister ft);
1065   void div_s(FPURegister fd, FPURegister fs, FPURegister ft);
1066   void div_d(FPURegister fd, FPURegister fs, FPURegister ft);
1067   void abs_s(FPURegister fd, FPURegister fs);
1068   void abs_d(FPURegister fd, FPURegister fs);
1069   void mov_d(FPURegister fd, FPURegister fs);
1070   void mov_s(FPURegister fd, FPURegister fs);
1071   void neg_s(FPURegister fd, FPURegister fs);
1072   void neg_d(FPURegister fd, FPURegister fs);
1073   void sqrt_s(FPURegister fd, FPURegister fs);
1074   void sqrt_d(FPURegister fd, FPURegister fs);
1075   void rsqrt_s(FPURegister fd, FPURegister fs);
1076   void rsqrt_d(FPURegister fd, FPURegister fs);
1077   void recip_d(FPURegister fd, FPURegister fs);
1078   void recip_s(FPURegister fd, FPURegister fs);
1079 
1080   // Conversion.
1081   void cvt_w_s(FPURegister fd, FPURegister fs);
1082   void cvt_w_d(FPURegister fd, FPURegister fs);
1083   void trunc_w_s(FPURegister fd, FPURegister fs);
1084   void trunc_w_d(FPURegister fd, FPURegister fs);
1085   void round_w_s(FPURegister fd, FPURegister fs);
1086   void round_w_d(FPURegister fd, FPURegister fs);
1087   void floor_w_s(FPURegister fd, FPURegister fs);
1088   void floor_w_d(FPURegister fd, FPURegister fs);
1089   void ceil_w_s(FPURegister fd, FPURegister fs);
1090   void ceil_w_d(FPURegister fd, FPURegister fs);
1091   void rint_s(FPURegister fd, FPURegister fs);
1092   void rint_d(FPURegister fd, FPURegister fs);
1093   void rint(SecondaryField fmt, FPURegister fd, FPURegister fs);
1094 
1095 
1096   void cvt_l_s(FPURegister fd, FPURegister fs);
1097   void cvt_l_d(FPURegister fd, FPURegister fs);
1098   void trunc_l_s(FPURegister fd, FPURegister fs);
1099   void trunc_l_d(FPURegister fd, FPURegister fs);
1100   void round_l_s(FPURegister fd, FPURegister fs);
1101   void round_l_d(FPURegister fd, FPURegister fs);
1102   void floor_l_s(FPURegister fd, FPURegister fs);
1103   void floor_l_d(FPURegister fd, FPURegister fs);
1104   void ceil_l_s(FPURegister fd, FPURegister fs);
1105   void ceil_l_d(FPURegister fd, FPURegister fs);
1106 
1107   void class_s(FPURegister fd, FPURegister fs);
1108   void class_d(FPURegister fd, FPURegister fs);
1109 
1110   void min(SecondaryField fmt, FPURegister fd, FPURegister fs, FPURegister ft);
1111   void mina(SecondaryField fmt, FPURegister fd, FPURegister fs, FPURegister ft);
1112   void max(SecondaryField fmt, FPURegister fd, FPURegister fs, FPURegister ft);
1113   void maxa(SecondaryField fmt, FPURegister fd, FPURegister fs, FPURegister ft);
1114   void min_s(FPURegister fd, FPURegister fs, FPURegister ft);
1115   void min_d(FPURegister fd, FPURegister fs, FPURegister ft);
1116   void max_s(FPURegister fd, FPURegister fs, FPURegister ft);
1117   void max_d(FPURegister fd, FPURegister fs, FPURegister ft);
1118   void mina_s(FPURegister fd, FPURegister fs, FPURegister ft);
1119   void mina_d(FPURegister fd, FPURegister fs, FPURegister ft);
1120   void maxa_s(FPURegister fd, FPURegister fs, FPURegister ft);
1121   void maxa_d(FPURegister fd, FPURegister fs, FPURegister ft);
1122 
1123   void cvt_s_w(FPURegister fd, FPURegister fs);
1124   void cvt_s_l(FPURegister fd, FPURegister fs);
1125   void cvt_s_d(FPURegister fd, FPURegister fs);
1126 
1127   void cvt_d_w(FPURegister fd, FPURegister fs);
1128   void cvt_d_l(FPURegister fd, FPURegister fs);
1129   void cvt_d_s(FPURegister fd, FPURegister fs);
1130 
1131   // Conditions and branches for MIPSr6.
1132   void cmp(FPUCondition cond, SecondaryField fmt,
1133          FPURegister fd, FPURegister ft, FPURegister fs);
1134   void cmp_s(FPUCondition cond, FPURegister fd, FPURegister fs, FPURegister ft);
1135   void cmp_d(FPUCondition cond, FPURegister fd, FPURegister fs, FPURegister ft);
1136 
1137   void bc1eqz(int16_t offset, FPURegister ft);
bc1eqz(Label * L,FPURegister ft)1138   inline void bc1eqz(Label* L, FPURegister ft) {
1139     bc1eqz(shifted_branch_offset(L), ft);
1140   }
1141   void bc1nez(int16_t offset, FPURegister ft);
bc1nez(Label * L,FPURegister ft)1142   inline void bc1nez(Label* L, FPURegister ft) {
1143     bc1nez(shifted_branch_offset(L), ft);
1144   }
1145 
1146   // Conditions and branches for non MIPSr6.
1147   void c(FPUCondition cond, SecondaryField fmt,
1148          FPURegister ft, FPURegister fs, uint16_t cc = 0);
1149   void c_s(FPUCondition cond, FPURegister ft, FPURegister fs, uint16_t cc = 0);
1150   void c_d(FPUCondition cond, FPURegister ft, FPURegister fs, uint16_t cc = 0);
1151 
1152   void bc1f(int16_t offset, uint16_t cc = 0);
1153   inline void bc1f(Label* L, uint16_t cc = 0) {
1154     bc1f(shifted_branch_offset(L), cc);
1155   }
1156   void bc1t(int16_t offset, uint16_t cc = 0);
1157   inline void bc1t(Label* L, uint16_t cc = 0) {
1158     bc1t(shifted_branch_offset(L), cc);
1159   }
1160   void fcmp(FPURegister src1, const double src2, FPUCondition cond);
1161 
1162   // MSA instructions
1163   void bz_v(MSARegister wt, int16_t offset);
bz_v(MSARegister wt,Label * L)1164   inline void bz_v(MSARegister wt, Label* L) {
1165     bz_v(wt, shifted_branch_offset(L));
1166   }
1167   void bz_b(MSARegister wt, int16_t offset);
bz_b(MSARegister wt,Label * L)1168   inline void bz_b(MSARegister wt, Label* L) {
1169     bz_b(wt, shifted_branch_offset(L));
1170   }
1171   void bz_h(MSARegister wt, int16_t offset);
bz_h(MSARegister wt,Label * L)1172   inline void bz_h(MSARegister wt, Label* L) {
1173     bz_h(wt, shifted_branch_offset(L));
1174   }
1175   void bz_w(MSARegister wt, int16_t offset);
bz_w(MSARegister wt,Label * L)1176   inline void bz_w(MSARegister wt, Label* L) {
1177     bz_w(wt, shifted_branch_offset(L));
1178   }
1179   void bz_d(MSARegister wt, int16_t offset);
bz_d(MSARegister wt,Label * L)1180   inline void bz_d(MSARegister wt, Label* L) {
1181     bz_d(wt, shifted_branch_offset(L));
1182   }
1183   void bnz_v(MSARegister wt, int16_t offset);
bnz_v(MSARegister wt,Label * L)1184   inline void bnz_v(MSARegister wt, Label* L) {
1185     bnz_v(wt, shifted_branch_offset(L));
1186   }
1187   void bnz_b(MSARegister wt, int16_t offset);
bnz_b(MSARegister wt,Label * L)1188   inline void bnz_b(MSARegister wt, Label* L) {
1189     bnz_b(wt, shifted_branch_offset(L));
1190   }
1191   void bnz_h(MSARegister wt, int16_t offset);
bnz_h(MSARegister wt,Label * L)1192   inline void bnz_h(MSARegister wt, Label* L) {
1193     bnz_h(wt, shifted_branch_offset(L));
1194   }
1195   void bnz_w(MSARegister wt, int16_t offset);
bnz_w(MSARegister wt,Label * L)1196   inline void bnz_w(MSARegister wt, Label* L) {
1197     bnz_w(wt, shifted_branch_offset(L));
1198   }
1199   void bnz_d(MSARegister wt, int16_t offset);
bnz_d(MSARegister wt,Label * L)1200   inline void bnz_d(MSARegister wt, Label* L) {
1201     bnz_d(wt, shifted_branch_offset(L));
1202   }
1203 
1204   void ld_b(MSARegister wd, const MemOperand& rs);
1205   void ld_h(MSARegister wd, const MemOperand& rs);
1206   void ld_w(MSARegister wd, const MemOperand& rs);
1207   void ld_d(MSARegister wd, const MemOperand& rs);
1208   void st_b(MSARegister wd, const MemOperand& rs);
1209   void st_h(MSARegister wd, const MemOperand& rs);
1210   void st_w(MSARegister wd, const MemOperand& rs);
1211   void st_d(MSARegister wd, const MemOperand& rs);
1212 
1213   void ldi_b(MSARegister wd, int32_t imm10);
1214   void ldi_h(MSARegister wd, int32_t imm10);
1215   void ldi_w(MSARegister wd, int32_t imm10);
1216   void ldi_d(MSARegister wd, int32_t imm10);
1217 
1218   void addvi_b(MSARegister wd, MSARegister ws, uint32_t imm5);
1219   void addvi_h(MSARegister wd, MSARegister ws, uint32_t imm5);
1220   void addvi_w(MSARegister wd, MSARegister ws, uint32_t imm5);
1221   void addvi_d(MSARegister wd, MSARegister ws, uint32_t imm5);
1222   void subvi_b(MSARegister wd, MSARegister ws, uint32_t imm5);
1223   void subvi_h(MSARegister wd, MSARegister ws, uint32_t imm5);
1224   void subvi_w(MSARegister wd, MSARegister ws, uint32_t imm5);
1225   void subvi_d(MSARegister wd, MSARegister ws, uint32_t imm5);
1226   void maxi_s_b(MSARegister wd, MSARegister ws, uint32_t imm5);
1227   void maxi_s_h(MSARegister wd, MSARegister ws, uint32_t imm5);
1228   void maxi_s_w(MSARegister wd, MSARegister ws, uint32_t imm5);
1229   void maxi_s_d(MSARegister wd, MSARegister ws, uint32_t imm5);
1230   void maxi_u_b(MSARegister wd, MSARegister ws, uint32_t imm5);
1231   void maxi_u_h(MSARegister wd, MSARegister ws, uint32_t imm5);
1232   void maxi_u_w(MSARegister wd, MSARegister ws, uint32_t imm5);
1233   void maxi_u_d(MSARegister wd, MSARegister ws, uint32_t imm5);
1234   void mini_s_b(MSARegister wd, MSARegister ws, uint32_t imm5);
1235   void mini_s_h(MSARegister wd, MSARegister ws, uint32_t imm5);
1236   void mini_s_w(MSARegister wd, MSARegister ws, uint32_t imm5);
1237   void mini_s_d(MSARegister wd, MSARegister ws, uint32_t imm5);
1238   void mini_u_b(MSARegister wd, MSARegister ws, uint32_t imm5);
1239   void mini_u_h(MSARegister wd, MSARegister ws, uint32_t imm5);
1240   void mini_u_w(MSARegister wd, MSARegister ws, uint32_t imm5);
1241   void mini_u_d(MSARegister wd, MSARegister ws, uint32_t imm5);
1242   void ceqi_b(MSARegister wd, MSARegister ws, uint32_t imm5);
1243   void ceqi_h(MSARegister wd, MSARegister ws, uint32_t imm5);
1244   void ceqi_w(MSARegister wd, MSARegister ws, uint32_t imm5);
1245   void ceqi_d(MSARegister wd, MSARegister ws, uint32_t imm5);
1246   void clti_s_b(MSARegister wd, MSARegister ws, uint32_t imm5);
1247   void clti_s_h(MSARegister wd, MSARegister ws, uint32_t imm5);
1248   void clti_s_w(MSARegister wd, MSARegister ws, uint32_t imm5);
1249   void clti_s_d(MSARegister wd, MSARegister ws, uint32_t imm5);
1250   void clti_u_b(MSARegister wd, MSARegister ws, uint32_t imm5);
1251   void clti_u_h(MSARegister wd, MSARegister ws, uint32_t imm5);
1252   void clti_u_w(MSARegister wd, MSARegister ws, uint32_t imm5);
1253   void clti_u_d(MSARegister wd, MSARegister ws, uint32_t imm5);
1254   void clei_s_b(MSARegister wd, MSARegister ws, uint32_t imm5);
1255   void clei_s_h(MSARegister wd, MSARegister ws, uint32_t imm5);
1256   void clei_s_w(MSARegister wd, MSARegister ws, uint32_t imm5);
1257   void clei_s_d(MSARegister wd, MSARegister ws, uint32_t imm5);
1258   void clei_u_b(MSARegister wd, MSARegister ws, uint32_t imm5);
1259   void clei_u_h(MSARegister wd, MSARegister ws, uint32_t imm5);
1260   void clei_u_w(MSARegister wd, MSARegister ws, uint32_t imm5);
1261   void clei_u_d(MSARegister wd, MSARegister ws, uint32_t imm5);
1262 
1263   void andi_b(MSARegister wd, MSARegister ws, uint32_t imm8);
1264   void ori_b(MSARegister wd, MSARegister ws, uint32_t imm8);
1265   void nori_b(MSARegister wd, MSARegister ws, uint32_t imm8);
1266   void xori_b(MSARegister wd, MSARegister ws, uint32_t imm8);
1267   void bmnzi_b(MSARegister wd, MSARegister ws, uint32_t imm8);
1268   void bmzi_b(MSARegister wd, MSARegister ws, uint32_t imm8);
1269   void bseli_b(MSARegister wd, MSARegister ws, uint32_t imm8);
1270   void shf_b(MSARegister wd, MSARegister ws, uint32_t imm8);
1271   void shf_h(MSARegister wd, MSARegister ws, uint32_t imm8);
1272   void shf_w(MSARegister wd, MSARegister ws, uint32_t imm8);
1273 
1274   void and_v(MSARegister wd, MSARegister ws, MSARegister wt);
1275   void or_v(MSARegister wd, MSARegister ws, MSARegister wt);
1276   void nor_v(MSARegister wd, MSARegister ws, MSARegister wt);
1277   void xor_v(MSARegister wd, MSARegister ws, MSARegister wt);
1278   void bmnz_v(MSARegister wd, MSARegister ws, MSARegister wt);
1279   void bmz_v(MSARegister wd, MSARegister ws, MSARegister wt);
1280   void bsel_v(MSARegister wd, MSARegister ws, MSARegister wt);
1281 
1282   void fill_b(MSARegister wd, Register rs);
1283   void fill_h(MSARegister wd, Register rs);
1284   void fill_w(MSARegister wd, Register rs);
1285   void fill_d(MSARegister wd, Register rs);
1286   void pcnt_b(MSARegister wd, MSARegister ws);
1287   void pcnt_h(MSARegister wd, MSARegister ws);
1288   void pcnt_w(MSARegister wd, MSARegister ws);
1289   void pcnt_d(MSARegister wd, MSARegister ws);
1290   void nloc_b(MSARegister wd, MSARegister ws);
1291   void nloc_h(MSARegister wd, MSARegister ws);
1292   void nloc_w(MSARegister wd, MSARegister ws);
1293   void nloc_d(MSARegister wd, MSARegister ws);
1294   void nlzc_b(MSARegister wd, MSARegister ws);
1295   void nlzc_h(MSARegister wd, MSARegister ws);
1296   void nlzc_w(MSARegister wd, MSARegister ws);
1297   void nlzc_d(MSARegister wd, MSARegister ws);
1298 
1299   void fclass_w(MSARegister wd, MSARegister ws);
1300   void fclass_d(MSARegister wd, MSARegister ws);
1301   void ftrunc_s_w(MSARegister wd, MSARegister ws);
1302   void ftrunc_s_d(MSARegister wd, MSARegister ws);
1303   void ftrunc_u_w(MSARegister wd, MSARegister ws);
1304   void ftrunc_u_d(MSARegister wd, MSARegister ws);
1305   void fsqrt_w(MSARegister wd, MSARegister ws);
1306   void fsqrt_d(MSARegister wd, MSARegister ws);
1307   void frsqrt_w(MSARegister wd, MSARegister ws);
1308   void frsqrt_d(MSARegister wd, MSARegister ws);
1309   void frcp_w(MSARegister wd, MSARegister ws);
1310   void frcp_d(MSARegister wd, MSARegister ws);
1311   void frint_w(MSARegister wd, MSARegister ws);
1312   void frint_d(MSARegister wd, MSARegister ws);
1313   void flog2_w(MSARegister wd, MSARegister ws);
1314   void flog2_d(MSARegister wd, MSARegister ws);
1315   void fexupl_w(MSARegister wd, MSARegister ws);
1316   void fexupl_d(MSARegister wd, MSARegister ws);
1317   void fexupr_w(MSARegister wd, MSARegister ws);
1318   void fexupr_d(MSARegister wd, MSARegister ws);
1319   void ffql_w(MSARegister wd, MSARegister ws);
1320   void ffql_d(MSARegister wd, MSARegister ws);
1321   void ffqr_w(MSARegister wd, MSARegister ws);
1322   void ffqr_d(MSARegister wd, MSARegister ws);
1323   void ftint_s_w(MSARegister wd, MSARegister ws);
1324   void ftint_s_d(MSARegister wd, MSARegister ws);
1325   void ftint_u_w(MSARegister wd, MSARegister ws);
1326   void ftint_u_d(MSARegister wd, MSARegister ws);
1327   void ffint_s_w(MSARegister wd, MSARegister ws);
1328   void ffint_s_d(MSARegister wd, MSARegister ws);
1329   void ffint_u_w(MSARegister wd, MSARegister ws);
1330   void ffint_u_d(MSARegister wd, MSARegister ws);
1331 
1332   void sll_b(MSARegister wd, MSARegister ws, MSARegister wt);
1333   void sll_h(MSARegister wd, MSARegister ws, MSARegister wt);
1334   void sll_w(MSARegister wd, MSARegister ws, MSARegister wt);
1335   void sll_d(MSARegister wd, MSARegister ws, MSARegister wt);
1336   void sra_b(MSARegister wd, MSARegister ws, MSARegister wt);
1337   void sra_h(MSARegister wd, MSARegister ws, MSARegister wt);
1338   void sra_w(MSARegister wd, MSARegister ws, MSARegister wt);
1339   void sra_d(MSARegister wd, MSARegister ws, MSARegister wt);
1340   void srl_b(MSARegister wd, MSARegister ws, MSARegister wt);
1341   void srl_h(MSARegister wd, MSARegister ws, MSARegister wt);
1342   void srl_w(MSARegister wd, MSARegister ws, MSARegister wt);
1343   void srl_d(MSARegister wd, MSARegister ws, MSARegister wt);
1344   void bclr_b(MSARegister wd, MSARegister ws, MSARegister wt);
1345   void bclr_h(MSARegister wd, MSARegister ws, MSARegister wt);
1346   void bclr_w(MSARegister wd, MSARegister ws, MSARegister wt);
1347   void bclr_d(MSARegister wd, MSARegister ws, MSARegister wt);
1348   void bset_b(MSARegister wd, MSARegister ws, MSARegister wt);
1349   void bset_h(MSARegister wd, MSARegister ws, MSARegister wt);
1350   void bset_w(MSARegister wd, MSARegister ws, MSARegister wt);
1351   void bset_d(MSARegister wd, MSARegister ws, MSARegister wt);
1352   void bneg_b(MSARegister wd, MSARegister ws, MSARegister wt);
1353   void bneg_h(MSARegister wd, MSARegister ws, MSARegister wt);
1354   void bneg_w(MSARegister wd, MSARegister ws, MSARegister wt);
1355   void bneg_d(MSARegister wd, MSARegister ws, MSARegister wt);
1356   void binsl_b(MSARegister wd, MSARegister ws, MSARegister wt);
1357   void binsl_h(MSARegister wd, MSARegister ws, MSARegister wt);
1358   void binsl_w(MSARegister wd, MSARegister ws, MSARegister wt);
1359   void binsl_d(MSARegister wd, MSARegister ws, MSARegister wt);
1360   void binsr_b(MSARegister wd, MSARegister ws, MSARegister wt);
1361   void binsr_h(MSARegister wd, MSARegister ws, MSARegister wt);
1362   void binsr_w(MSARegister wd, MSARegister ws, MSARegister wt);
1363   void binsr_d(MSARegister wd, MSARegister ws, MSARegister wt);
1364   void addv_b(MSARegister wd, MSARegister ws, MSARegister wt);
1365   void addv_h(MSARegister wd, MSARegister ws, MSARegister wt);
1366   void addv_w(MSARegister wd, MSARegister ws, MSARegister wt);
1367   void addv_d(MSARegister wd, MSARegister ws, MSARegister wt);
1368   void subv_b(MSARegister wd, MSARegister ws, MSARegister wt);
1369   void subv_h(MSARegister wd, MSARegister ws, MSARegister wt);
1370   void subv_w(MSARegister wd, MSARegister ws, MSARegister wt);
1371   void subv_d(MSARegister wd, MSARegister ws, MSARegister wt);
1372   void max_s_b(MSARegister wd, MSARegister ws, MSARegister wt);
1373   void max_s_h(MSARegister wd, MSARegister ws, MSARegister wt);
1374   void max_s_w(MSARegister wd, MSARegister ws, MSARegister wt);
1375   void max_s_d(MSARegister wd, MSARegister ws, MSARegister wt);
1376   void max_u_b(MSARegister wd, MSARegister ws, MSARegister wt);
1377   void max_u_h(MSARegister wd, MSARegister ws, MSARegister wt);
1378   void max_u_w(MSARegister wd, MSARegister ws, MSARegister wt);
1379   void max_u_d(MSARegister wd, MSARegister ws, MSARegister wt);
1380   void min_s_b(MSARegister wd, MSARegister ws, MSARegister wt);
1381   void min_s_h(MSARegister wd, MSARegister ws, MSARegister wt);
1382   void min_s_w(MSARegister wd, MSARegister ws, MSARegister wt);
1383   void min_s_d(MSARegister wd, MSARegister ws, MSARegister wt);
1384   void min_u_b(MSARegister wd, MSARegister ws, MSARegister wt);
1385   void min_u_h(MSARegister wd, MSARegister ws, MSARegister wt);
1386   void min_u_w(MSARegister wd, MSARegister ws, MSARegister wt);
1387   void min_u_d(MSARegister wd, MSARegister ws, MSARegister wt);
1388   void max_a_b(MSARegister wd, MSARegister ws, MSARegister wt);
1389   void max_a_h(MSARegister wd, MSARegister ws, MSARegister wt);
1390   void max_a_w(MSARegister wd, MSARegister ws, MSARegister wt);
1391   void max_a_d(MSARegister wd, MSARegister ws, MSARegister wt);
1392   void min_a_b(MSARegister wd, MSARegister ws, MSARegister wt);
1393   void min_a_h(MSARegister wd, MSARegister ws, MSARegister wt);
1394   void min_a_w(MSARegister wd, MSARegister ws, MSARegister wt);
1395   void min_a_d(MSARegister wd, MSARegister ws, MSARegister wt);
1396   void ceq_b(MSARegister wd, MSARegister ws, MSARegister wt);
1397   void ceq_h(MSARegister wd, MSARegister ws, MSARegister wt);
1398   void ceq_w(MSARegister wd, MSARegister ws, MSARegister wt);
1399   void ceq_d(MSARegister wd, MSARegister ws, MSARegister wt);
1400   void clt_s_b(MSARegister wd, MSARegister ws, MSARegister wt);
1401   void clt_s_h(MSARegister wd, MSARegister ws, MSARegister wt);
1402   void clt_s_w(MSARegister wd, MSARegister ws, MSARegister wt);
1403   void clt_s_d(MSARegister wd, MSARegister ws, MSARegister wt);
1404   void clt_u_b(MSARegister wd, MSARegister ws, MSARegister wt);
1405   void clt_u_h(MSARegister wd, MSARegister ws, MSARegister wt);
1406   void clt_u_w(MSARegister wd, MSARegister ws, MSARegister wt);
1407   void clt_u_d(MSARegister wd, MSARegister ws, MSARegister wt);
1408   void cle_s_b(MSARegister wd, MSARegister ws, MSARegister wt);
1409   void cle_s_h(MSARegister wd, MSARegister ws, MSARegister wt);
1410   void cle_s_w(MSARegister wd, MSARegister ws, MSARegister wt);
1411   void cle_s_d(MSARegister wd, MSARegister ws, MSARegister wt);
1412   void cle_u_b(MSARegister wd, MSARegister ws, MSARegister wt);
1413   void cle_u_h(MSARegister wd, MSARegister ws, MSARegister wt);
1414   void cle_u_w(MSARegister wd, MSARegister ws, MSARegister wt);
1415   void cle_u_d(MSARegister wd, MSARegister ws, MSARegister wt);
1416   void add_a_b(MSARegister wd, MSARegister ws, MSARegister wt);
1417   void add_a_h(MSARegister wd, MSARegister ws, MSARegister wt);
1418   void add_a_w(MSARegister wd, MSARegister ws, MSARegister wt);
1419   void add_a_d(MSARegister wd, MSARegister ws, MSARegister wt);
1420   void adds_a_b(MSARegister wd, MSARegister ws, MSARegister wt);
1421   void adds_a_h(MSARegister wd, MSARegister ws, MSARegister wt);
1422   void adds_a_w(MSARegister wd, MSARegister ws, MSARegister wt);
1423   void adds_a_d(MSARegister wd, MSARegister ws, MSARegister wt);
1424   void adds_s_b(MSARegister wd, MSARegister ws, MSARegister wt);
1425   void adds_s_h(MSARegister wd, MSARegister ws, MSARegister wt);
1426   void adds_s_w(MSARegister wd, MSARegister ws, MSARegister wt);
1427   void adds_s_d(MSARegister wd, MSARegister ws, MSARegister wt);
1428   void adds_u_b(MSARegister wd, MSARegister ws, MSARegister wt);
1429   void adds_u_h(MSARegister wd, MSARegister ws, MSARegister wt);
1430   void adds_u_w(MSARegister wd, MSARegister ws, MSARegister wt);
1431   void adds_u_d(MSARegister wd, MSARegister ws, MSARegister wt);
1432   void ave_s_b(MSARegister wd, MSARegister ws, MSARegister wt);
1433   void ave_s_h(MSARegister wd, MSARegister ws, MSARegister wt);
1434   void ave_s_w(MSARegister wd, MSARegister ws, MSARegister wt);
1435   void ave_s_d(MSARegister wd, MSARegister ws, MSARegister wt);
1436   void ave_u_b(MSARegister wd, MSARegister ws, MSARegister wt);
1437   void ave_u_h(MSARegister wd, MSARegister ws, MSARegister wt);
1438   void ave_u_w(MSARegister wd, MSARegister ws, MSARegister wt);
1439   void ave_u_d(MSARegister wd, MSARegister ws, MSARegister wt);
1440   void aver_s_b(MSARegister wd, MSARegister ws, MSARegister wt);
1441   void aver_s_h(MSARegister wd, MSARegister ws, MSARegister wt);
1442   void aver_s_w(MSARegister wd, MSARegister ws, MSARegister wt);
1443   void aver_s_d(MSARegister wd, MSARegister ws, MSARegister wt);
1444   void aver_u_b(MSARegister wd, MSARegister ws, MSARegister wt);
1445   void aver_u_h(MSARegister wd, MSARegister ws, MSARegister wt);
1446   void aver_u_w(MSARegister wd, MSARegister ws, MSARegister wt);
1447   void aver_u_d(MSARegister wd, MSARegister ws, MSARegister wt);
1448   void subs_s_b(MSARegister wd, MSARegister ws, MSARegister wt);
1449   void subs_s_h(MSARegister wd, MSARegister ws, MSARegister wt);
1450   void subs_s_w(MSARegister wd, MSARegister ws, MSARegister wt);
1451   void subs_s_d(MSARegister wd, MSARegister ws, MSARegister wt);
1452   void subs_u_b(MSARegister wd, MSARegister ws, MSARegister wt);
1453   void subs_u_h(MSARegister wd, MSARegister ws, MSARegister wt);
1454   void subs_u_w(MSARegister wd, MSARegister ws, MSARegister wt);
1455   void subs_u_d(MSARegister wd, MSARegister ws, MSARegister wt);
1456   void subsus_u_b(MSARegister wd, MSARegister ws, MSARegister wt);
1457   void subsus_u_h(MSARegister wd, MSARegister ws, MSARegister wt);
1458   void subsus_u_w(MSARegister wd, MSARegister ws, MSARegister wt);
1459   void subsus_u_d(MSARegister wd, MSARegister ws, MSARegister wt);
1460   void subsus_s_b(MSARegister wd, MSARegister ws, MSARegister wt);
1461   void subsus_s_h(MSARegister wd, MSARegister ws, MSARegister wt);
1462   void subsus_s_w(MSARegister wd, MSARegister ws, MSARegister wt);
1463   void subsus_s_d(MSARegister wd, MSARegister ws, MSARegister wt);
1464   void subsuu_u_b(MSARegister wd, MSARegister ws, MSARegister wt);
1465   void subsuu_u_h(MSARegister wd, MSARegister ws, MSARegister wt);
1466   void subsuu_u_w(MSARegister wd, MSARegister ws, MSARegister wt);
1467   void subsuu_u_d(MSARegister wd, MSARegister ws, MSARegister wt);
1468   void subsuu_s_b(MSARegister wd, MSARegister ws, MSARegister wt);
1469   void subsuu_s_h(MSARegister wd, MSARegister ws, MSARegister wt);
1470   void subsuu_s_w(MSARegister wd, MSARegister ws, MSARegister wt);
1471   void subsuu_s_d(MSARegister wd, MSARegister ws, MSARegister wt);
1472   void asub_s_b(MSARegister wd, MSARegister ws, MSARegister wt);
1473   void asub_s_h(MSARegister wd, MSARegister ws, MSARegister wt);
1474   void asub_s_w(MSARegister wd, MSARegister ws, MSARegister wt);
1475   void asub_s_d(MSARegister wd, MSARegister ws, MSARegister wt);
1476   void asub_u_b(MSARegister wd, MSARegister ws, MSARegister wt);
1477   void asub_u_h(MSARegister wd, MSARegister ws, MSARegister wt);
1478   void asub_u_w(MSARegister wd, MSARegister ws, MSARegister wt);
1479   void asub_u_d(MSARegister wd, MSARegister ws, MSARegister wt);
1480   void mulv_b(MSARegister wd, MSARegister ws, MSARegister wt);
1481   void mulv_h(MSARegister wd, MSARegister ws, MSARegister wt);
1482   void mulv_w(MSARegister wd, MSARegister ws, MSARegister wt);
1483   void mulv_d(MSARegister wd, MSARegister ws, MSARegister wt);
1484   void maddv_b(MSARegister wd, MSARegister ws, MSARegister wt);
1485   void maddv_h(MSARegister wd, MSARegister ws, MSARegister wt);
1486   void maddv_w(MSARegister wd, MSARegister ws, MSARegister wt);
1487   void maddv_d(MSARegister wd, MSARegister ws, MSARegister wt);
1488   void msubv_b(MSARegister wd, MSARegister ws, MSARegister wt);
1489   void msubv_h(MSARegister wd, MSARegister ws, MSARegister wt);
1490   void msubv_w(MSARegister wd, MSARegister ws, MSARegister wt);
1491   void msubv_d(MSARegister wd, MSARegister ws, MSARegister wt);
1492   void div_s_b(MSARegister wd, MSARegister ws, MSARegister wt);
1493   void div_s_h(MSARegister wd, MSARegister ws, MSARegister wt);
1494   void div_s_w(MSARegister wd, MSARegister ws, MSARegister wt);
1495   void div_s_d(MSARegister wd, MSARegister ws, MSARegister wt);
1496   void div_u_b(MSARegister wd, MSARegister ws, MSARegister wt);
1497   void div_u_h(MSARegister wd, MSARegister ws, MSARegister wt);
1498   void div_u_w(MSARegister wd, MSARegister ws, MSARegister wt);
1499   void div_u_d(MSARegister wd, MSARegister ws, MSARegister wt);
1500   void mod_s_b(MSARegister wd, MSARegister ws, MSARegister wt);
1501   void mod_s_h(MSARegister wd, MSARegister ws, MSARegister wt);
1502   void mod_s_w(MSARegister wd, MSARegister ws, MSARegister wt);
1503   void mod_s_d(MSARegister wd, MSARegister ws, MSARegister wt);
1504   void mod_u_b(MSARegister wd, MSARegister ws, MSARegister wt);
1505   void mod_u_h(MSARegister wd, MSARegister ws, MSARegister wt);
1506   void mod_u_w(MSARegister wd, MSARegister ws, MSARegister wt);
1507   void mod_u_d(MSARegister wd, MSARegister ws, MSARegister wt);
1508   void dotp_s_b(MSARegister wd, MSARegister ws, MSARegister wt);
1509   void dotp_s_h(MSARegister wd, MSARegister ws, MSARegister wt);
1510   void dotp_s_w(MSARegister wd, MSARegister ws, MSARegister wt);
1511   void dotp_s_d(MSARegister wd, MSARegister ws, MSARegister wt);
1512   void dotp_u_b(MSARegister wd, MSARegister ws, MSARegister wt);
1513   void dotp_u_h(MSARegister wd, MSARegister ws, MSARegister wt);
1514   void dotp_u_w(MSARegister wd, MSARegister ws, MSARegister wt);
1515   void dotp_u_d(MSARegister wd, MSARegister ws, MSARegister wt);
1516   void dpadd_s_b(MSARegister wd, MSARegister ws, MSARegister wt);
1517   void dpadd_s_h(MSARegister wd, MSARegister ws, MSARegister wt);
1518   void dpadd_s_w(MSARegister wd, MSARegister ws, MSARegister wt);
1519   void dpadd_s_d(MSARegister wd, MSARegister ws, MSARegister wt);
1520   void dpadd_u_b(MSARegister wd, MSARegister ws, MSARegister wt);
1521   void dpadd_u_h(MSARegister wd, MSARegister ws, MSARegister wt);
1522   void dpadd_u_w(MSARegister wd, MSARegister ws, MSARegister wt);
1523   void dpadd_u_d(MSARegister wd, MSARegister ws, MSARegister wt);
1524   void dpsub_s_b(MSARegister wd, MSARegister ws, MSARegister wt);
1525   void dpsub_s_h(MSARegister wd, MSARegister ws, MSARegister wt);
1526   void dpsub_s_w(MSARegister wd, MSARegister ws, MSARegister wt);
1527   void dpsub_s_d(MSARegister wd, MSARegister ws, MSARegister wt);
1528   void dpsub_u_b(MSARegister wd, MSARegister ws, MSARegister wt);
1529   void dpsub_u_h(MSARegister wd, MSARegister ws, MSARegister wt);
1530   void dpsub_u_w(MSARegister wd, MSARegister ws, MSARegister wt);
1531   void dpsub_u_d(MSARegister wd, MSARegister ws, MSARegister wt);
1532   void sld_b(MSARegister wd, MSARegister ws, Register rt);
1533   void sld_h(MSARegister wd, MSARegister ws, Register rt);
1534   void sld_w(MSARegister wd, MSARegister ws, Register rt);
1535   void sld_d(MSARegister wd, MSARegister ws, Register rt);
1536   void splat_b(MSARegister wd, MSARegister ws, Register rt);
1537   void splat_h(MSARegister wd, MSARegister ws, Register rt);
1538   void splat_w(MSARegister wd, MSARegister ws, Register rt);
1539   void splat_d(MSARegister wd, MSARegister ws, Register rt);
1540   void pckev_b(MSARegister wd, MSARegister ws, MSARegister wt);
1541   void pckev_h(MSARegister wd, MSARegister ws, MSARegister wt);
1542   void pckev_w(MSARegister wd, MSARegister ws, MSARegister wt);
1543   void pckev_d(MSARegister wd, MSARegister ws, MSARegister wt);
1544   void pckod_b(MSARegister wd, MSARegister ws, MSARegister wt);
1545   void pckod_h(MSARegister wd, MSARegister ws, MSARegister wt);
1546   void pckod_w(MSARegister wd, MSARegister ws, MSARegister wt);
1547   void pckod_d(MSARegister wd, MSARegister ws, MSARegister wt);
1548   void ilvl_b(MSARegister wd, MSARegister ws, MSARegister wt);
1549   void ilvl_h(MSARegister wd, MSARegister ws, MSARegister wt);
1550   void ilvl_w(MSARegister wd, MSARegister ws, MSARegister wt);
1551   void ilvl_d(MSARegister wd, MSARegister ws, MSARegister wt);
1552   void ilvr_b(MSARegister wd, MSARegister ws, MSARegister wt);
1553   void ilvr_h(MSARegister wd, MSARegister ws, MSARegister wt);
1554   void ilvr_w(MSARegister wd, MSARegister ws, MSARegister wt);
1555   void ilvr_d(MSARegister wd, MSARegister ws, MSARegister wt);
1556   void ilvev_b(MSARegister wd, MSARegister ws, MSARegister wt);
1557   void ilvev_h(MSARegister wd, MSARegister ws, MSARegister wt);
1558   void ilvev_w(MSARegister wd, MSARegister ws, MSARegister wt);
1559   void ilvev_d(MSARegister wd, MSARegister ws, MSARegister wt);
1560   void ilvod_b(MSARegister wd, MSARegister ws, MSARegister wt);
1561   void ilvod_h(MSARegister wd, MSARegister ws, MSARegister wt);
1562   void ilvod_w(MSARegister wd, MSARegister ws, MSARegister wt);
1563   void ilvod_d(MSARegister wd, MSARegister ws, MSARegister wt);
1564   void vshf_b(MSARegister wd, MSARegister ws, MSARegister wt);
1565   void vshf_h(MSARegister wd, MSARegister ws, MSARegister wt);
1566   void vshf_w(MSARegister wd, MSARegister ws, MSARegister wt);
1567   void vshf_d(MSARegister wd, MSARegister ws, MSARegister wt);
1568   void srar_b(MSARegister wd, MSARegister ws, MSARegister wt);
1569   void srar_h(MSARegister wd, MSARegister ws, MSARegister wt);
1570   void srar_w(MSARegister wd, MSARegister ws, MSARegister wt);
1571   void srar_d(MSARegister wd, MSARegister ws, MSARegister wt);
1572   void srlr_b(MSARegister wd, MSARegister ws, MSARegister wt);
1573   void srlr_h(MSARegister wd, MSARegister ws, MSARegister wt);
1574   void srlr_w(MSARegister wd, MSARegister ws, MSARegister wt);
1575   void srlr_d(MSARegister wd, MSARegister ws, MSARegister wt);
1576   void hadd_s_b(MSARegister wd, MSARegister ws, MSARegister wt);
1577   void hadd_s_h(MSARegister wd, MSARegister ws, MSARegister wt);
1578   void hadd_s_w(MSARegister wd, MSARegister ws, MSARegister wt);
1579   void hadd_s_d(MSARegister wd, MSARegister ws, MSARegister wt);
1580   void hadd_u_b(MSARegister wd, MSARegister ws, MSARegister wt);
1581   void hadd_u_h(MSARegister wd, MSARegister ws, MSARegister wt);
1582   void hadd_u_w(MSARegister wd, MSARegister ws, MSARegister wt);
1583   void hadd_u_d(MSARegister wd, MSARegister ws, MSARegister wt);
1584   void hsub_s_b(MSARegister wd, MSARegister ws, MSARegister wt);
1585   void hsub_s_h(MSARegister wd, MSARegister ws, MSARegister wt);
1586   void hsub_s_w(MSARegister wd, MSARegister ws, MSARegister wt);
1587   void hsub_s_d(MSARegister wd, MSARegister ws, MSARegister wt);
1588   void hsub_u_b(MSARegister wd, MSARegister ws, MSARegister wt);
1589   void hsub_u_h(MSARegister wd, MSARegister ws, MSARegister wt);
1590   void hsub_u_w(MSARegister wd, MSARegister ws, MSARegister wt);
1591   void hsub_u_d(MSARegister wd, MSARegister ws, MSARegister wt);
1592 
1593   void fcaf_w(MSARegister wd, MSARegister ws, MSARegister wt);
1594   void fcaf_d(MSARegister wd, MSARegister ws, MSARegister wt);
1595   void fcun_w(MSARegister wd, MSARegister ws, MSARegister wt);
1596   void fcun_d(MSARegister wd, MSARegister ws, MSARegister wt);
1597   void fceq_w(MSARegister wd, MSARegister ws, MSARegister wt);
1598   void fceq_d(MSARegister wd, MSARegister ws, MSARegister wt);
1599   void fcueq_w(MSARegister wd, MSARegister ws, MSARegister wt);
1600   void fcueq_d(MSARegister wd, MSARegister ws, MSARegister wt);
1601   void fclt_w(MSARegister wd, MSARegister ws, MSARegister wt);
1602   void fclt_d(MSARegister wd, MSARegister ws, MSARegister wt);
1603   void fcult_w(MSARegister wd, MSARegister ws, MSARegister wt);
1604   void fcult_d(MSARegister wd, MSARegister ws, MSARegister wt);
1605   void fcle_w(MSARegister wd, MSARegister ws, MSARegister wt);
1606   void fcle_d(MSARegister wd, MSARegister ws, MSARegister wt);
1607   void fcule_w(MSARegister wd, MSARegister ws, MSARegister wt);
1608   void fcule_d(MSARegister wd, MSARegister ws, MSARegister wt);
1609   void fsaf_w(MSARegister wd, MSARegister ws, MSARegister wt);
1610   void fsaf_d(MSARegister wd, MSARegister ws, MSARegister wt);
1611   void fsun_w(MSARegister wd, MSARegister ws, MSARegister wt);
1612   void fsun_d(MSARegister wd, MSARegister ws, MSARegister wt);
1613   void fseq_w(MSARegister wd, MSARegister ws, MSARegister wt);
1614   void fseq_d(MSARegister wd, MSARegister ws, MSARegister wt);
1615   void fsueq_w(MSARegister wd, MSARegister ws, MSARegister wt);
1616   void fsueq_d(MSARegister wd, MSARegister ws, MSARegister wt);
1617   void fslt_w(MSARegister wd, MSARegister ws, MSARegister wt);
1618   void fslt_d(MSARegister wd, MSARegister ws, MSARegister wt);
1619   void fsult_w(MSARegister wd, MSARegister ws, MSARegister wt);
1620   void fsult_d(MSARegister wd, MSARegister ws, MSARegister wt);
1621   void fsle_w(MSARegister wd, MSARegister ws, MSARegister wt);
1622   void fsle_d(MSARegister wd, MSARegister ws, MSARegister wt);
1623   void fsule_w(MSARegister wd, MSARegister ws, MSARegister wt);
1624   void fsule_d(MSARegister wd, MSARegister ws, MSARegister wt);
1625   void fadd_w(MSARegister wd, MSARegister ws, MSARegister wt);
1626   void fadd_d(MSARegister wd, MSARegister ws, MSARegister wt);
1627   void fsub_w(MSARegister wd, MSARegister ws, MSARegister wt);
1628   void fsub_d(MSARegister wd, MSARegister ws, MSARegister wt);
1629   void fmul_w(MSARegister wd, MSARegister ws, MSARegister wt);
1630   void fmul_d(MSARegister wd, MSARegister ws, MSARegister wt);
1631   void fdiv_w(MSARegister wd, MSARegister ws, MSARegister wt);
1632   void fdiv_d(MSARegister wd, MSARegister ws, MSARegister wt);
1633   void fmadd_w(MSARegister wd, MSARegister ws, MSARegister wt);
1634   void fmadd_d(MSARegister wd, MSARegister ws, MSARegister wt);
1635   void fmsub_w(MSARegister wd, MSARegister ws, MSARegister wt);
1636   void fmsub_d(MSARegister wd, MSARegister ws, MSARegister wt);
1637   void fexp2_w(MSARegister wd, MSARegister ws, MSARegister wt);
1638   void fexp2_d(MSARegister wd, MSARegister ws, MSARegister wt);
1639   void fexdo_h(MSARegister wd, MSARegister ws, MSARegister wt);
1640   void fexdo_w(MSARegister wd, MSARegister ws, MSARegister wt);
1641   void ftq_h(MSARegister wd, MSARegister ws, MSARegister wt);
1642   void ftq_w(MSARegister wd, MSARegister ws, MSARegister wt);
1643   void fmin_w(MSARegister wd, MSARegister ws, MSARegister wt);
1644   void fmin_d(MSARegister wd, MSARegister ws, MSARegister wt);
1645   void fmin_a_w(MSARegister wd, MSARegister ws, MSARegister wt);
1646   void fmin_a_d(MSARegister wd, MSARegister ws, MSARegister wt);
1647   void fmax_w(MSARegister wd, MSARegister ws, MSARegister wt);
1648   void fmax_d(MSARegister wd, MSARegister ws, MSARegister wt);
1649   void fmax_a_w(MSARegister wd, MSARegister ws, MSARegister wt);
1650   void fmax_a_d(MSARegister wd, MSARegister ws, MSARegister wt);
1651   void fcor_w(MSARegister wd, MSARegister ws, MSARegister wt);
1652   void fcor_d(MSARegister wd, MSARegister ws, MSARegister wt);
1653   void fcune_w(MSARegister wd, MSARegister ws, MSARegister wt);
1654   void fcune_d(MSARegister wd, MSARegister ws, MSARegister wt);
1655   void fcne_w(MSARegister wd, MSARegister ws, MSARegister wt);
1656   void fcne_d(MSARegister wd, MSARegister ws, MSARegister wt);
1657   void mul_q_h(MSARegister wd, MSARegister ws, MSARegister wt);
1658   void mul_q_w(MSARegister wd, MSARegister ws, MSARegister wt);
1659   void madd_q_h(MSARegister wd, MSARegister ws, MSARegister wt);
1660   void madd_q_w(MSARegister wd, MSARegister ws, MSARegister wt);
1661   void msub_q_h(MSARegister wd, MSARegister ws, MSARegister wt);
1662   void msub_q_w(MSARegister wd, MSARegister ws, MSARegister wt);
1663   void fsor_w(MSARegister wd, MSARegister ws, MSARegister wt);
1664   void fsor_d(MSARegister wd, MSARegister ws, MSARegister wt);
1665   void fsune_w(MSARegister wd, MSARegister ws, MSARegister wt);
1666   void fsune_d(MSARegister wd, MSARegister ws, MSARegister wt);
1667   void fsne_w(MSARegister wd, MSARegister ws, MSARegister wt);
1668   void fsne_d(MSARegister wd, MSARegister ws, MSARegister wt);
1669   void mulr_q_h(MSARegister wd, MSARegister ws, MSARegister wt);
1670   void mulr_q_w(MSARegister wd, MSARegister ws, MSARegister wt);
1671   void maddr_q_h(MSARegister wd, MSARegister ws, MSARegister wt);
1672   void maddr_q_w(MSARegister wd, MSARegister ws, MSARegister wt);
1673   void msubr_q_h(MSARegister wd, MSARegister ws, MSARegister wt);
1674   void msubr_q_w(MSARegister wd, MSARegister ws, MSARegister wt);
1675 
1676   void sldi_b(MSARegister wd, MSARegister ws, uint32_t n);
1677   void sldi_h(MSARegister wd, MSARegister ws, uint32_t n);
1678   void sldi_w(MSARegister wd, MSARegister ws, uint32_t n);
1679   void sldi_d(MSARegister wd, MSARegister ws, uint32_t n);
1680   void splati_b(MSARegister wd, MSARegister ws, uint32_t n);
1681   void splati_h(MSARegister wd, MSARegister ws, uint32_t n);
1682   void splati_w(MSARegister wd, MSARegister ws, uint32_t n);
1683   void splati_d(MSARegister wd, MSARegister ws, uint32_t n);
1684   void copy_s_b(Register rd, MSARegister ws, uint32_t n);
1685   void copy_s_h(Register rd, MSARegister ws, uint32_t n);
1686   void copy_s_w(Register rd, MSARegister ws, uint32_t n);
1687   void copy_s_d(Register rd, MSARegister ws, uint32_t n);
1688   void copy_u_b(Register rd, MSARegister ws, uint32_t n);
1689   void copy_u_h(Register rd, MSARegister ws, uint32_t n);
1690   void copy_u_w(Register rd, MSARegister ws, uint32_t n);
1691   void insert_b(MSARegister wd, uint32_t n, Register rs);
1692   void insert_h(MSARegister wd, uint32_t n, Register rs);
1693   void insert_w(MSARegister wd, uint32_t n, Register rs);
1694   void insert_d(MSARegister wd, uint32_t n, Register rs);
1695   void insve_b(MSARegister wd, uint32_t n, MSARegister ws);
1696   void insve_h(MSARegister wd, uint32_t n, MSARegister ws);
1697   void insve_w(MSARegister wd, uint32_t n, MSARegister ws);
1698   void insve_d(MSARegister wd, uint32_t n, MSARegister ws);
1699   void move_v(MSARegister wd, MSARegister ws);
1700   void ctcmsa(MSAControlRegister cd, Register rs);
1701   void cfcmsa(Register rd, MSAControlRegister cs);
1702 
1703   void slli_b(MSARegister wd, MSARegister ws, uint32_t m);
1704   void slli_h(MSARegister wd, MSARegister ws, uint32_t m);
1705   void slli_w(MSARegister wd, MSARegister ws, uint32_t m);
1706   void slli_d(MSARegister wd, MSARegister ws, uint32_t m);
1707   void srai_b(MSARegister wd, MSARegister ws, uint32_t m);
1708   void srai_h(MSARegister wd, MSARegister ws, uint32_t m);
1709   void srai_w(MSARegister wd, MSARegister ws, uint32_t m);
1710   void srai_d(MSARegister wd, MSARegister ws, uint32_t m);
1711   void srli_b(MSARegister wd, MSARegister ws, uint32_t m);
1712   void srli_h(MSARegister wd, MSARegister ws, uint32_t m);
1713   void srli_w(MSARegister wd, MSARegister ws, uint32_t m);
1714   void srli_d(MSARegister wd, MSARegister ws, uint32_t m);
1715   void bclri_b(MSARegister wd, MSARegister ws, uint32_t m);
1716   void bclri_h(MSARegister wd, MSARegister ws, uint32_t m);
1717   void bclri_w(MSARegister wd, MSARegister ws, uint32_t m);
1718   void bclri_d(MSARegister wd, MSARegister ws, uint32_t m);
1719   void bseti_b(MSARegister wd, MSARegister ws, uint32_t m);
1720   void bseti_h(MSARegister wd, MSARegister ws, uint32_t m);
1721   void bseti_w(MSARegister wd, MSARegister ws, uint32_t m);
1722   void bseti_d(MSARegister wd, MSARegister ws, uint32_t m);
1723   void bnegi_b(MSARegister wd, MSARegister ws, uint32_t m);
1724   void bnegi_h(MSARegister wd, MSARegister ws, uint32_t m);
1725   void bnegi_w(MSARegister wd, MSARegister ws, uint32_t m);
1726   void bnegi_d(MSARegister wd, MSARegister ws, uint32_t m);
1727   void binsli_b(MSARegister wd, MSARegister ws, uint32_t m);
1728   void binsli_h(MSARegister wd, MSARegister ws, uint32_t m);
1729   void binsli_w(MSARegister wd, MSARegister ws, uint32_t m);
1730   void binsli_d(MSARegister wd, MSARegister ws, uint32_t m);
1731   void binsri_b(MSARegister wd, MSARegister ws, uint32_t m);
1732   void binsri_h(MSARegister wd, MSARegister ws, uint32_t m);
1733   void binsri_w(MSARegister wd, MSARegister ws, uint32_t m);
1734   void binsri_d(MSARegister wd, MSARegister ws, uint32_t m);
1735   void sat_s_b(MSARegister wd, MSARegister ws, uint32_t m);
1736   void sat_s_h(MSARegister wd, MSARegister ws, uint32_t m);
1737   void sat_s_w(MSARegister wd, MSARegister ws, uint32_t m);
1738   void sat_s_d(MSARegister wd, MSARegister ws, uint32_t m);
1739   void sat_u_b(MSARegister wd, MSARegister ws, uint32_t m);
1740   void sat_u_h(MSARegister wd, MSARegister ws, uint32_t m);
1741   void sat_u_w(MSARegister wd, MSARegister ws, uint32_t m);
1742   void sat_u_d(MSARegister wd, MSARegister ws, uint32_t m);
1743   void srari_b(MSARegister wd, MSARegister ws, uint32_t m);
1744   void srari_h(MSARegister wd, MSARegister ws, uint32_t m);
1745   void srari_w(MSARegister wd, MSARegister ws, uint32_t m);
1746   void srari_d(MSARegister wd, MSARegister ws, uint32_t m);
1747   void srlri_b(MSARegister wd, MSARegister ws, uint32_t m);
1748   void srlri_h(MSARegister wd, MSARegister ws, uint32_t m);
1749   void srlri_w(MSARegister wd, MSARegister ws, uint32_t m);
1750   void srlri_d(MSARegister wd, MSARegister ws, uint32_t m);
1751 
1752   // Check the code size generated from label to here.
SizeOfCodeGeneratedSince(Label * label)1753   int SizeOfCodeGeneratedSince(Label* label) {
1754     return pc_offset() - label->pos();
1755   }
1756 
1757   // Check the number of instructions generated from label to here.
InstructionsGeneratedSince(Label * label)1758   int InstructionsGeneratedSince(Label* label) {
1759     return SizeOfCodeGeneratedSince(label) / kInstrSize;
1760   }
1761 
1762   // Class for scoping postponing the trampoline pool generation.
1763   class BlockTrampolinePoolScope {
1764    public:
BlockTrampolinePoolScope(Assembler * assem)1765     explicit BlockTrampolinePoolScope(Assembler* assem) : assem_(assem) {
1766       assem_->StartBlockTrampolinePool();
1767     }
~BlockTrampolinePoolScope()1768     ~BlockTrampolinePoolScope() {
1769       assem_->EndBlockTrampolinePool();
1770     }
1771 
1772    private:
1773     Assembler* assem_;
1774 
1775     DISALLOW_IMPLICIT_CONSTRUCTORS(BlockTrampolinePoolScope);
1776   };
1777 
1778   // Class for postponing the assembly buffer growth. Typically used for
1779   // sequences of instructions that must be emitted as a unit, before
1780   // buffer growth (and relocation) can occur.
1781   // This blocking scope is not nestable.
1782   class BlockGrowBufferScope {
1783    public:
BlockGrowBufferScope(Assembler * assem)1784     explicit BlockGrowBufferScope(Assembler* assem) : assem_(assem) {
1785       assem_->StartBlockGrowBuffer();
1786     }
~BlockGrowBufferScope()1787     ~BlockGrowBufferScope() {
1788       assem_->EndBlockGrowBuffer();
1789     }
1790 
1791    private:
1792     Assembler* assem_;
1793 
1794     DISALLOW_IMPLICIT_CONSTRUCTORS(BlockGrowBufferScope);
1795   };
1796 
1797   // Record a comment relocation entry that can be used by a disassembler.
1798   // Use --code-comments to enable.
1799   void RecordComment(const char* msg);
1800 
1801   // Record a deoptimization reason that can be used by a log or cpu profiler.
1802   // Use --trace-deopt to enable.
1803   void RecordDeoptReason(DeoptimizeReason reason, SourcePosition position,
1804                          int id);
1805 
1806   static int RelocateInternalReference(RelocInfo::Mode rmode, Address pc,
1807                                        intptr_t pc_delta);
1808 
1809   // Writes a single byte or word of data in the code stream.  Used for
1810   // inline tables, e.g., jump-tables.
1811   void db(uint8_t data);
1812   void dd(uint32_t data);
1813   void dq(uint64_t data);
dp(uintptr_t data)1814   void dp(uintptr_t data) { dq(data); }
1815   void dd(Label* label);
1816 
1817   // Postpone the generation of the trampoline pool for the specified number of
1818   // instructions.
1819   void BlockTrampolinePoolFor(int instructions);
1820 
1821   // Check if there is less than kGap bytes available in the buffer.
1822   // If this is the case, we need to grow the buffer before emitting
1823   // an instruction or relocation information.
overflow()1824   inline bool overflow() const { return pc_ >= reloc_info_writer.pos() - kGap; }
1825 
1826   // Get the number of bytes available in the buffer.
available_space()1827   inline intptr_t available_space() const {
1828     return reloc_info_writer.pos() - pc_;
1829   }
1830 
1831   // Read/patch instructions.
instr_at(Address pc)1832   static Instr instr_at(Address pc) { return *reinterpret_cast<Instr*>(pc); }
instr_at_put(Address pc,Instr instr)1833   static void instr_at_put(Address pc, Instr instr) {
1834     *reinterpret_cast<Instr*>(pc) = instr;
1835   }
instr_at(int pos)1836   Instr instr_at(int pos) { return *reinterpret_cast<Instr*>(buffer_ + pos); }
instr_at_put(int pos,Instr instr)1837   void instr_at_put(int pos, Instr instr) {
1838     *reinterpret_cast<Instr*>(buffer_ + pos) = instr;
1839   }
1840 
1841   // Check if an instruction is a branch of some kind.
1842   static bool IsBranch(Instr instr);
1843   static bool IsMsaBranch(Instr instr);
1844   static bool IsBc(Instr instr);
1845   static bool IsNal(Instr instr);
1846   static bool IsBzc(Instr instr);
1847 
1848   static bool IsBeq(Instr instr);
1849   static bool IsBne(Instr instr);
1850   static bool IsBeqzc(Instr instr);
1851   static bool IsBnezc(Instr instr);
1852   static bool IsBeqc(Instr instr);
1853   static bool IsBnec(Instr instr);
1854 
1855 
1856   static bool IsJump(Instr instr);
1857   static bool IsJ(Instr instr);
1858   static bool IsLui(Instr instr);
1859   static bool IsOri(Instr instr);
1860   static bool IsMov(Instr instr, Register rd, Register rs);
1861 
1862   static bool IsJal(Instr instr);
1863   static bool IsJr(Instr instr);
1864   static bool IsJalr(Instr instr);
1865 
1866   static bool IsNop(Instr instr, unsigned int type);
1867   static bool IsPop(Instr instr);
1868   static bool IsPush(Instr instr);
1869   static bool IsLwRegFpOffset(Instr instr);
1870   static bool IsSwRegFpOffset(Instr instr);
1871   static bool IsLwRegFpNegOffset(Instr instr);
1872   static bool IsSwRegFpNegOffset(Instr instr);
1873 
1874   static Register GetRtReg(Instr instr);
1875   static Register GetRsReg(Instr instr);
1876   static Register GetRdReg(Instr instr);
1877 
1878   static uint32_t GetRt(Instr instr);
1879   static uint32_t GetRtField(Instr instr);
1880   static uint32_t GetRs(Instr instr);
1881   static uint32_t GetRsField(Instr instr);
1882   static uint32_t GetRd(Instr instr);
1883   static uint32_t GetRdField(Instr instr);
1884   static uint32_t GetSa(Instr instr);
1885   static uint32_t GetSaField(Instr instr);
1886   static uint32_t GetOpcodeField(Instr instr);
1887   static uint32_t GetFunction(Instr instr);
1888   static uint32_t GetFunctionField(Instr instr);
1889   static uint32_t GetImmediate16(Instr instr);
1890   static uint32_t GetLabelConst(Instr instr);
1891 
1892   static int32_t GetBranchOffset(Instr instr);
1893   static bool IsLw(Instr instr);
1894   static int16_t GetLwOffset(Instr instr);
1895   static Instr SetLwOffset(Instr instr, int16_t offset);
1896 
1897   static bool IsSw(Instr instr);
1898   static Instr SetSwOffset(Instr instr, int16_t offset);
1899   static bool IsAddImmediate(Instr instr);
1900   static Instr SetAddImmediateOffset(Instr instr, int16_t offset);
1901 
1902   static bool IsAndImmediate(Instr instr);
1903   static bool IsEmittedConstant(Instr instr);
1904 
1905   void CheckTrampolinePool();
1906 
PatchConstantPoolAccessInstruction(int pc_offset,int offset,ConstantPoolEntry::Access access,ConstantPoolEntry::Type type)1907   void PatchConstantPoolAccessInstruction(int pc_offset, int offset,
1908                                           ConstantPoolEntry::Access access,
1909                                           ConstantPoolEntry::Type type) {
1910     // No embedded constant pool support.
1911     UNREACHABLE();
1912   }
1913 
IsPrevInstrCompactBranch()1914   bool IsPrevInstrCompactBranch() { return prev_instr_compact_branch_; }
IsCompactBranchSupported()1915   static bool IsCompactBranchSupported() { return kArchVariant == kMips64r6; }
1916 
UnboundLabelsCount()1917   inline int UnboundLabelsCount() { return unbound_labels_count_; }
1918 
1919  protected:
1920   // Load Scaled Address instructions.
1921   void lsa(Register rd, Register rt, Register rs, uint8_t sa);
1922   void dlsa(Register rd, Register rt, Register rs, uint8_t sa);
1923 
1924   // Readable constants for base and offset adjustment helper, these indicate if
1925   // aside from offset, another value like offset + 4 should fit into int16.
1926   enum class OffsetAccessType : bool {
1927     SINGLE_ACCESS = false,
1928     TWO_ACCESSES = true
1929   };
1930 
1931   // Helper function for memory load/store using base register and offset.
1932   void AdjustBaseAndOffset(
1933       MemOperand& src,
1934       OffsetAccessType access_type = OffsetAccessType::SINGLE_ACCESS,
1935       int second_access_add_to_offset = 4);
1936 
1937   inline static void set_target_internal_reference_encoded_at(Address pc,
1938                                                               Address target);
1939 
buffer_space()1940   int64_t buffer_space() const { return reloc_info_writer.pos() - pc_; }
1941 
1942   // Decode branch instruction at pos and return branch target pos.
1943   int target_at(int pos, bool is_internal);
1944 
1945   // Patch branch instruction at pos to branch to given branch target pos.
1946   void target_at_put(int pos, int target_pos, bool is_internal);
1947 
1948   // Say if we need to relocate with this mode.
1949   bool MustUseReg(RelocInfo::Mode rmode);
1950 
1951   // Record reloc info for current pc_.
1952   void RecordRelocInfo(RelocInfo::Mode rmode, intptr_t data = 0);
1953 
1954   // Block the emission of the trampoline pool before pc_offset.
BlockTrampolinePoolBefore(int pc_offset)1955   void BlockTrampolinePoolBefore(int pc_offset) {
1956     if (no_trampoline_pool_before_ < pc_offset)
1957       no_trampoline_pool_before_ = pc_offset;
1958   }
1959 
StartBlockTrampolinePool()1960   void StartBlockTrampolinePool() {
1961     trampoline_pool_blocked_nesting_++;
1962   }
1963 
EndBlockTrampolinePool()1964   void EndBlockTrampolinePool() {
1965     trampoline_pool_blocked_nesting_--;
1966     if (trampoline_pool_blocked_nesting_ == 0) {
1967       CheckTrampolinePoolQuick(1);
1968     }
1969   }
1970 
is_trampoline_pool_blocked()1971   bool is_trampoline_pool_blocked() const {
1972     return trampoline_pool_blocked_nesting_ > 0;
1973   }
1974 
has_exception()1975   bool has_exception() const {
1976     return internal_trampoline_exception_;
1977   }
1978 
is_trampoline_emitted()1979   bool is_trampoline_emitted() const {
1980     return trampoline_emitted_;
1981   }
1982 
1983   // Temporarily block automatic assembly buffer growth.
StartBlockGrowBuffer()1984   void StartBlockGrowBuffer() {
1985     DCHECK(!block_buffer_growth_);
1986     block_buffer_growth_ = true;
1987   }
1988 
EndBlockGrowBuffer()1989   void EndBlockGrowBuffer() {
1990     DCHECK(block_buffer_growth_);
1991     block_buffer_growth_ = false;
1992   }
1993 
is_buffer_growth_blocked()1994   bool is_buffer_growth_blocked() const {
1995     return block_buffer_growth_;
1996   }
1997 
EmitForbiddenSlotInstruction()1998   void EmitForbiddenSlotInstruction() {
1999     if (IsPrevInstrCompactBranch()) {
2000       nop();
2001     }
2002   }
2003 
2004   void CheckTrampolinePoolQuick(int extra_instructions = 0) {
2005     if (pc_offset() >= next_buffer_check_ - extra_instructions * kInstrSize) {
2006       CheckTrampolinePool();
2007     }
2008   }
2009 
2010  private:
2011   // Avoid overflows for displacements etc.
2012   static const int kMaximalBufferSize = 512 * MB;
2013 
2014   // Buffer size and constant pool distance are checked together at regular
2015   // intervals of kBufferCheckInterval emitted bytes.
2016   static constexpr int kBufferCheckInterval = 1 * KB / 2;
2017 
2018   // Code generation.
2019   // The relocation writer's position is at least kGap bytes below the end of
2020   // the generated instructions. This is so that multi-instruction sequences do
2021   // not have to check for overflow. The same is true for writes of large
2022   // relocation info entries.
2023   static constexpr int kGap = 128;
2024 
2025   // Repeated checking whether the trampoline pool should be emitted is rather
2026   // expensive. By default we only check again once a number of instructions
2027   // has been generated.
2028   static constexpr int kCheckConstIntervalInst = 32;
2029   static constexpr int kCheckConstInterval =
2030       kCheckConstIntervalInst * kInstrSize;
2031 
2032   int next_buffer_check_;  // pc offset of next buffer check.
2033 
2034   // Emission of the trampoline pool may be blocked in some code sequences.
2035   int trampoline_pool_blocked_nesting_;  // Block emission if this is not zero.
2036   int no_trampoline_pool_before_;  // Block emission before this pc offset.
2037 
2038   // Keep track of the last emitted pool to guarantee a maximal distance.
2039   int last_trampoline_pool_end_;  // pc offset of the end of the last pool.
2040 
2041   // Automatic growth of the assembly buffer may be blocked for some sequences.
2042   bool block_buffer_growth_;  // Block growth when true.
2043 
2044   // Relocation information generation.
2045   // Each relocation is encoded as a variable size value.
2046   static constexpr int kMaxRelocSize = RelocInfoWriter::kMaxSize;
2047   RelocInfoWriter reloc_info_writer;
2048 
2049   // The bound position, before this we cannot do instruction elimination.
2050   int last_bound_pos_;
2051 
2052   // Readable constants for compact branch handling in emit()
2053   enum class CompactBranchType : bool { NO = false, COMPACT_BRANCH = true };
2054 
2055   // Code emission.
2056   inline void CheckBuffer();
2057   void GrowBuffer();
2058   inline void emit(Instr x,
2059                    CompactBranchType is_compact_branch = CompactBranchType::NO);
2060   inline void emit(uint64_t x);
2061   inline void CheckForEmitInForbiddenSlot();
2062   template <typename T>
2063   inline void EmitHelper(T x);
2064   inline void EmitHelper(Instr x, CompactBranchType is_compact_branch);
2065 
2066   // Instruction generation.
2067   // We have 3 different kind of encoding layout on MIPS.
2068   // However due to many different types of objects encoded in the same fields
2069   // we have quite a few aliases for each mode.
2070   // Using the same structure to refer to Register and FPURegister would spare a
2071   // few aliases, but mixing both does not look clean to me.
2072   // Anyway we could surely implement this differently.
2073 
2074   void GenInstrRegister(Opcode opcode, Register rs, Register rt, Register rd,
2075                         uint16_t sa = 0, SecondaryField func = nullptrSF);
2076 
2077   void GenInstrRegister(Opcode opcode,
2078                         Register rs,
2079                         Register rt,
2080                         uint16_t msb,
2081                         uint16_t lsb,
2082                         SecondaryField func);
2083 
2084   void GenInstrRegister(Opcode opcode, SecondaryField fmt, FPURegister ft,
2085                         FPURegister fs, FPURegister fd,
2086                         SecondaryField func = nullptrSF);
2087 
2088   void GenInstrRegister(Opcode opcode, FPURegister fr, FPURegister ft,
2089                         FPURegister fs, FPURegister fd,
2090                         SecondaryField func = nullptrSF);
2091 
2092   void GenInstrRegister(Opcode opcode, SecondaryField fmt, Register rt,
2093                         FPURegister fs, FPURegister fd,
2094                         SecondaryField func = nullptrSF);
2095 
2096   void GenInstrRegister(Opcode opcode, SecondaryField fmt, Register rt,
2097                         FPUControlRegister fs, SecondaryField func = nullptrSF);
2098 
2099   void GenInstrImmediate(
2100       Opcode opcode, Register rs, Register rt, int32_t j,
2101       CompactBranchType is_compact_branch = CompactBranchType::NO);
2102   void GenInstrImmediate(
2103       Opcode opcode, Register rs, SecondaryField SF, int32_t j,
2104       CompactBranchType is_compact_branch = CompactBranchType::NO);
2105   void GenInstrImmediate(
2106       Opcode opcode, Register r1, FPURegister r2, int32_t j,
2107       CompactBranchType is_compact_branch = CompactBranchType::NO);
2108   void GenInstrImmediate(Opcode opcode, Register base, Register rt,
2109                          int32_t offset9, int bit6, SecondaryField func);
2110   void GenInstrImmediate(
2111       Opcode opcode, Register rs, int32_t offset21,
2112       CompactBranchType is_compact_branch = CompactBranchType::NO);
2113   void GenInstrImmediate(Opcode opcode, Register rs, uint32_t offset21);
2114   void GenInstrImmediate(
2115       Opcode opcode, int32_t offset26,
2116       CompactBranchType is_compact_branch = CompactBranchType::NO);
2117 
2118   void GenInstrJump(Opcode opcode,
2119                      uint32_t address);
2120 
2121   // MSA
2122   void GenInstrMsaI8(SecondaryField operation, uint32_t imm8, MSARegister ws,
2123                      MSARegister wd);
2124 
2125   void GenInstrMsaI5(SecondaryField operation, SecondaryField df, int32_t imm5,
2126                      MSARegister ws, MSARegister wd);
2127 
2128   void GenInstrMsaBit(SecondaryField operation, SecondaryField df, uint32_t m,
2129                       MSARegister ws, MSARegister wd);
2130 
2131   void GenInstrMsaI10(SecondaryField operation, SecondaryField df,
2132                       int32_t imm10, MSARegister wd);
2133 
2134   template <typename RegType>
2135   void GenInstrMsa3R(SecondaryField operation, SecondaryField df, RegType t,
2136                      MSARegister ws, MSARegister wd);
2137 
2138   template <typename DstType, typename SrcType>
2139   void GenInstrMsaElm(SecondaryField operation, SecondaryField df, uint32_t n,
2140                       SrcType src, DstType dst);
2141 
2142   void GenInstrMsa3RF(SecondaryField operation, uint32_t df, MSARegister wt,
2143                       MSARegister ws, MSARegister wd);
2144 
2145   void GenInstrMsaVec(SecondaryField operation, MSARegister wt, MSARegister ws,
2146                       MSARegister wd);
2147 
2148   void GenInstrMsaMI10(SecondaryField operation, int32_t s10, Register rs,
2149                        MSARegister wd);
2150 
2151   void GenInstrMsa2R(SecondaryField operation, SecondaryField df,
2152                      MSARegister ws, MSARegister wd);
2153 
2154   void GenInstrMsa2RF(SecondaryField operation, SecondaryField df,
2155                       MSARegister ws, MSARegister wd);
2156 
2157   void GenInstrMsaBranch(SecondaryField operation, MSARegister wt,
2158                          int32_t offset16);
2159 
is_valid_msa_df_m(SecondaryField bit_df,uint32_t m)2160   inline bool is_valid_msa_df_m(SecondaryField bit_df, uint32_t m) {
2161     switch (bit_df) {
2162       case BIT_DF_b:
2163         return is_uint3(m);
2164       case BIT_DF_h:
2165         return is_uint4(m);
2166       case BIT_DF_w:
2167         return is_uint5(m);
2168       case BIT_DF_d:
2169         return is_uint6(m);
2170       default:
2171         return false;
2172     }
2173   }
2174 
is_valid_msa_df_n(SecondaryField elm_df,uint32_t n)2175   inline bool is_valid_msa_df_n(SecondaryField elm_df, uint32_t n) {
2176     switch (elm_df) {
2177       case ELM_DF_B:
2178         return is_uint4(n);
2179       case ELM_DF_H:
2180         return is_uint3(n);
2181       case ELM_DF_W:
2182         return is_uint2(n);
2183       case ELM_DF_D:
2184         return is_uint1(n);
2185       default:
2186         return false;
2187     }
2188   }
2189 
2190   // Labels.
2191   void print(const Label* L);
2192   void bind_to(Label* L, int pos);
2193   void next(Label* L, bool is_internal);
2194 
2195   // One trampoline consists of:
2196   // - space for trampoline slots,
2197   // - space for labels.
2198   //
2199   // Space for trampoline slots is equal to slot_count * 2 * kInstrSize.
2200   // Space for trampoline slots precedes space for labels. Each label is of one
2201   // instruction size, so total amount for labels is equal to
2202   // label_count *  kInstrSize.
2203   class Trampoline {
2204    public:
Trampoline()2205     Trampoline() {
2206       start_ = 0;
2207       next_slot_ = 0;
2208       free_slot_count_ = 0;
2209       end_ = 0;
2210     }
Trampoline(int start,int slot_count)2211     Trampoline(int start, int slot_count) {
2212       start_ = start;
2213       next_slot_ = start;
2214       free_slot_count_ = slot_count;
2215       end_ = start + slot_count * kTrampolineSlotsSize;
2216     }
start()2217     int start() {
2218       return start_;
2219     }
end()2220     int end() {
2221       return end_;
2222     }
take_slot()2223     int take_slot() {
2224       int trampoline_slot = kInvalidSlotPos;
2225       if (free_slot_count_ <= 0) {
2226         // We have run out of space on trampolines.
2227         // Make sure we fail in debug mode, so we become aware of each case
2228         // when this happens.
2229         DCHECK(0);
2230         // Internal exception will be caught.
2231       } else {
2232         trampoline_slot = next_slot_;
2233         free_slot_count_--;
2234         next_slot_ += kTrampolineSlotsSize;
2235       }
2236       return trampoline_slot;
2237     }
2238 
2239    private:
2240     int start_;
2241     int end_;
2242     int next_slot_;
2243     int free_slot_count_;
2244   };
2245 
2246   int32_t get_trampoline_entry(int32_t pos);
2247   int unbound_labels_count_;
2248   // After trampoline is emitted, long branches are used in generated code for
2249   // the forward branches whose target offsets could be beyond reach of branch
2250   // instruction. We use this information to trigger different mode of
2251   // branch instruction generation, where we use jump instructions rather
2252   // than regular branch instructions.
2253   bool trampoline_emitted_;
2254   static constexpr int kInvalidSlotPos = -1;
2255 
2256   // Internal reference positions, required for unbounded internal reference
2257   // labels.
2258   std::set<int64_t> internal_reference_positions_;
is_internal_reference(Label * L)2259   bool is_internal_reference(Label* L) {
2260     return internal_reference_positions_.find(L->pos()) !=
2261            internal_reference_positions_.end();
2262   }
2263 
EmittedCompactBranchInstruction()2264   void EmittedCompactBranchInstruction() { prev_instr_compact_branch_ = true; }
ClearCompactBranchState()2265   void ClearCompactBranchState() { prev_instr_compact_branch_ = false; }
2266   bool prev_instr_compact_branch_ = false;
2267 
2268   Trampoline trampoline_;
2269   bool internal_trampoline_exception_;
2270 
2271   RegList scratch_register_list_;
2272 
2273  private:
2274   void AllocateAndInstallRequestedHeapObjects(Isolate* isolate);
2275 
2276   friend class RegExpMacroAssemblerMIPS;
2277   friend class RelocInfo;
2278   friend class BlockTrampolinePoolScope;
2279   friend class EnsureSpace;
2280 };
2281 
2282 
2283 class EnsureSpace BASE_EMBEDDED {
2284  public:
2285   explicit inline EnsureSpace(Assembler* assembler);
2286 };
2287 
2288 class UseScratchRegisterScope {
2289  public:
2290   explicit UseScratchRegisterScope(Assembler* assembler);
2291   ~UseScratchRegisterScope();
2292 
2293   Register Acquire();
2294   bool hasAvailable() const;
2295 
2296  private:
2297   RegList* available_;
2298   RegList old_available_;
2299 };
2300 
2301 }  // namespace internal
2302 }  // namespace v8
2303 
2304 #endif  // V8_MIPS64_ASSEMBLER_MIPS64_H_
2305