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