1// Copyright (c) 1994-2006 Sun Microsystems Inc.
2// All Rights Reserved.
3//
4// Redistribution and use in source and binary forms, with or without
5// modification, are permitted provided that the following conditions are
6// met:
7//
8// - Redistributions of source code must retain the above copyright notice,
9// this list of conditions and the following disclaimer.
10//
11// - Redistribution in binary form must reproduce the above copyright
12// notice, this list of conditions and the following disclaimer in the
13// documentation and/or other materials provided with the distribution.
14//
15// - Neither the name of Sun Microsystems or the names of contributors may
16// be used to endorse or promote products derived from this software without
17// specific prior written permission.
18//
19// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
20// IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
21// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
23// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
24// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
25// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
26// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
27// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
28// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
29// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30
31// The original source code covered by the above license above has been
32// modified significantly by Google Inc.
33// Copyright 2012 the V8 project authors. All rights reserved.
34
35
36#ifndef V8_MIPS_ASSEMBLER_MIPS_H_
37#define V8_MIPS_ASSEMBLER_MIPS_H_
38
39#include <stdio.h>
40
41#include <set>
42
43#include "src/assembler.h"
44#include "src/mips/constants-mips.h"
45
46namespace v8 {
47namespace internal {
48
49// clang-format off
50#define GENERAL_REGISTERS(V)                              \
51  V(zero_reg)  V(at)  V(v0)  V(v1)  V(a0)  V(a1)  V(a2)  V(a3)  \
52  V(t0)  V(t1)  V(t2)  V(t3)  V(t4)  V(t5)  V(t6)  V(t7)  \
53  V(s0)  V(s1)  V(s2)  V(s3)  V(s4)  V(s5)  V(s6)  V(s7)  V(t8)  V(t9) \
54  V(k0)  V(k1)  V(gp)  V(sp)  V(fp)  V(ra)
55
56#define ALLOCATABLE_GENERAL_REGISTERS(V) \
57  V(v0)  V(v1)  V(a0)  V(a1)  V(a2)  V(a3) \
58  V(t0)  V(t1)  V(t2)  V(t3)  V(t4)  V(t5)  V(t6) V(s7)
59
60#define DOUBLE_REGISTERS(V)                               \
61  V(f0)  V(f1)  V(f2)  V(f3)  V(f4)  V(f5)  V(f6)  V(f7)  \
62  V(f8)  V(f9)  V(f10) V(f11) V(f12) V(f13) V(f14) V(f15) \
63  V(f16) V(f17) V(f18) V(f19) V(f20) V(f21) V(f22) V(f23) \
64  V(f24) V(f25) V(f26) V(f27) V(f28) V(f29) V(f30) V(f31)
65
66#define FLOAT_REGISTERS DOUBLE_REGISTERS
67#define SIMD128_REGISTERS DOUBLE_REGISTERS
68
69#define ALLOCATABLE_DOUBLE_REGISTERS(V)                   \
70  V(f0)  V(f2)  V(f4)  V(f6)  V(f8)  V(f10) V(f12) V(f14) \
71  V(f16) V(f18) V(f20) V(f22) V(f24) V(f26)
72// clang-format on
73
74// CPU Registers.
75//
76// 1) We would prefer to use an enum, but enum values are assignment-
77// compatible with int, which has caused code-generation bugs.
78//
79// 2) We would prefer to use a class instead of a struct but we don't like
80// the register initialization to depend on the particular initialization
81// order (which appears to be different on OS X, Linux, and Windows for the
82// installed versions of C++ we tried). Using a struct permits C-style
83// "initialization". Also, the Register objects cannot be const as this
84// forces initialization stubs in MSVC, making us dependent on initialization
85// order.
86//
87// 3) By not using an enum, we are possibly preventing the compiler from
88// doing certain constant folds, which may significantly reduce the
89// code generated for some assembly instructions (because they boil down
90// to a few constants). If this is a problem, we could change the code
91// such that we use an enum in optimized mode, and the struct in debug
92// mode. This way we get the compile-time error checking in debug mode
93// and best performance in optimized code.
94
95
96// -----------------------------------------------------------------------------
97// Implementation of Register and FPURegister.
98
99struct Register {
100  static const int kCpRegister = 23;  // cp (s7) is the 23rd register.
101
102  enum Code {
103#define REGISTER_CODE(R) kCode_##R,
104    GENERAL_REGISTERS(REGISTER_CODE)
105#undef REGISTER_CODE
106        kAfterLast,
107    kCode_no_reg = -1
108  };
109
110  static const int kNumRegisters = Code::kAfterLast;
111
112#if defined(V8_TARGET_LITTLE_ENDIAN)
113  static const int kMantissaOffset = 0;
114  static const int kExponentOffset = 4;
115#elif defined(V8_TARGET_BIG_ENDIAN)
116  static const int kMantissaOffset = 4;
117  static const int kExponentOffset = 0;
118#else
119#error Unknown endianness
120#endif
121
122
123  static Register from_code(int code) {
124    DCHECK(code >= 0);
125    DCHECK(code < kNumRegisters);
126    Register r = {code};
127    return r;
128  }
129  bool is_valid() const { return 0 <= reg_code && reg_code < kNumRegisters; }
130  bool is(Register reg) const { return reg_code == reg.reg_code; }
131  int code() const {
132    DCHECK(is_valid());
133    return reg_code;
134  }
135  int bit() const {
136    DCHECK(is_valid());
137    return 1 << reg_code;
138  }
139
140  // Unfortunately we can't make this private in a struct.
141  int reg_code;
142};
143
144// s7: context register
145// s3: lithium scratch
146// s4: lithium scratch2
147#define DECLARE_REGISTER(R) const Register R = {Register::kCode_##R};
148GENERAL_REGISTERS(DECLARE_REGISTER)
149#undef DECLARE_REGISTER
150const Register no_reg = {Register::kCode_no_reg};
151
152
153int ToNumber(Register reg);
154
155Register ToRegister(int num);
156
157static const bool kSimpleFPAliasing = true;
158
159// Coprocessor register.
160struct FPURegister {
161  enum Code {
162#define REGISTER_CODE(R) kCode_##R,
163    DOUBLE_REGISTERS(REGISTER_CODE)
164#undef REGISTER_CODE
165        kAfterLast,
166    kCode_no_reg = -1
167  };
168
169  static const int kMaxNumRegisters = Code::kAfterLast;
170
171  inline static int NumRegisters();
172
173  // TODO(plind): Warning, inconsistent numbering here. kNumFPURegisters refers
174  // to number of 32-bit FPU regs, but kNumAllocatableRegisters refers to
175  // number of Double regs (64-bit regs, or FPU-reg-pairs).
176
177  bool is_valid() const { return 0 <= reg_code && reg_code < kMaxNumRegisters; }
178  bool is(FPURegister reg) const { return reg_code == reg.reg_code; }
179  FPURegister low() const {
180    // Find low reg of a Double-reg pair, which is the reg itself.
181    DCHECK(reg_code % 2 == 0);  // Specified Double reg must be even.
182    FPURegister reg;
183    reg.reg_code = reg_code;
184    DCHECK(reg.is_valid());
185    return reg;
186  }
187  FPURegister high() const {
188    // Find high reg of a Doubel-reg pair, which is reg + 1.
189    DCHECK(reg_code % 2 == 0);  // Specified Double reg must be even.
190    FPURegister reg;
191    reg.reg_code = reg_code + 1;
192    DCHECK(reg.is_valid());
193    return reg;
194  }
195
196  int code() const {
197    DCHECK(is_valid());
198    return reg_code;
199  }
200  int bit() const {
201    DCHECK(is_valid());
202    return 1 << reg_code;
203  }
204
205  static FPURegister from_code(int code) {
206    FPURegister r = {code};
207    return r;
208  }
209  void setcode(int f) {
210    reg_code = f;
211    DCHECK(is_valid());
212  }
213  // Unfortunately we can't make this private in a struct.
214  int reg_code;
215};
216
217// A few double registers are reserved: one as a scratch register and one to
218// hold 0.0.
219//  f28: 0.0
220//  f30: scratch register.
221
222// V8 now supports the O32 ABI, and the FPU Registers are organized as 32
223// 32-bit registers, f0 through f31. When used as 'double' they are used
224// in pairs, starting with the even numbered register. So a double operation
225// on f0 really uses f0 and f1.
226// (Modern mips hardware also supports 32 64-bit registers, via setting
227// (priviledged) Status Register FR bit to 1. This is used by the N32 ABI,
228// but it is not in common use. Someday we will want to support this in v8.)
229
230// For O32 ABI, Floats and Doubles refer to same set of 32 32-bit registers.
231typedef FPURegister FloatRegister;
232
233typedef FPURegister DoubleRegister;
234
235// TODO(mips) Define SIMD registers.
236typedef FPURegister Simd128Register;
237
238const DoubleRegister no_freg = {-1};
239
240const DoubleRegister f0 = {0};  // Return value in hard float mode.
241const DoubleRegister f1 = {1};
242const DoubleRegister f2 = {2};
243const DoubleRegister f3 = {3};
244const DoubleRegister f4 = {4};
245const DoubleRegister f5 = {5};
246const DoubleRegister f6 = {6};
247const DoubleRegister f7 = {7};
248const DoubleRegister f8 = {8};
249const DoubleRegister f9 = {9};
250const DoubleRegister f10 = {10};
251const DoubleRegister f11 = {11};
252const DoubleRegister f12 = {12};  // Arg 0 in hard float mode.
253const DoubleRegister f13 = {13};
254const DoubleRegister f14 = {14};  // Arg 1 in hard float mode.
255const DoubleRegister f15 = {15};
256const DoubleRegister f16 = {16};
257const DoubleRegister f17 = {17};
258const DoubleRegister f18 = {18};
259const DoubleRegister f19 = {19};
260const DoubleRegister f20 = {20};
261const DoubleRegister f21 = {21};
262const DoubleRegister f22 = {22};
263const DoubleRegister f23 = {23};
264const DoubleRegister f24 = {24};
265const DoubleRegister f25 = {25};
266const DoubleRegister f26 = {26};
267const DoubleRegister f27 = {27};
268const DoubleRegister f28 = {28};
269const DoubleRegister f29 = {29};
270const DoubleRegister f30 = {30};
271const DoubleRegister f31 = {31};
272
273// Register aliases.
274// cp is assumed to be a callee saved register.
275// Defined using #define instead of "static const Register&" because Clang
276// complains otherwise when a compilation unit that includes this header
277// doesn't use the variables.
278#define kRootRegister s6
279#define cp s7
280#define kLithiumScratchReg s3
281#define kLithiumScratchReg2 s4
282#define kLithiumScratchDouble f30
283#define kDoubleRegZero f28
284// Used on mips32r6 for compare operations.
285// We use the last non-callee saved odd register for O32 ABI
286#define kDoubleCompareReg f19
287
288// FPU (coprocessor 1) control registers.
289// Currently only FCSR (#31) is implemented.
290struct FPUControlRegister {
291  bool is_valid() const { return reg_code == kFCSRRegister; }
292  bool is(FPUControlRegister creg) const { return reg_code == creg.reg_code; }
293  int code() const {
294    DCHECK(is_valid());
295    return reg_code;
296  }
297  int bit() const {
298    DCHECK(is_valid());
299    return 1 << reg_code;
300  }
301  void setcode(int f) {
302    reg_code = f;
303    DCHECK(is_valid());
304  }
305  // Unfortunately we can't make this private in a struct.
306  int reg_code;
307};
308
309const FPUControlRegister no_fpucreg = { kInvalidFPUControlRegister };
310const FPUControlRegister FCSR = { kFCSRRegister };
311
312// -----------------------------------------------------------------------------
313// Machine instruction Operands.
314
315// Class Operand represents a shifter operand in data processing instructions.
316class Operand BASE_EMBEDDED {
317 public:
318  // Immediate.
319  INLINE(explicit Operand(int32_t immediate,
320         RelocInfo::Mode rmode = RelocInfo::NONE32));
321  INLINE(explicit Operand(const ExternalReference& f));
322  INLINE(explicit Operand(const char* s));
323  INLINE(explicit Operand(Object** opp));
324  INLINE(explicit Operand(Context** cpp));
325  explicit Operand(Handle<Object> handle);
326  INLINE(explicit Operand(Smi* value));
327
328  // Register.
329  INLINE(explicit Operand(Register rm));
330
331  // Return true if this is a register operand.
332  INLINE(bool is_reg() const);
333
334  inline int32_t immediate() const {
335    DCHECK(!is_reg());
336    return imm32_;
337  }
338
339  Register rm() const { return rm_; }
340
341 private:
342  Register rm_;
343  int32_t imm32_;  // Valid if rm_ == no_reg.
344  RelocInfo::Mode rmode_;
345
346  friend class Assembler;
347  friend class MacroAssembler;
348};
349
350
351// On MIPS we have only one adressing mode with base_reg + offset.
352// Class MemOperand represents a memory operand in load and store instructions.
353class MemOperand : public Operand {
354 public:
355  // Immediate value attached to offset.
356  enum OffsetAddend {
357    offset_minus_one = -1,
358    offset_zero = 0
359  };
360
361  explicit MemOperand(Register rn, int32_t offset = 0);
362  explicit MemOperand(Register rn, int32_t unit, int32_t multiplier,
363                      OffsetAddend offset_addend = offset_zero);
364  int32_t offset() const { return offset_; }
365
366  bool OffsetIsInt16Encodable() const {
367    return is_int16(offset_);
368  }
369
370 private:
371  int32_t offset_;
372
373  friend class Assembler;
374};
375
376
377class Assembler : public AssemblerBase {
378 public:
379  // Create an assembler. Instructions and relocation information are emitted
380  // into a buffer, with the instructions starting from the beginning and the
381  // relocation information starting from the end of the buffer. See CodeDesc
382  // for a detailed comment on the layout (globals.h).
383  //
384  // If the provided buffer is NULL, the assembler allocates and grows its own
385  // buffer, and buffer_size determines the initial buffer size. The buffer is
386  // owned by the assembler and deallocated upon destruction of the assembler.
387  //
388  // If the provided buffer is not NULL, the assembler uses the provided buffer
389  // for code generation and assumes its size to be buffer_size. If the buffer
390  // is too small, a fatal error occurs. No deallocation of the buffer is done
391  // upon destruction of the assembler.
392  Assembler(Isolate* isolate, void* buffer, int buffer_size);
393  virtual ~Assembler() { }
394
395  // GetCode emits any pending (non-emitted) code and fills the descriptor
396  // desc. GetCode() is idempotent; it returns the same result if no other
397  // Assembler functions are invoked in between GetCode() calls.
398  void GetCode(CodeDesc* desc);
399
400  // Label operations & relative jumps (PPUM Appendix D).
401  //
402  // Takes a branch opcode (cc) and a label (L) and generates
403  // either a backward branch or a forward branch and links it
404  // to the label fixup chain. Usage:
405  //
406  // Label L;    // unbound label
407  // j(cc, &L);  // forward branch to unbound label
408  // bind(&L);   // bind label to the current pc
409  // j(cc, &L);  // backward branch to bound label
410  // bind(&L);   // illegal: a label may be bound only once
411  //
412  // Note: The same Label can be used for forward and backward branches
413  // but it may be bound only once.
414  void bind(Label* L);  // Binds an unbound label L to current code position.
415
416  enum OffsetSize : int { kOffset26 = 26, kOffset21 = 21, kOffset16 = 16 };
417
418  // Determines if Label is bound and near enough so that branch instruction
419  // can be used to reach it, instead of jump instruction.
420  bool is_near(Label* L);
421  bool is_near(Label* L, OffsetSize bits);
422  bool is_near_branch(Label* L);
423  inline bool is_near_pre_r6(Label* L) {
424    DCHECK(!IsMipsArchVariant(kMips32r6));
425    return pc_offset() - L->pos() < kMaxBranchOffset - 4 * kInstrSize;
426  }
427  inline bool is_near_r6(Label* L) {
428    DCHECK(IsMipsArchVariant(kMips32r6));
429    return pc_offset() - L->pos() < kMaxCompactBranchOffset - 4 * kInstrSize;
430  }
431
432  int BranchOffset(Instr instr);
433
434  // Returns the branch offset to the given label from the current code
435  // position. Links the label to the current position if it is still unbound.
436  // Manages the jump elimination optimization if the second parameter is true.
437  int32_t branch_offset_helper(Label* L, OffsetSize bits);
438  inline int32_t branch_offset(Label* L) {
439    return branch_offset_helper(L, OffsetSize::kOffset16);
440  }
441  inline int32_t branch_offset21(Label* L) {
442    return branch_offset_helper(L, OffsetSize::kOffset21);
443  }
444  inline int32_t branch_offset26(Label* L) {
445    return branch_offset_helper(L, OffsetSize::kOffset26);
446  }
447  inline int32_t shifted_branch_offset(Label* L) {
448    return branch_offset(L) >> 2;
449  }
450  inline int32_t shifted_branch_offset21(Label* L) {
451    return branch_offset21(L) >> 2;
452  }
453  inline int32_t shifted_branch_offset26(Label* L) {
454    return branch_offset26(L) >> 2;
455  }
456  uint32_t jump_address(Label* L);
457
458  // Puts a labels target address at the given position.
459  // The high 8 bits are set to zero.
460  void label_at_put(Label* L, int at_offset);
461
462  // Read/Modify the code target address in the branch/call instruction at pc.
463  static Address target_address_at(Address pc);
464  static void set_target_address_at(
465      Isolate* isolate, Address pc, Address target,
466      ICacheFlushMode icache_flush_mode = FLUSH_ICACHE_IF_NEEDED);
467  // On MIPS there is no Constant Pool so we skip that parameter.
468  INLINE(static Address target_address_at(Address pc, Address constant_pool)) {
469    return target_address_at(pc);
470  }
471  INLINE(static void set_target_address_at(
472      Isolate* isolate, Address pc, Address constant_pool, Address target,
473      ICacheFlushMode icache_flush_mode = FLUSH_ICACHE_IF_NEEDED)) {
474    set_target_address_at(isolate, pc, target, icache_flush_mode);
475  }
476  INLINE(static Address target_address_at(Address pc, Code* code)) {
477    Address constant_pool = code ? code->constant_pool() : NULL;
478    return target_address_at(pc, constant_pool);
479  }
480  INLINE(static void set_target_address_at(
481      Isolate* isolate, Address pc, Code* code, Address target,
482      ICacheFlushMode icache_flush_mode = FLUSH_ICACHE_IF_NEEDED)) {
483    Address constant_pool = code ? code->constant_pool() : NULL;
484    set_target_address_at(isolate, pc, constant_pool, target,
485                          icache_flush_mode);
486  }
487
488  // Return the code target address at a call site from the return address
489  // of that call in the instruction stream.
490  inline static Address target_address_from_return_address(Address pc);
491
492  static void QuietNaN(HeapObject* nan);
493
494  // This sets the branch destination (which gets loaded at the call address).
495  // This is for calls and branches within generated code.  The serializer
496  // has already deserialized the lui/ori instructions etc.
497  inline static void deserialization_set_special_target_at(
498      Isolate* isolate, Address instruction_payload, Code* code,
499      Address target) {
500    set_target_address_at(
501        isolate,
502        instruction_payload - kInstructionsFor32BitConstant * kInstrSize, code,
503        target);
504  }
505
506  // This sets the internal reference at the pc.
507  inline static void deserialization_set_target_internal_reference_at(
508      Isolate* isolate, Address pc, Address target,
509      RelocInfo::Mode mode = RelocInfo::INTERNAL_REFERENCE);
510
511  // Size of an instruction.
512  static const int kInstrSize = sizeof(Instr);
513
514  // Difference between address of current opcode and target address offset.
515  static const int kBranchPCOffset = 4;
516
517  // Here we are patching the address in the LUI/ORI instruction pair.
518  // These values are used in the serialization process and must be zero for
519  // MIPS platform, as Code, Embedded Object or External-reference pointers
520  // are split across two consecutive instructions and don't exist separately
521  // in the code, so the serializer should not step forwards in memory after
522  // a target is resolved and written.
523  static const int kSpecialTargetSize = 0;
524
525  // Number of consecutive instructions used to store 32bit constant. This
526  // constant is used in RelocInfo::target_address_address() function to tell
527  // serializer address of the instruction that follows LUI/ORI instruction
528  // pair.
529  static const int kInstructionsFor32BitConstant = 2;
530
531  // Distance between the instruction referring to the address of the call
532  // target and the return address.
533#ifdef _MIPS_ARCH_MIPS32R6
534  static const int kCallTargetAddressOffset = 3 * kInstrSize;
535#else
536  static const int kCallTargetAddressOffset = 4 * kInstrSize;
537#endif
538
539  // Distance between start of patched debug break slot and the emitted address
540  // to jump to.
541  static const int kPatchDebugBreakSlotAddressOffset = 4 * kInstrSize;
542
543  // Difference between address of current opcode and value read from pc
544  // register.
545  static const int kPcLoadDelta = 4;
546
547#ifdef _MIPS_ARCH_MIPS32R6
548  static const int kDebugBreakSlotInstructions = 3;
549#else
550  static const int kDebugBreakSlotInstructions = 4;
551#endif
552  static const int kDebugBreakSlotLength =
553      kDebugBreakSlotInstructions * kInstrSize;
554
555
556  // ---------------------------------------------------------------------------
557  // Code generation.
558
559  // Insert the smallest number of nop instructions
560  // possible to align the pc offset to a multiple
561  // of m. m must be a power of 2 (>= 4).
562  void Align(int m);
563  // Insert the smallest number of zero bytes possible to align the pc offset
564  // to a mulitple of m. m must be a power of 2 (>= 2).
565  void DataAlign(int m);
566  // Aligns code to something that's optimal for a jump target for the platform.
567  void CodeTargetAlign();
568
569  // Different nop operations are used by the code generator to detect certain
570  // states of the generated code.
571  enum NopMarkerTypes {
572    NON_MARKING_NOP = 0,
573    DEBUG_BREAK_NOP,
574    // IC markers.
575    PROPERTY_ACCESS_INLINED,
576    PROPERTY_ACCESS_INLINED_CONTEXT,
577    PROPERTY_ACCESS_INLINED_CONTEXT_DONT_DELETE,
578    // Helper values.
579    LAST_CODE_MARKER,
580    FIRST_IC_MARKER = PROPERTY_ACCESS_INLINED,
581    // Code aging
582    CODE_AGE_MARKER_NOP = 6,
583    CODE_AGE_SEQUENCE_NOP
584  };
585
586  // Type == 0 is the default non-marking nop. For mips this is a
587  // sll(zero_reg, zero_reg, 0). We use rt_reg == at for non-zero
588  // marking, to avoid conflict with ssnop and ehb instructions.
589  void nop(unsigned int type = 0) {
590    DCHECK(type < 32);
591    Register nop_rt_reg = (type == 0) ? zero_reg : at;
592    sll(zero_reg, nop_rt_reg, type, true);
593  }
594
595
596  // --------Branch-and-jump-instructions----------
597  // We don't use likely variant of instructions.
598  void b(int16_t offset);
599  inline void b(Label* L) { b(shifted_branch_offset(L)); }
600  void bal(int16_t offset);
601  inline void bal(Label* L) { bal(shifted_branch_offset(L)); }
602  void bc(int32_t offset);
603  inline void bc(Label* L) { bc(shifted_branch_offset26(L)); }
604  void balc(int32_t offset);
605  inline void balc(Label* L) { balc(shifted_branch_offset26(L)); }
606
607  void beq(Register rs, Register rt, int16_t offset);
608  inline void beq(Register rs, Register rt, Label* L) {
609    beq(rs, rt, shifted_branch_offset(L));
610  }
611  void bgez(Register rs, int16_t offset);
612  void bgezc(Register rt, int16_t offset);
613  inline void bgezc(Register rt, Label* L) {
614    bgezc(rt, shifted_branch_offset(L));
615  }
616  void bgeuc(Register rs, Register rt, int16_t offset);
617  inline void bgeuc(Register rs, Register rt, Label* L) {
618    bgeuc(rs, rt, shifted_branch_offset(L));
619  }
620  void bgec(Register rs, Register rt, int16_t offset);
621  inline void bgec(Register rs, Register rt, Label* L) {
622    bgec(rs, rt, shifted_branch_offset(L));
623  }
624  void bgezal(Register rs, int16_t offset);
625  void bgezalc(Register rt, int16_t offset);
626  inline void bgezalc(Register rt, Label* L) {
627    bgezalc(rt, shifted_branch_offset(L));
628  }
629  void bgezall(Register rs, int16_t offset);
630  inline void bgezall(Register rs, Label* L) {
631    bgezall(rs, branch_offset(L) >> 2);
632  }
633  void bgtz(Register rs, int16_t offset);
634  void bgtzc(Register rt, int16_t offset);
635  inline void bgtzc(Register rt, Label* L) {
636    bgtzc(rt, shifted_branch_offset(L));
637  }
638  void blez(Register rs, int16_t offset);
639  void blezc(Register rt, int16_t offset);
640  inline void blezc(Register rt, Label* L) {
641    blezc(rt, shifted_branch_offset(L));
642  }
643  void bltz(Register rs, int16_t offset);
644  void bltzc(Register rt, int16_t offset);
645  inline void bltzc(Register rt, Label* L) {
646    bltzc(rt, shifted_branch_offset(L));
647  }
648  void bltuc(Register rs, Register rt, int16_t offset);
649  inline void bltuc(Register rs, Register rt, Label* L) {
650    bltuc(rs, rt, shifted_branch_offset(L));
651  }
652  void bltc(Register rs, Register rt, int16_t offset);
653  inline void bltc(Register rs, Register rt, Label* L) {
654    bltc(rs, rt, shifted_branch_offset(L));
655  }
656  void bltzal(Register rs, int16_t offset);
657  void blezalc(Register rt, int16_t offset);
658  inline void blezalc(Register rt, Label* L) {
659    blezalc(rt, shifted_branch_offset(L));
660  }
661  void bltzalc(Register rt, int16_t offset);
662  inline void bltzalc(Register rt, Label* L) {
663    bltzalc(rt, shifted_branch_offset(L));
664  }
665  void bgtzalc(Register rt, int16_t offset);
666  inline void bgtzalc(Register rt, Label* L) {
667    bgtzalc(rt, shifted_branch_offset(L));
668  }
669  void beqzalc(Register rt, int16_t offset);
670  inline void beqzalc(Register rt, Label* L) {
671    beqzalc(rt, shifted_branch_offset(L));
672  }
673  void beqc(Register rs, Register rt, int16_t offset);
674  inline void beqc(Register rs, Register rt, Label* L) {
675    beqc(rs, rt, shifted_branch_offset(L));
676  }
677  void beqzc(Register rs, int32_t offset);
678  inline void beqzc(Register rs, Label* L) {
679    beqzc(rs, shifted_branch_offset21(L));
680  }
681  void bnezalc(Register rt, int16_t offset);
682  inline void bnezalc(Register rt, Label* L) {
683    bnezalc(rt, shifted_branch_offset(L));
684  }
685  void bnec(Register rs, Register rt, int16_t offset);
686  inline void bnec(Register rs, Register rt, Label* L) {
687    bnec(rs, rt, shifted_branch_offset(L));
688  }
689  void bnezc(Register rt, int32_t offset);
690  inline void bnezc(Register rt, Label* L) {
691    bnezc(rt, shifted_branch_offset21(L));
692  }
693  void bne(Register rs, Register rt, int16_t offset);
694  inline void bne(Register rs, Register rt, Label* L) {
695    bne(rs, rt, shifted_branch_offset(L));
696  }
697  void bovc(Register rs, Register rt, int16_t offset);
698  inline void bovc(Register rs, Register rt, Label* L) {
699    bovc(rs, rt, shifted_branch_offset(L));
700  }
701  void bnvc(Register rs, Register rt, int16_t offset);
702  inline void bnvc(Register rs, Register rt, Label* L) {
703    bnvc(rs, rt, shifted_branch_offset(L));
704  }
705
706  // Never use the int16_t b(l)cond version with a branch offset
707  // instead of using the Label* version.
708
709  // Jump targets must be in the current 256 MB-aligned region. i.e. 28 bits.
710  void j(int32_t target);
711  void jal(int32_t target);
712  void jalr(Register rs, Register rd = ra);
713  void jr(Register target);
714  void jic(Register rt, int16_t offset);
715  void jialc(Register rt, int16_t offset);
716
717
718  // -------Data-processing-instructions---------
719
720  // Arithmetic.
721  void addu(Register rd, Register rs, Register rt);
722  void subu(Register rd, Register rs, Register rt);
723  void mult(Register rs, Register rt);
724  void multu(Register rs, Register rt);
725  void div(Register rs, Register rt);
726  void divu(Register rs, Register rt);
727  void div(Register rd, Register rs, Register rt);
728  void divu(Register rd, Register rs, Register rt);
729  void mod(Register rd, Register rs, Register rt);
730  void modu(Register rd, Register rs, Register rt);
731  void mul(Register rd, Register rs, Register rt);
732  void muh(Register rd, Register rs, Register rt);
733  void mulu(Register rd, Register rs, Register rt);
734  void muhu(Register rd, Register rs, Register rt);
735
736  void addiu(Register rd, Register rs, int32_t j);
737
738  // Logical.
739  void and_(Register rd, Register rs, Register rt);
740  void or_(Register rd, Register rs, Register rt);
741  void xor_(Register rd, Register rs, Register rt);
742  void nor(Register rd, Register rs, Register rt);
743
744  void andi(Register rd, Register rs, int32_t j);
745  void ori(Register rd, Register rs, int32_t j);
746  void xori(Register rd, Register rs, int32_t j);
747  void lui(Register rd, int32_t j);
748  void aui(Register rs, Register rt, int32_t j);
749
750  // Shifts.
751  // Please note: sll(zero_reg, zero_reg, x) instructions are reserved as nop
752  // and may cause problems in normal code. coming_from_nop makes sure this
753  // doesn't happen.
754  void sll(Register rd, Register rt, uint16_t sa, bool coming_from_nop = false);
755  void sllv(Register rd, Register rt, Register rs);
756  void srl(Register rd, Register rt, uint16_t sa);
757  void srlv(Register rd, Register rt, Register rs);
758  void sra(Register rt, Register rd, uint16_t sa);
759  void srav(Register rt, Register rd, Register rs);
760  void rotr(Register rd, Register rt, uint16_t sa);
761  void rotrv(Register rd, Register rt, Register rs);
762
763  // ------------Memory-instructions-------------
764
765  void lb(Register rd, const MemOperand& rs);
766  void lbu(Register rd, const MemOperand& rs);
767  void lh(Register rd, const MemOperand& rs);
768  void lhu(Register rd, const MemOperand& rs);
769  void lw(Register rd, const MemOperand& rs);
770  void lwl(Register rd, const MemOperand& rs);
771  void lwr(Register rd, const MemOperand& rs);
772  void sb(Register rd, const MemOperand& rs);
773  void sh(Register rd, const MemOperand& rs);
774  void sw(Register rd, const MemOperand& rs);
775  void swl(Register rd, const MemOperand& rs);
776  void swr(Register rd, const MemOperand& rs);
777
778
779  // ---------PC-Relative-instructions-----------
780
781  void addiupc(Register rs, int32_t imm19);
782  void lwpc(Register rs, int32_t offset19);
783  void auipc(Register rs, int16_t imm16);
784  void aluipc(Register rs, int16_t imm16);
785
786
787  // ----------------Prefetch--------------------
788
789  void pref(int32_t hint, const MemOperand& rs);
790
791
792  // -------------Misc-instructions--------------
793
794  // Break / Trap instructions.
795  void break_(uint32_t code, bool break_as_stop = false);
796  void stop(const char* msg, uint32_t code = kMaxStopCode);
797  void tge(Register rs, Register rt, uint16_t code);
798  void tgeu(Register rs, Register rt, uint16_t code);
799  void tlt(Register rs, Register rt, uint16_t code);
800  void tltu(Register rs, Register rt, uint16_t code);
801  void teq(Register rs, Register rt, uint16_t code);
802  void tne(Register rs, Register rt, uint16_t code);
803
804  // Memory barrier instruction.
805  void sync();
806
807  // Move from HI/LO register.
808  void mfhi(Register rd);
809  void mflo(Register rd);
810
811  // Set on less than.
812  void slt(Register rd, Register rs, Register rt);
813  void sltu(Register rd, Register rs, Register rt);
814  void slti(Register rd, Register rs, int32_t j);
815  void sltiu(Register rd, Register rs, int32_t j);
816
817  // Conditional move.
818  void movz(Register rd, Register rs, Register rt);
819  void movn(Register rd, Register rs, Register rt);
820  void movt(Register rd, Register rs, uint16_t cc = 0);
821  void movf(Register rd, Register rs, uint16_t cc = 0);
822
823  void sel(SecondaryField fmt, FPURegister fd, FPURegister fs, FPURegister ft);
824  void sel_s(FPURegister fd, FPURegister fs, FPURegister ft);
825  void sel_d(FPURegister fd, FPURegister fs, FPURegister ft);
826  void seleqz(Register rd, Register rs, Register rt);
827  void seleqz(SecondaryField fmt, FPURegister fd, FPURegister fs,
828              FPURegister ft);
829  void selnez(Register rd, Register rs, Register rt);
830  void selnez(SecondaryField fmt, FPURegister fd, FPURegister fs,
831              FPURegister ft);
832  void seleqz_d(FPURegister fd, FPURegister fs, FPURegister ft);
833  void seleqz_s(FPURegister fd, FPURegister fs, FPURegister ft);
834  void selnez_d(FPURegister fd, FPURegister fs, FPURegister ft);
835  void selnez_s(FPURegister fd, FPURegister fs, FPURegister ft);
836
837  void movz_s(FPURegister fd, FPURegister fs, Register rt);
838  void movz_d(FPURegister fd, FPURegister fs, Register rt);
839  void movt_s(FPURegister fd, FPURegister fs, uint16_t cc = 0);
840  void movt_d(FPURegister fd, FPURegister fs, uint16_t cc = 0);
841  void movf_s(FPURegister fd, FPURegister fs, uint16_t cc = 0);
842  void movf_d(FPURegister fd, FPURegister fs, uint16_t cc = 0);
843  void movn_s(FPURegister fd, FPURegister fs, Register rt);
844  void movn_d(FPURegister fd, FPURegister fs, Register rt);
845  // Bit twiddling.
846  void clz(Register rd, Register rs);
847  void ins_(Register rt, Register rs, uint16_t pos, uint16_t size);
848  void ext_(Register rt, Register rs, uint16_t pos, uint16_t size);
849  void bitswap(Register rd, Register rt);
850  void align(Register rd, Register rs, Register rt, uint8_t bp);
851
852  void wsbh(Register rd, Register rt);
853  void seh(Register rd, Register rt);
854  void seb(Register rd, Register rt);
855
856  // --------Coprocessor-instructions----------------
857
858  // Load, store, and move.
859  void lwc1(FPURegister fd, const MemOperand& src);
860  void ldc1(FPURegister fd, const MemOperand& src);
861
862  void swc1(FPURegister fs, const MemOperand& dst);
863  void sdc1(FPURegister fs, const MemOperand& dst);
864
865  void mtc1(Register rt, FPURegister fs);
866  void mthc1(Register rt, FPURegister fs);
867
868  void mfc1(Register rt, FPURegister fs);
869  void mfhc1(Register rt, FPURegister fs);
870
871  void ctc1(Register rt, FPUControlRegister fs);
872  void cfc1(Register rt, FPUControlRegister fs);
873
874  // Arithmetic.
875  void add_s(FPURegister fd, FPURegister fs, FPURegister ft);
876  void add_d(FPURegister fd, FPURegister fs, FPURegister ft);
877  void sub_s(FPURegister fd, FPURegister fs, FPURegister ft);
878  void sub_d(FPURegister fd, FPURegister fs, FPURegister ft);
879  void mul_s(FPURegister fd, FPURegister fs, FPURegister ft);
880  void mul_d(FPURegister fd, FPURegister fs, FPURegister ft);
881  void madd_s(FPURegister fd, FPURegister fr, FPURegister fs, FPURegister ft);
882  void madd_d(FPURegister fd, FPURegister fr, FPURegister fs, FPURegister ft);
883  void msub_s(FPURegister fd, FPURegister fr, FPURegister fs, FPURegister ft);
884  void msub_d(FPURegister fd, FPURegister fr, FPURegister fs, FPURegister ft);
885  void maddf_s(FPURegister fd, FPURegister fs, FPURegister ft);
886  void maddf_d(FPURegister fd, FPURegister fs, FPURegister ft);
887  void msubf_s(FPURegister fd, FPURegister fs, FPURegister ft);
888  void msubf_d(FPURegister fd, FPURegister fs, FPURegister ft);
889  void div_s(FPURegister fd, FPURegister fs, FPURegister ft);
890  void div_d(FPURegister fd, FPURegister fs, FPURegister ft);
891  void abs_s(FPURegister fd, FPURegister fs);
892  void abs_d(FPURegister fd, FPURegister fs);
893  void mov_d(FPURegister fd, FPURegister fs);
894  void mov_s(FPURegister fd, FPURegister fs);
895  void neg_s(FPURegister fd, FPURegister fs);
896  void neg_d(FPURegister fd, FPURegister fs);
897  void sqrt_s(FPURegister fd, FPURegister fs);
898  void sqrt_d(FPURegister fd, FPURegister fs);
899  void rsqrt_s(FPURegister fd, FPURegister fs);
900  void rsqrt_d(FPURegister fd, FPURegister fs);
901  void recip_d(FPURegister fd, FPURegister fs);
902  void recip_s(FPURegister fd, FPURegister fs);
903
904  // Conversion.
905  void cvt_w_s(FPURegister fd, FPURegister fs);
906  void cvt_w_d(FPURegister fd, FPURegister fs);
907  void trunc_w_s(FPURegister fd, FPURegister fs);
908  void trunc_w_d(FPURegister fd, FPURegister fs);
909  void round_w_s(FPURegister fd, FPURegister fs);
910  void round_w_d(FPURegister fd, FPURegister fs);
911  void floor_w_s(FPURegister fd, FPURegister fs);
912  void floor_w_d(FPURegister fd, FPURegister fs);
913  void ceil_w_s(FPURegister fd, FPURegister fs);
914  void ceil_w_d(FPURegister fd, FPURegister fs);
915  void rint_s(FPURegister fd, FPURegister fs);
916  void rint_d(FPURegister fd, FPURegister fs);
917  void rint(SecondaryField fmt, FPURegister fd, FPURegister fs);
918
919  void cvt_l_s(FPURegister fd, FPURegister fs);
920  void cvt_l_d(FPURegister fd, FPURegister fs);
921  void trunc_l_s(FPURegister fd, FPURegister fs);
922  void trunc_l_d(FPURegister fd, FPURegister fs);
923  void round_l_s(FPURegister fd, FPURegister fs);
924  void round_l_d(FPURegister fd, FPURegister fs);
925  void floor_l_s(FPURegister fd, FPURegister fs);
926  void floor_l_d(FPURegister fd, FPURegister fs);
927  void ceil_l_s(FPURegister fd, FPURegister fs);
928  void ceil_l_d(FPURegister fd, FPURegister fs);
929
930  void class_s(FPURegister fd, FPURegister fs);
931  void class_d(FPURegister fd, FPURegister fs);
932
933  void min(SecondaryField fmt, FPURegister fd, FPURegister fs, FPURegister ft);
934  void mina(SecondaryField fmt, FPURegister fd, FPURegister fs, FPURegister ft);
935  void max(SecondaryField fmt, FPURegister fd, FPURegister fs, FPURegister ft);
936  void maxa(SecondaryField fmt, FPURegister fd, FPURegister fs, FPURegister ft);
937  void min_s(FPURegister fd, FPURegister fs, FPURegister ft);
938  void min_d(FPURegister fd, FPURegister fs, FPURegister ft);
939  void max_s(FPURegister fd, FPURegister fs, FPURegister ft);
940  void max_d(FPURegister fd, FPURegister fs, FPURegister ft);
941  void mina_s(FPURegister fd, FPURegister fs, FPURegister ft);
942  void mina_d(FPURegister fd, FPURegister fs, FPURegister ft);
943  void maxa_s(FPURegister fd, FPURegister fs, FPURegister ft);
944  void maxa_d(FPURegister fd, FPURegister fs, FPURegister ft);
945
946  void cvt_s_w(FPURegister fd, FPURegister fs);
947  void cvt_s_l(FPURegister fd, FPURegister fs);
948  void cvt_s_d(FPURegister fd, FPURegister fs);
949
950  void cvt_d_w(FPURegister fd, FPURegister fs);
951  void cvt_d_l(FPURegister fd, FPURegister fs);
952  void cvt_d_s(FPURegister fd, FPURegister fs);
953
954  // Conditions and branches for MIPSr6.
955  void cmp(FPUCondition cond, SecondaryField fmt,
956         FPURegister fd, FPURegister ft, FPURegister fs);
957  void cmp_s(FPUCondition cond, FPURegister fd, FPURegister fs, FPURegister ft);
958  void cmp_d(FPUCondition cond, FPURegister fd, FPURegister fs, FPURegister ft);
959
960  void bc1eqz(int16_t offset, FPURegister ft);
961  inline void bc1eqz(Label* L, FPURegister ft) {
962    bc1eqz(shifted_branch_offset(L), ft);
963  }
964  void bc1nez(int16_t offset, FPURegister ft);
965  inline void bc1nez(Label* L, FPURegister ft) {
966    bc1nez(shifted_branch_offset(L), ft);
967  }
968
969  // Conditions and branches for non MIPSr6.
970  void c(FPUCondition cond, SecondaryField fmt,
971         FPURegister ft, FPURegister fs, uint16_t cc = 0);
972  void c_s(FPUCondition cond, FPURegister ft, FPURegister fs, uint16_t cc = 0);
973  void c_d(FPUCondition cond, FPURegister ft, FPURegister fs, uint16_t cc = 0);
974
975  void bc1f(int16_t offset, uint16_t cc = 0);
976  inline void bc1f(Label* L, uint16_t cc = 0) {
977    bc1f(shifted_branch_offset(L), cc);
978  }
979  void bc1t(int16_t offset, uint16_t cc = 0);
980  inline void bc1t(Label* L, uint16_t cc = 0) {
981    bc1t(shifted_branch_offset(L), cc);
982  }
983  void fcmp(FPURegister src1, const double src2, FPUCondition cond);
984
985  // Check the code size generated from label to here.
986  int SizeOfCodeGeneratedSince(Label* label) {
987    return pc_offset() - label->pos();
988  }
989
990  // Check the number of instructions generated from label to here.
991  int InstructionsGeneratedSince(Label* label) {
992    return SizeOfCodeGeneratedSince(label) / kInstrSize;
993  }
994
995  // Class for scoping postponing the trampoline pool generation.
996  class BlockTrampolinePoolScope {
997   public:
998    explicit BlockTrampolinePoolScope(Assembler* assem) : assem_(assem) {
999      assem_->StartBlockTrampolinePool();
1000    }
1001    ~BlockTrampolinePoolScope() {
1002      assem_->EndBlockTrampolinePool();
1003    }
1004
1005   private:
1006    Assembler* assem_;
1007
1008    DISALLOW_IMPLICIT_CONSTRUCTORS(BlockTrampolinePoolScope);
1009  };
1010
1011  // Class for postponing the assembly buffer growth. Typically used for
1012  // sequences of instructions that must be emitted as a unit, before
1013  // buffer growth (and relocation) can occur.
1014  // This blocking scope is not nestable.
1015  class BlockGrowBufferScope {
1016   public:
1017    explicit BlockGrowBufferScope(Assembler* assem) : assem_(assem) {
1018      assem_->StartBlockGrowBuffer();
1019    }
1020    ~BlockGrowBufferScope() {
1021      assem_->EndBlockGrowBuffer();
1022    }
1023
1024   private:
1025    Assembler* assem_;
1026
1027    DISALLOW_IMPLICIT_CONSTRUCTORS(BlockGrowBufferScope);
1028  };
1029
1030  // Debugging.
1031
1032  // Mark generator continuation.
1033  void RecordGeneratorContinuation();
1034
1035  // Mark address of a debug break slot.
1036  void RecordDebugBreakSlot(RelocInfo::Mode mode);
1037
1038  // Record the AST id of the CallIC being compiled, so that it can be placed
1039  // in the relocation information.
1040  void SetRecordedAstId(TypeFeedbackId ast_id) {
1041    DCHECK(recorded_ast_id_.IsNone());
1042    recorded_ast_id_ = ast_id;
1043  }
1044
1045  TypeFeedbackId RecordedAstId() {
1046    DCHECK(!recorded_ast_id_.IsNone());
1047    return recorded_ast_id_;
1048  }
1049
1050  void ClearRecordedAstId() { recorded_ast_id_ = TypeFeedbackId::None(); }
1051
1052  // Record a comment relocation entry that can be used by a disassembler.
1053  // Use --code-comments to enable.
1054  void RecordComment(const char* msg);
1055
1056  // Record a deoptimization reason that can be used by a log or cpu profiler.
1057  // Use --trace-deopt to enable.
1058  void RecordDeoptReason(DeoptimizeReason reason, SourcePosition position,
1059                         int id);
1060
1061  static int RelocateInternalReference(RelocInfo::Mode rmode, byte* pc,
1062                                       intptr_t pc_delta);
1063
1064  // Writes a single byte or word of data in the code stream.  Used for
1065  // inline tables, e.g., jump-tables.
1066  void db(uint8_t data);
1067  void dd(uint32_t data);
1068  void dq(uint64_t data);
1069  void dp(uintptr_t data) { dd(data); }
1070  void dd(Label* label);
1071
1072  // Postpone the generation of the trampoline pool for the specified number of
1073  // instructions.
1074  void BlockTrampolinePoolFor(int instructions);
1075
1076  // Check if there is less than kGap bytes available in the buffer.
1077  // If this is the case, we need to grow the buffer before emitting
1078  // an instruction or relocation information.
1079  inline bool overflow() const { return pc_ >= reloc_info_writer.pos() - kGap; }
1080
1081  // Get the number of bytes available in the buffer.
1082  inline int available_space() const { return reloc_info_writer.pos() - pc_; }
1083
1084  // Read/patch instructions.
1085  static Instr instr_at(byte* pc) { return *reinterpret_cast<Instr*>(pc); }
1086  static void instr_at_put(byte* pc, Instr instr) {
1087    *reinterpret_cast<Instr*>(pc) = instr;
1088  }
1089  Instr instr_at(int pos) { return *reinterpret_cast<Instr*>(buffer_ + pos); }
1090  void instr_at_put(int pos, Instr instr) {
1091    *reinterpret_cast<Instr*>(buffer_ + pos) = instr;
1092  }
1093
1094  // Check if an instruction is a branch of some kind.
1095  static bool IsBranch(Instr instr);
1096  static bool IsBc(Instr instr);
1097  static bool IsBzc(Instr instr);
1098  static bool IsBeq(Instr instr);
1099  static bool IsBne(Instr instr);
1100  static bool IsBeqzc(Instr instr);
1101  static bool IsBnezc(Instr instr);
1102  static bool IsBeqc(Instr instr);
1103  static bool IsBnec(Instr instr);
1104  static bool IsJicOrJialc(Instr instr);
1105
1106  static bool IsJump(Instr instr);
1107  static bool IsJ(Instr instr);
1108  static bool IsLui(Instr instr);
1109  static bool IsOri(Instr instr);
1110
1111  static bool IsJal(Instr instr);
1112  static bool IsJr(Instr instr);
1113  static bool IsJalr(Instr instr);
1114
1115  static bool IsNop(Instr instr, unsigned int type);
1116  static bool IsPop(Instr instr);
1117  static bool IsPush(Instr instr);
1118  static bool IsLwRegFpOffset(Instr instr);
1119  static bool IsSwRegFpOffset(Instr instr);
1120  static bool IsLwRegFpNegOffset(Instr instr);
1121  static bool IsSwRegFpNegOffset(Instr instr);
1122
1123  static Register GetRtReg(Instr instr);
1124  static Register GetRsReg(Instr instr);
1125  static Register GetRdReg(Instr instr);
1126
1127  static uint32_t GetRt(Instr instr);
1128  static uint32_t GetRtField(Instr instr);
1129  static uint32_t GetRs(Instr instr);
1130  static uint32_t GetRsField(Instr instr);
1131  static uint32_t GetRd(Instr instr);
1132  static uint32_t GetRdField(Instr instr);
1133  static uint32_t GetSa(Instr instr);
1134  static uint32_t GetSaField(Instr instr);
1135  static uint32_t GetOpcodeField(Instr instr);
1136  static uint32_t GetFunction(Instr instr);
1137  static uint32_t GetFunctionField(Instr instr);
1138  static uint32_t GetImmediate16(Instr instr);
1139  static uint32_t GetLabelConst(Instr instr);
1140
1141  static int32_t GetBranchOffset(Instr instr);
1142  static bool IsLw(Instr instr);
1143  static int16_t GetLwOffset(Instr instr);
1144  static int16_t GetJicOrJialcOffset(Instr instr);
1145  static int16_t GetLuiOffset(Instr instr);
1146  static Instr SetLwOffset(Instr instr, int16_t offset);
1147
1148  static bool IsSw(Instr instr);
1149  static Instr SetSwOffset(Instr instr, int16_t offset);
1150  static bool IsAddImmediate(Instr instr);
1151  static Instr SetAddImmediateOffset(Instr instr, int16_t offset);
1152  static uint32_t CreateTargetAddress(Instr instr_lui, Instr instr_jic);
1153  static void UnpackTargetAddress(uint32_t address, int16_t& lui_offset,
1154                                  int16_t& jic_offset);
1155  static void UnpackTargetAddressUnsigned(uint32_t address,
1156                                          uint32_t& lui_offset,
1157                                          uint32_t& jic_offset);
1158
1159  static bool IsAndImmediate(Instr instr);
1160  static bool IsEmittedConstant(Instr instr);
1161
1162  void CheckTrampolinePool();
1163
1164  void PatchConstantPoolAccessInstruction(int pc_offset, int offset,
1165                                          ConstantPoolEntry::Access access,
1166                                          ConstantPoolEntry::Type type) {
1167    // No embedded constant pool support.
1168    UNREACHABLE();
1169  }
1170
1171  bool IsPrevInstrCompactBranch() { return prev_instr_compact_branch_; }
1172
1173  inline int UnboundLabelsCount() { return unbound_labels_count_; }
1174
1175 protected:
1176  // Load Scaled Address instruction.
1177  void lsa(Register rd, Register rt, Register rs, uint8_t sa);
1178
1179  // Helpers.
1180  void LoadRegPlusOffsetToAt(const MemOperand& src);
1181  int32_t LoadRegPlusUpperOffsetPartToAt(const MemOperand& src);
1182  int32_t LoadUpperOffsetForTwoMemoryAccesses(const MemOperand& src);
1183
1184  // Relocation for a type-recording IC has the AST id added to it.  This
1185  // member variable is a way to pass the information from the call site to
1186  // the relocation info.
1187  TypeFeedbackId recorded_ast_id_;
1188
1189  int32_t buffer_space() const { return reloc_info_writer.pos() - pc_; }
1190
1191  // Decode branch instruction at pos and return branch target pos.
1192  int target_at(int pos, bool is_internal);
1193
1194  // Patch branch instruction at pos to branch to given branch target pos.
1195  void target_at_put(int pos, int target_pos, bool is_internal);
1196
1197  // Say if we need to relocate with this mode.
1198  bool MustUseReg(RelocInfo::Mode rmode);
1199
1200  // Record reloc info for current pc_.
1201  void RecordRelocInfo(RelocInfo::Mode rmode, intptr_t data = 0);
1202
1203  // Block the emission of the trampoline pool before pc_offset.
1204  void BlockTrampolinePoolBefore(int pc_offset) {
1205    if (no_trampoline_pool_before_ < pc_offset)
1206      no_trampoline_pool_before_ = pc_offset;
1207  }
1208
1209  void StartBlockTrampolinePool() {
1210    trampoline_pool_blocked_nesting_++;
1211  }
1212
1213  void EndBlockTrampolinePool() {
1214    trampoline_pool_blocked_nesting_--;
1215  }
1216
1217  bool is_trampoline_pool_blocked() const {
1218    return trampoline_pool_blocked_nesting_ > 0;
1219  }
1220
1221  bool has_exception() const {
1222    return internal_trampoline_exception_;
1223  }
1224
1225  void DoubleAsTwoUInt32(double d, uint32_t* lo, uint32_t* hi);
1226
1227  bool is_trampoline_emitted() const {
1228    return trampoline_emitted_;
1229  }
1230
1231  // Temporarily block automatic assembly buffer growth.
1232  void StartBlockGrowBuffer() {
1233    DCHECK(!block_buffer_growth_);
1234    block_buffer_growth_ = true;
1235  }
1236
1237  void EndBlockGrowBuffer() {
1238    DCHECK(block_buffer_growth_);
1239    block_buffer_growth_ = false;
1240  }
1241
1242  bool is_buffer_growth_blocked() const {
1243    return block_buffer_growth_;
1244  }
1245
1246  void EmitForbiddenSlotInstruction() {
1247    if (IsPrevInstrCompactBranch()) {
1248      nop();
1249    }
1250  }
1251
1252  inline void CheckTrampolinePoolQuick(int extra_instructions = 0);
1253
1254  inline void CheckBuffer();
1255
1256 private:
1257  inline static void set_target_internal_reference_encoded_at(Address pc,
1258                                                              Address target);
1259
1260  // Buffer size and constant pool distance are checked together at regular
1261  // intervals of kBufferCheckInterval emitted bytes.
1262  static const int kBufferCheckInterval = 1*KB/2;
1263
1264  // Code generation.
1265  // The relocation writer's position is at least kGap bytes below the end of
1266  // the generated instructions. This is so that multi-instruction sequences do
1267  // not have to check for overflow. The same is true for writes of large
1268  // relocation info entries.
1269  static const int kGap = 32;
1270
1271
1272  // Repeated checking whether the trampoline pool should be emitted is rather
1273  // expensive. By default we only check again once a number of instructions
1274  // has been generated.
1275  static const int kCheckConstIntervalInst = 32;
1276  static const int kCheckConstInterval = kCheckConstIntervalInst * kInstrSize;
1277
1278  int next_buffer_check_;  // pc offset of next buffer check.
1279
1280  // Emission of the trampoline pool may be blocked in some code sequences.
1281  int trampoline_pool_blocked_nesting_;  // Block emission if this is not zero.
1282  int no_trampoline_pool_before_;  // Block emission before this pc offset.
1283
1284  // Keep track of the last emitted pool to guarantee a maximal distance.
1285  int last_trampoline_pool_end_;  // pc offset of the end of the last pool.
1286
1287  // Automatic growth of the assembly buffer may be blocked for some sequences.
1288  bool block_buffer_growth_;  // Block growth when true.
1289
1290  // Relocation information generation.
1291  // Each relocation is encoded as a variable size value.
1292  static const int kMaxRelocSize = RelocInfoWriter::kMaxSize;
1293  RelocInfoWriter reloc_info_writer;
1294
1295  // The bound position, before this we cannot do instruction elimination.
1296  int last_bound_pos_;
1297
1298  // Readable constants for compact branch handling in emit()
1299  enum class CompactBranchType : bool { NO = false, COMPACT_BRANCH = true };
1300
1301  // Code emission.
1302  void GrowBuffer();
1303  inline void emit(Instr x,
1304                   CompactBranchType is_compact_branch = CompactBranchType::NO);
1305  inline void emit(uint64_t x);
1306  inline void CheckForEmitInForbiddenSlot();
1307  template <typename T>
1308  inline void EmitHelper(T x);
1309  inline void EmitHelper(Instr x, CompactBranchType is_compact_branch);
1310
1311  // Instruction generation.
1312  // We have 3 different kind of encoding layout on MIPS.
1313  // However due to many different types of objects encoded in the same fields
1314  // we have quite a few aliases for each mode.
1315  // Using the same structure to refer to Register and FPURegister would spare a
1316  // few aliases, but mixing both does not look clean to me.
1317  // Anyway we could surely implement this differently.
1318
1319  void GenInstrRegister(Opcode opcode,
1320                        Register rs,
1321                        Register rt,
1322                        Register rd,
1323                        uint16_t sa = 0,
1324                        SecondaryField func = NULLSF);
1325
1326  void GenInstrRegister(Opcode opcode,
1327                        Register rs,
1328                        Register rt,
1329                        uint16_t msb,
1330                        uint16_t lsb,
1331                        SecondaryField func);
1332
1333  void GenInstrRegister(Opcode opcode,
1334                        SecondaryField fmt,
1335                        FPURegister ft,
1336                        FPURegister fs,
1337                        FPURegister fd,
1338                        SecondaryField func = NULLSF);
1339
1340  void GenInstrRegister(Opcode opcode,
1341                        FPURegister fr,
1342                        FPURegister ft,
1343                        FPURegister fs,
1344                        FPURegister fd,
1345                        SecondaryField func = NULLSF);
1346
1347  void GenInstrRegister(Opcode opcode,
1348                        SecondaryField fmt,
1349                        Register rt,
1350                        FPURegister fs,
1351                        FPURegister fd,
1352                        SecondaryField func = NULLSF);
1353
1354  void GenInstrRegister(Opcode opcode,
1355                        SecondaryField fmt,
1356                        Register rt,
1357                        FPUControlRegister fs,
1358                        SecondaryField func = NULLSF);
1359
1360  void GenInstrImmediate(
1361      Opcode opcode, Register rs, Register rt, int32_t j,
1362      CompactBranchType is_compact_branch = CompactBranchType::NO);
1363  void GenInstrImmediate(
1364      Opcode opcode, Register rs, SecondaryField SF, int32_t j,
1365      CompactBranchType is_compact_branch = CompactBranchType::NO);
1366  void GenInstrImmediate(
1367      Opcode opcode, Register r1, FPURegister r2, int32_t j,
1368      CompactBranchType is_compact_branch = CompactBranchType::NO);
1369  void GenInstrImmediate(
1370      Opcode opcode, Register rs, int32_t offset21,
1371      CompactBranchType is_compact_branch = CompactBranchType::NO);
1372  void GenInstrImmediate(Opcode opcode, Register rs, uint32_t offset21);
1373  void GenInstrImmediate(
1374      Opcode opcode, int32_t offset26,
1375      CompactBranchType is_compact_branch = CompactBranchType::NO);
1376
1377
1378  void GenInstrJump(Opcode opcode,
1379                     uint32_t address);
1380
1381
1382  // Labels.
1383  void print(Label* L);
1384  void bind_to(Label* L, int pos);
1385  void next(Label* L, bool is_internal);
1386
1387  // One trampoline consists of:
1388  // - space for trampoline slots,
1389  // - space for labels.
1390  //
1391  // Space for trampoline slots is equal to slot_count * 2 * kInstrSize.
1392  // Space for trampoline slots preceeds space for labels. Each label is of one
1393  // instruction size, so total amount for labels is equal to
1394  // label_count *  kInstrSize.
1395  class Trampoline {
1396   public:
1397    Trampoline() {
1398      start_ = 0;
1399      next_slot_ = 0;
1400      free_slot_count_ = 0;
1401      end_ = 0;
1402    }
1403    Trampoline(int start, int slot_count) {
1404      start_ = start;
1405      next_slot_ = start;
1406      free_slot_count_ = slot_count;
1407      end_ = start + slot_count * kTrampolineSlotsSize;
1408    }
1409    int start() {
1410      return start_;
1411    }
1412    int end() {
1413      return end_;
1414    }
1415    int take_slot() {
1416      int trampoline_slot = kInvalidSlotPos;
1417      if (free_slot_count_ <= 0) {
1418        // We have run out of space on trampolines.
1419        // Make sure we fail in debug mode, so we become aware of each case
1420        // when this happens.
1421        DCHECK(0);
1422        // Internal exception will be caught.
1423      } else {
1424        trampoline_slot = next_slot_;
1425        free_slot_count_--;
1426        next_slot_ += kTrampolineSlotsSize;
1427      }
1428      return trampoline_slot;
1429    }
1430
1431   private:
1432    int start_;
1433    int end_;
1434    int next_slot_;
1435    int free_slot_count_;
1436  };
1437
1438  int32_t get_trampoline_entry(int32_t pos);
1439  int unbound_labels_count_;
1440  // If trampoline is emitted, generated code is becoming large. As this is
1441  // already a slow case which can possibly break our code generation for the
1442  // extreme case, we use this information to trigger different mode of
1443  // branch instruction generation, where we use jump instructions rather
1444  // than regular branch instructions.
1445  bool trampoline_emitted_;
1446#ifdef _MIPS_ARCH_MIPS32R6
1447  static const int kTrampolineSlotsSize = 2 * kInstrSize;
1448#else
1449  static const int kTrampolineSlotsSize = 4 * kInstrSize;
1450#endif
1451  static const int kMaxBranchOffset = (1 << (18 - 1)) - 1;
1452  static const int kMaxCompactBranchOffset = (1 << (28 - 1)) - 1;
1453  static const int kInvalidSlotPos = -1;
1454
1455  // Internal reference positions, required for unbounded internal reference
1456  // labels.
1457  std::set<int> internal_reference_positions_;
1458
1459  void EmittedCompactBranchInstruction() { prev_instr_compact_branch_ = true; }
1460  void ClearCompactBranchState() { prev_instr_compact_branch_ = false; }
1461  bool prev_instr_compact_branch_ = false;
1462
1463  Trampoline trampoline_;
1464  bool internal_trampoline_exception_;
1465
1466  friend class RegExpMacroAssemblerMIPS;
1467  friend class RelocInfo;
1468  friend class CodePatcher;
1469  friend class BlockTrampolinePoolScope;
1470  friend class EnsureSpace;
1471};
1472
1473
1474class EnsureSpace BASE_EMBEDDED {
1475 public:
1476  explicit EnsureSpace(Assembler* assembler) {
1477    assembler->CheckBuffer();
1478  }
1479};
1480
1481}  // namespace internal
1482}  // namespace v8
1483
1484#endif  // V8_ARM_ASSEMBLER_MIPS_H_
1485