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