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