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