v8  3.25.30(node0.11.13)
V8 is Google's open source JavaScript engine
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
macro-assembler-mips.h
Go to the documentation of this file.
1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are
4 // met:
5 //
6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided
11 // with the distribution.
12 // * Neither the name of Google Inc. nor the names of its
13 // contributors may be used to endorse or promote products derived
14 // from this software without specific prior written permission.
15 //
16 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 
28 #ifndef V8_MIPS_MACRO_ASSEMBLER_MIPS_H_
29 #define V8_MIPS_MACRO_ASSEMBLER_MIPS_H_
30 
31 #include "assembler.h"
32 #include "mips/assembler-mips.h"
33 #include "v8globals.h"
34 
35 namespace v8 {
36 namespace internal {
37 
38 // Forward declaration.
39 class JumpTarget;
40 
41 // Reserved Register Usage Summary.
42 //
43 // Registers t8, t9, and at are reserved for use by the MacroAssembler.
44 //
45 // The programmer should know that the MacroAssembler may clobber these three,
46 // but won't touch other registers except in special cases.
47 //
48 // Per the MIPS ABI, register t9 must be used for indirect function call
49 // via 'jalr t9' or 'jr t9' instructions. This is relied upon by gcc when
50 // trying to update gp register for position-independent-code. Whenever
51 // MIPS generated code calls C code, it must be via t9 register.
52 
53 
54 // Flags used for LeaveExitFrame function.
56  EMIT_RETURN = true,
58 };
59 
60 // Flags used for AllocateHeapNumber
62  // Tag the result.
63  TAG_RESULT,
64  // Don't tag
66 };
67 
68 // Flags used for the ObjectToDoubleFPURegister function.
70  // No special flags.
72  // Object is known to be a non smi.
73  OBJECT_NOT_SMI = 1 << 0,
74  // Don't load NaNs or infinities, branch to the non number case instead.
76 };
77 
78 // Allow programmer to use Branch Delay Slot of Branches, Jumps, Calls.
82 };
83 
84 // Flags used for the li macro-assembler function.
85 enum LiFlags {
86  // If the constant value can be represented in just 16 bits, then
87  // optimize the li to use a single instruction, rather than lui/ori pair.
89  // Always use 2 instructions (lui/ori pair), even if the constant could
90  // be loaded with just one, so that this value is patchable later.
92 };
93 
94 
98 
99 Register GetRegisterThatIsNotOneOf(Register reg1,
100  Register reg2 = no_reg,
101  Register reg3 = no_reg,
102  Register reg4 = no_reg,
103  Register reg5 = no_reg,
104  Register reg6 = no_reg);
105 
106 bool AreAliased(Register r1, Register r2, Register r3, Register r4);
107 
108 
109 // -----------------------------------------------------------------------------
110 // Static helper functions.
111 
112 inline MemOperand ContextOperand(Register context, int index) {
113  return MemOperand(context, Context::SlotOffset(index));
114 }
115 
116 
119 }
120 
121 
122 // Generate a MemOperand for loading a field from an object.
123 inline MemOperand FieldMemOperand(Register object, int offset) {
124  return MemOperand(object, offset - kHeapObjectTag);
125 }
126 
127 
128 // Generate a MemOperand for storing arguments 5..N on the stack
129 // when calling CallCFunction().
131  ASSERT(index > kCArgSlotCount);
132  // Argument 5 takes the slot just past the four Arg-slots.
133  int offset = (index - 5) * kPointerSize + kCArgsSlotsSize;
134  return MemOperand(sp, offset);
135 }
136 
137 
138 // MacroAssembler implements a collection of frequently used macros.
139 class MacroAssembler: public Assembler {
140  public:
141  // The isolate parameter can be NULL if the macro assembler should
142  // not use isolate-dependent functionality. In this case, it's the
143  // responsibility of the caller to never invoke such function on the
144  // macro assembler.
145  MacroAssembler(Isolate* isolate, void* buffer, int size);
146 
147  // Arguments macros.
148 #define COND_TYPED_ARGS Condition cond, Register r1, const Operand& r2
149 #define COND_ARGS cond, r1, r2
150 
151  // Cases when relocation is not needed.
152 #define DECLARE_NORELOC_PROTOTYPE(Name, target_type) \
153  void Name(target_type target, BranchDelaySlot bd = PROTECT); \
154  inline void Name(BranchDelaySlot bd, target_type target) { \
155  Name(target, bd); \
156  } \
157  void Name(target_type target, \
158  COND_TYPED_ARGS, \
159  BranchDelaySlot bd = PROTECT); \
160  inline void Name(BranchDelaySlot bd, \
161  target_type target, \
162  COND_TYPED_ARGS) { \
163  Name(target, COND_ARGS, bd); \
164  }
165 
166 #define DECLARE_BRANCH_PROTOTYPES(Name) \
167  DECLARE_NORELOC_PROTOTYPE(Name, Label*) \
168  DECLARE_NORELOC_PROTOTYPE(Name, int16_t)
169 
171  DECLARE_BRANCH_PROTOTYPES(BranchAndLink)
172  DECLARE_BRANCH_PROTOTYPES(BranchShort)
173 
174 #undef DECLARE_BRANCH_PROTOTYPES
175 #undef COND_TYPED_ARGS
176 #undef COND_ARGS
177 
178 
179  // Jump, Call, and Ret pseudo instructions implementing inter-working.
180 #define COND_ARGS Condition cond = al, Register rs = zero_reg, \
181  const Operand& rt = Operand(zero_reg), BranchDelaySlot bd = PROTECT
182 
183  void Jump(Register target, COND_ARGS);
184  void Jump(intptr_t target, RelocInfo::Mode rmode, COND_ARGS);
185  void Jump(Address target, RelocInfo::Mode rmode, COND_ARGS);
186  void Jump(Handle<Code> code, RelocInfo::Mode rmode, COND_ARGS);
187  static int CallSize(Register target, COND_ARGS);
188  void Call(Register target, COND_ARGS);
189  static int CallSize(Address target, RelocInfo::Mode rmode, COND_ARGS);
190  void Call(Address target, RelocInfo::Mode rmode, COND_ARGS);
191  int CallSize(Handle<Code> code,
192  RelocInfo::Mode rmode = RelocInfo::CODE_TARGET,
193  TypeFeedbackId ast_id = TypeFeedbackId::None(),
194  COND_ARGS);
195  void Call(Handle<Code> code,
196  RelocInfo::Mode rmode = RelocInfo::CODE_TARGET,
197  TypeFeedbackId ast_id = TypeFeedbackId::None(),
198  COND_ARGS);
199  void Ret(COND_ARGS);
200  inline void Ret(BranchDelaySlot bd, Condition cond = al,
201  Register rs = zero_reg, const Operand& rt = Operand(zero_reg)) {
202  Ret(cond, rs, rt, bd);
203  }
204 
205  void Branch(Label* L,
206  Condition cond,
207  Register rs,
208  Heap::RootListIndex index,
209  BranchDelaySlot bdslot = PROTECT);
210 
211 #undef COND_ARGS
212 
213  // Emit code to discard a non-negative number of pointer-sized elements
214  // from the stack, clobbering only the sp register.
215  void Drop(int count,
216  Condition cond = cc_always,
217  Register reg = no_reg,
218  const Operand& op = Operand(no_reg));
219 
220  // Trivial case of DropAndRet that utilizes the delay slot and only emits
221  // 2 instructions.
222  void DropAndRet(int drop);
223 
224  void DropAndRet(int drop,
225  Condition cond,
226  Register reg,
227  const Operand& op);
228 
229  // Swap two registers. If the scratch register is omitted then a slightly
230  // less efficient form using xor instead of mov is emitted.
231  void Swap(Register reg1, Register reg2, Register scratch = no_reg);
232 
233  void Call(Label* target);
234 
235  inline void Move(Register dst, Register src) {
236  if (!dst.is(src)) {
237  mov(dst, src);
238  }
239  }
240 
241  inline void Move(FPURegister dst, FPURegister src) {
242  if (!dst.is(src)) {
243  mov_d(dst, src);
244  }
245  }
246 
247  inline void Move(Register dst_low, Register dst_high, FPURegister src) {
248  mfc1(dst_low, src);
249  mfc1(dst_high, FPURegister::from_code(src.code() + 1));
250  }
251 
252  inline void FmoveHigh(Register dst_high, FPURegister src) {
253  mfc1(dst_high, FPURegister::from_code(src.code() + 1));
254  }
255 
256  inline void FmoveLow(Register dst_low, FPURegister src) {
257  mfc1(dst_low, src);
258  }
259 
260  inline void Move(FPURegister dst, Register src_low, Register src_high) {
261  mtc1(src_low, dst);
262  mtc1(src_high, FPURegister::from_code(dst.code() + 1));
263  }
264 
265  // Conditional move.
266  void Move(FPURegister dst, double imm);
267  void Movz(Register rd, Register rs, Register rt);
268  void Movn(Register rd, Register rs, Register rt);
269  void Movt(Register rd, Register rs, uint16_t cc = 0);
270  void Movf(Register rd, Register rs, uint16_t cc = 0);
271 
272  void Clz(Register rd, Register rs);
273 
274  // Jump unconditionally to given label.
275  // We NEED a nop in the branch delay slot, as it used by v8, for example in
276  // CodeGenerator::ProcessDeferred().
277  // Currently the branch delay slot is filled by the MacroAssembler.
278  // Use rather b(Label) for code generation.
279  void jmp(Label* L) {
280  Branch(L);
281  }
282 
283  void Load(Register dst, const MemOperand& src, Representation r);
284  void Store(Register src, const MemOperand& dst, Representation r);
285 
286  // Load an object from the root table.
287  void LoadRoot(Register destination,
288  Heap::RootListIndex index);
289  void LoadRoot(Register destination,
290  Heap::RootListIndex index,
291  Condition cond, Register src1, const Operand& src2);
292 
293  // Store an object to the root table.
294  void StoreRoot(Register source,
295  Heap::RootListIndex index);
296  void StoreRoot(Register source,
297  Heap::RootListIndex index,
298  Condition cond, Register src1, const Operand& src2);
299 
300  // ---------------------------------------------------------------------------
301  // GC Support
302 
304  Register value,
305  Register address);
306 
308  kReturnAtEnd,
310  };
311 
312 
313  // Record in the remembered set the fact that we have a pointer to new space
314  // at the address pointed to by the addr register. Only works if addr is not
315  // in new space.
316  void RememberedSetHelper(Register object, // Used for debug code.
317  Register addr,
318  Register scratch,
319  SaveFPRegsMode save_fp,
320  RememberedSetFinalAction and_then);
321 
322  void CheckPageFlag(Register object,
323  Register scratch,
324  int mask,
325  Condition cc,
326  Label* condition_met);
327 
329  Register scratch,
330  Label* if_deprecated);
331 
332  // Check if object is in new space. Jumps if the object is not in new space.
333  // The register scratch can be object itself, but it will be clobbered.
335  Register scratch,
336  Label* branch) {
337  InNewSpace(object, scratch, ne, branch);
338  }
339 
340  // Check if object is in new space. Jumps if the object is in new space.
341  // The register scratch can be object itself, but scratch will be clobbered.
343  Register scratch,
344  Label* branch) {
345  InNewSpace(object, scratch, eq, branch);
346  }
347 
348  // Check if an object has a given incremental marking color.
349  void HasColor(Register object,
350  Register scratch0,
351  Register scratch1,
352  Label* has_color,
353  int first_bit,
354  int second_bit);
355 
356  void JumpIfBlack(Register object,
357  Register scratch0,
358  Register scratch1,
359  Label* on_black);
360 
361  // Checks the color of an object. If the object is already grey or black
362  // then we just fall through, since it is already live. If it is white and
363  // we can determine that it doesn't need to be scanned, then we just mark it
364  // black and fall through. For the rest we jump to the label so the
365  // incremental marker can fix its assumptions.
366  void EnsureNotWhite(Register object,
367  Register scratch1,
368  Register scratch2,
369  Register scratch3,
370  Label* object_is_white_and_not_data);
371 
372  // Detects conservatively whether an object is data-only, i.e. it does need to
373  // be scanned by the garbage collector.
374  void JumpIfDataObject(Register value,
375  Register scratch,
376  Label* not_data_object);
377 
378  // Notify the garbage collector that we wrote a pointer into an object.
379  // |object| is the object being stored into, |value| is the object being
380  // stored. value and scratch registers are clobbered by the operation.
381  // The offset is the offset from the start of the object, not the offset from
382  // the tagged HeapObject pointer. For use with FieldOperand(reg, off).
383  void RecordWriteField(
384  Register object,
385  int offset,
386  Register value,
387  Register scratch,
388  RAStatus ra_status,
389  SaveFPRegsMode save_fp,
390  RememberedSetAction remembered_set_action = EMIT_REMEMBERED_SET,
391  SmiCheck smi_check = INLINE_SMI_CHECK);
392 
393  // As above, but the offset has the tag presubtracted. For use with
394  // MemOperand(reg, off).
396  Register context,
397  int offset,
398  Register value,
399  Register scratch,
400  RAStatus ra_status,
401  SaveFPRegsMode save_fp,
402  RememberedSetAction remembered_set_action = EMIT_REMEMBERED_SET,
403  SmiCheck smi_check = INLINE_SMI_CHECK) {
404  RecordWriteField(context,
405  offset + kHeapObjectTag,
406  value,
407  scratch,
408  ra_status,
409  save_fp,
410  remembered_set_action,
411  smi_check);
412  }
413 
414  // For a given |object| notify the garbage collector that the slot |address|
415  // has been written. |value| is the object being stored. The value and
416  // address registers are clobbered by the operation.
417  void RecordWrite(
418  Register object,
419  Register address,
420  Register value,
421  RAStatus ra_status,
422  SaveFPRegsMode save_fp,
423  RememberedSetAction remembered_set_action = EMIT_REMEMBERED_SET,
424  SmiCheck smi_check = INLINE_SMI_CHECK);
425 
426 
427  // ---------------------------------------------------------------------------
428  // Inline caching support.
429 
430  // Generate code for checking access rights - used for security checks
431  // on access to global objects across environments. The holder register
432  // is left untouched, whereas both scratch registers are clobbered.
433  void CheckAccessGlobalProxy(Register holder_reg,
434  Register scratch,
435  Label* miss);
436 
437  void GetNumberHash(Register reg0, Register scratch);
438 
439  void LoadFromNumberDictionary(Label* miss,
440  Register elements,
441  Register key,
442  Register result,
443  Register reg0,
444  Register reg1,
445  Register reg2);
446 
447 
448  inline void MarkCode(NopMarkerTypes type) {
449  nop(type);
450  }
451 
452  // Check if the given instruction is a 'type' marker.
453  // i.e. check if it is a sll zero_reg, zero_reg, <type> (referenced as
454  // nop(type)). These instructions are generated to mark special location in
455  // the code, like some special IC code.
456  static inline bool IsMarkedCode(Instr instr, int type) {
457  ASSERT((FIRST_IC_MARKER <= type) && (type < LAST_CODE_MARKER));
458  return IsNop(instr, type);
459  }
460 
461 
462  static inline int GetCodeMarker(Instr instr) {
463  uint32_t opcode = ((instr & kOpcodeMask));
464  uint32_t rt = ((instr & kRtFieldMask) >> kRtShift);
465  uint32_t rs = ((instr & kRsFieldMask) >> kRsShift);
466  uint32_t sa = ((instr & kSaFieldMask) >> kSaShift);
467 
468  // Return <n> if we have a sll zero_reg, zero_reg, n
469  // else return -1.
470  bool sllzz = (opcode == SLL &&
471  rt == static_cast<uint32_t>(ToNumber(zero_reg)) &&
472  rs == static_cast<uint32_t>(ToNumber(zero_reg)));
473  int type =
474  (sllzz && FIRST_IC_MARKER <= sa && sa < LAST_CODE_MARKER) ? sa : -1;
475  ASSERT((type == -1) ||
476  ((FIRST_IC_MARKER <= type) && (type < LAST_CODE_MARKER)));
477  return type;
478  }
479 
480 
481 
482  // ---------------------------------------------------------------------------
483  // Allocation support.
484 
485  // Allocate an object in new space or old pointer space. The object_size is
486  // specified either in bytes or in words if the allocation flag SIZE_IN_WORDS
487  // is passed. If the space is exhausted control continues at the gc_required
488  // label. The allocated object is returned in result. If the flag
489  // tag_allocated_object is true the result is tagged as as a heap object.
490  // All registers are clobbered also when control continues at the gc_required
491  // label.
492  void Allocate(int object_size,
493  Register result,
494  Register scratch1,
495  Register scratch2,
496  Label* gc_required,
498 
499  void Allocate(Register object_size,
500  Register result,
501  Register scratch1,
502  Register scratch2,
503  Label* gc_required,
505 
506  // Undo allocation in new space. The object passed and objects allocated after
507  // it will no longer be allocated. The caller must make sure that no pointers
508  // are left to the object(s) no longer allocated as they would be invalid when
509  // allocation is undone.
510  void UndoAllocationInNewSpace(Register object, Register scratch);
511 
512 
513  void AllocateTwoByteString(Register result,
514  Register length,
515  Register scratch1,
516  Register scratch2,
517  Register scratch3,
518  Label* gc_required);
519  void AllocateAsciiString(Register result,
520  Register length,
521  Register scratch1,
522  Register scratch2,
523  Register scratch3,
524  Label* gc_required);
526  Register length,
527  Register scratch1,
528  Register scratch2,
529  Label* gc_required);
530  void AllocateAsciiConsString(Register result,
531  Register length,
532  Register scratch1,
533  Register scratch2,
534  Label* gc_required);
536  Register length,
537  Register scratch1,
538  Register scratch2,
539  Label* gc_required);
541  Register length,
542  Register scratch1,
543  Register scratch2,
544  Label* gc_required);
545 
546  // Allocates a heap number or jumps to the gc_required label if the young
547  // space is full and a scavenge is needed. All registers are clobbered also
548  // when control continues at the gc_required label.
549  void AllocateHeapNumber(Register result,
550  Register scratch1,
551  Register scratch2,
552  Register heap_number_map,
553  Label* gc_required,
554  TaggingMode tagging_mode = TAG_RESULT);
556  FPURegister value,
557  Register scratch1,
558  Register scratch2,
559  Label* gc_required);
560 
561  // ---------------------------------------------------------------------------
562  // Instruction macros.
563 
564 #define DEFINE_INSTRUCTION(instr) \
565  void instr(Register rd, Register rs, const Operand& rt); \
566  void instr(Register rd, Register rs, Register rt) { \
567  instr(rd, rs, Operand(rt)); \
568  } \
569  void instr(Register rs, Register rt, int32_t j) { \
570  instr(rs, rt, Operand(j)); \
571  }
572 
573 #define DEFINE_INSTRUCTION2(instr) \
574  void instr(Register rs, const Operand& rt); \
575  void instr(Register rs, Register rt) { \
576  instr(rs, Operand(rt)); \
577  } \
578  void instr(Register rs, int32_t j) { \
579  instr(rs, Operand(j)); \
580  }
581 
582  DEFINE_INSTRUCTION(Addu);
583  DEFINE_INSTRUCTION(Subu);
585  DEFINE_INSTRUCTION2(Mult);
586  DEFINE_INSTRUCTION2(Multu);
587  DEFINE_INSTRUCTION2(Div);
588  DEFINE_INSTRUCTION2(Divu);
589 
591  DEFINE_INSTRUCTION(Or);
592  DEFINE_INSTRUCTION(Xor);
593  DEFINE_INSTRUCTION(Nor);
595 
596  DEFINE_INSTRUCTION(Slt);
597  DEFINE_INSTRUCTION(Sltu);
598 
599  // MIPS32 R2 instruction macro.
601 
602 #undef DEFINE_INSTRUCTION
603 #undef DEFINE_INSTRUCTION2
604 
605  void Pref(int32_t hint, const MemOperand& rs);
606 
607 
608  // ---------------------------------------------------------------------------
609  // Pseudo-instructions.
610 
611  void mov(Register rd, Register rt) { or_(rd, rt, zero_reg); }
612 
613  void Ulw(Register rd, const MemOperand& rs);
614  void Usw(Register rd, const MemOperand& rs);
615 
616  // Load int32 in the rd register.
618  inline void li(Register rd, int32_t j, LiFlags mode = OPTIMIZE_SIZE) {
619  li(rd, Operand(j), mode);
620  }
621  void li(Register dst, Handle<Object> value, LiFlags mode = OPTIMIZE_SIZE);
622 
623  // Push multiple registers on the stack.
624  // Registers are saved in numerical order, with higher numbered registers
625  // saved in higher memory addresses.
626  void MultiPush(RegList regs);
627  void MultiPushReversed(RegList regs);
628 
629  void MultiPushFPU(RegList regs);
630  void MultiPushReversedFPU(RegList regs);
631 
632  void push(Register src) {
633  Addu(sp, sp, Operand(-kPointerSize));
634  sw(src, MemOperand(sp, 0));
635  }
636  void Push(Register src) { push(src); }
637 
638  // Push a handle.
639  void Push(Handle<Object> handle);
640  void Push(Smi* smi) { Push(Handle<Smi>(smi, isolate())); }
641 
642  // Push two registers. Pushes leftmost register first (to highest address).
643  void Push(Register src1, Register src2) {
644  Subu(sp, sp, Operand(2 * kPointerSize));
645  sw(src1, MemOperand(sp, 1 * kPointerSize));
646  sw(src2, MemOperand(sp, 0 * kPointerSize));
647  }
648 
649  // Push three registers. Pushes leftmost register first (to highest address).
650  void Push(Register src1, Register src2, Register src3) {
651  Subu(sp, sp, Operand(3 * kPointerSize));
652  sw(src1, MemOperand(sp, 2 * kPointerSize));
653  sw(src2, MemOperand(sp, 1 * kPointerSize));
654  sw(src3, MemOperand(sp, 0 * kPointerSize));
655  }
656 
657  // Push four registers. Pushes leftmost register first (to highest address).
658  void Push(Register src1, Register src2, Register src3, Register src4) {
659  Subu(sp, sp, Operand(4 * kPointerSize));
660  sw(src1, MemOperand(sp, 3 * kPointerSize));
661  sw(src2, MemOperand(sp, 2 * kPointerSize));
662  sw(src3, MemOperand(sp, 1 * kPointerSize));
663  sw(src4, MemOperand(sp, 0 * kPointerSize));
664  }
665 
666  void Push(Register src, Condition cond, Register tst1, Register tst2) {
667  // Since we don't have conditional execution we use a Branch.
668  Branch(3, cond, tst1, Operand(tst2));
669  Subu(sp, sp, Operand(kPointerSize));
670  sw(src, MemOperand(sp, 0));
671  }
672 
673  // Pops multiple values from the stack and load them in the
674  // registers specified in regs. Pop order is the opposite as in MultiPush.
675  void MultiPop(RegList regs);
676  void MultiPopReversed(RegList regs);
677 
678  void MultiPopFPU(RegList regs);
679  void MultiPopReversedFPU(RegList regs);
680 
681  void pop(Register dst) {
682  lw(dst, MemOperand(sp, 0));
683  Addu(sp, sp, Operand(kPointerSize));
684  }
685  void Pop(Register dst) { pop(dst); }
686 
687  // Pop two registers. Pops rightmost register first (from lower address).
688  void Pop(Register src1, Register src2) {
689  ASSERT(!src1.is(src2));
690  lw(src2, MemOperand(sp, 0 * kPointerSize));
691  lw(src1, MemOperand(sp, 1 * kPointerSize));
692  Addu(sp, sp, 2 * kPointerSize);
693  }
694 
695  // Pop three registers. Pops rightmost register first (from lower address).
696  void Pop(Register src1, Register src2, Register src3) {
697  lw(src3, MemOperand(sp, 0 * kPointerSize));
698  lw(src2, MemOperand(sp, 1 * kPointerSize));
699  lw(src1, MemOperand(sp, 2 * kPointerSize));
700  Addu(sp, sp, 3 * kPointerSize);
701  }
702 
703  void Pop(uint32_t count = 1) {
704  Addu(sp, sp, Operand(count * kPointerSize));
705  }
706 
707  // Push and pop the registers that can hold pointers, as defined by the
708  // RegList constant kSafepointSavedRegisters.
709  void PushSafepointRegisters();
710  void PopSafepointRegisters();
713  // Store value in register src in the safepoint stack slot for
714  // register dst.
717  // Load the value of the src register from its safepoint stack slot
718  // into register dst.
720 
721  // Flush the I-cache from asm code. You should use CPU::FlushICache from C.
722  // Does not handle errors.
723  void FlushICache(Register address, unsigned instructions);
724 
725  // MIPS32 R2 instruction macro.
726  void Ins(Register rt, Register rs, uint16_t pos, uint16_t size);
727  void Ext(Register rt, Register rs, uint16_t pos, uint16_t size);
728 
729  // ---------------------------------------------------------------------------
730  // FPU macros. These do not handle special cases like NaN or +- inf.
731 
732  // Convert unsigned word to double.
733  void Cvt_d_uw(FPURegister fd, FPURegister fs, FPURegister scratch);
734  void Cvt_d_uw(FPURegister fd, Register rs, FPURegister scratch);
735 
736  // Convert double to unsigned word.
737  void Trunc_uw_d(FPURegister fd, FPURegister fs, FPURegister scratch);
738  void Trunc_uw_d(FPURegister fd, Register rs, FPURegister scratch);
739 
740  void Trunc_w_d(FPURegister fd, FPURegister fs);
741  void Round_w_d(FPURegister fd, FPURegister fs);
742  void Floor_w_d(FPURegister fd, FPURegister fs);
743  void Ceil_w_d(FPURegister fd, FPURegister fs);
744  // Wrapper function for the different cmp/branch types.
745  void BranchF(Label* target,
746  Label* nan,
747  Condition cc,
748  FPURegister cmp1,
749  FPURegister cmp2,
750  BranchDelaySlot bd = PROTECT);
751 
752  // Alternate (inline) version for better readability with USE_DELAY_SLOT.
753  inline void BranchF(BranchDelaySlot bd,
754  Label* target,
755  Label* nan,
756  Condition cc,
757  FPURegister cmp1,
758  FPURegister cmp2) {
759  BranchF(target, nan, cc, cmp1, cmp2, bd);
760  };
761 
762  // Truncates a double using a specific rounding mode, and writes the value
763  // to the result register.
764  // The except_flag will contain any exceptions caused by the instruction.
765  // If check_inexact is kDontCheckForInexactConversion, then the inexact
766  // exception is masked.
767  void EmitFPUTruncate(FPURoundingMode rounding_mode,
768  Register result,
769  DoubleRegister double_input,
770  Register scratch,
771  DoubleRegister double_scratch,
772  Register except_flag,
773  CheckForInexactConversion check_inexact
775 
776  // Performs a truncating conversion of a floating point number as used by
777  // the JS bitwise operations. See ECMA-262 9.5: ToInt32. Goes to 'done' if it
778  // succeeds, otherwise falls through if result is saturated. On return
779  // 'result' either holds answer, or is clobbered on fall through.
780  //
781  // Only public for the test code in test-code-stubs-arm.cc.
783  DoubleRegister input,
784  Label* done);
785 
786  // Performs a truncating conversion of a floating point number as used by
787  // the JS bitwise operations. See ECMA-262 9.5: ToInt32.
788  // Exits with 'result' holding the answer.
789  void TruncateDoubleToI(Register result, DoubleRegister double_input);
790 
791  // Performs a truncating conversion of a heap number as used by
792  // the JS bitwise operations. See ECMA-262 9.5: ToInt32. 'result' and 'input'
793  // must be different registers. Exits with 'result' holding the answer.
794  void TruncateHeapNumberToI(Register result, Register object);
795 
796  // Converts the smi or heap number in object to an int32 using the rules
797  // for ToInt32 as described in ECMAScript 9.5.: the value is truncated
798  // and brought into the range -2^31 .. +2^31 - 1. 'result' and 'input' must be
799  // different registers.
800  void TruncateNumberToI(Register object,
801  Register result,
802  Register heap_number_map,
803  Register scratch,
804  Label* not_int32);
805 
806  // Loads the number from object into dst register.
807  // If |object| is neither smi nor heap number, |not_number| is jumped to
808  // with |object| still intact.
809  void LoadNumber(Register object,
810  FPURegister dst,
811  Register heap_number_map,
812  Register scratch,
813  Label* not_number);
814 
815  // Loads the number from object into double_dst in the double format.
816  // Control will jump to not_int32 if the value cannot be exactly represented
817  // by a 32-bit integer.
818  // Floating point value in the 32-bit integer range that are not exact integer
819  // won't be loaded.
820  void LoadNumberAsInt32Double(Register object,
821  DoubleRegister double_dst,
822  Register heap_number_map,
823  Register scratch1,
824  Register scratch2,
825  FPURegister double_scratch,
826  Label* not_int32);
827 
828  // Loads the number from object into dst as a 32-bit integer.
829  // Control will jump to not_int32 if the object cannot be exactly represented
830  // by a 32-bit integer.
831  // Floating point value in the 32-bit integer range that are not exact integer
832  // won't be converted.
833  void LoadNumberAsInt32(Register object,
834  Register dst,
835  Register heap_number_map,
836  Register scratch1,
837  Register scratch2,
838  FPURegister double_scratch0,
839  FPURegister double_scratch1,
840  Label* not_int32);
841 
842  // Enter exit frame.
843  // argc - argument count to be dropped by LeaveExitFrame.
844  // save_doubles - saves FPU registers on stack, currently disabled.
845  // stack_space - extra stack space.
846  void EnterExitFrame(bool save_doubles,
847  int stack_space = 0);
848 
849  // Leave the current exit frame.
850  void LeaveExitFrame(bool save_doubles,
851  Register arg_count,
852  bool restore_context,
853  bool do_return = NO_EMIT_RETURN);
854 
855  // Get the actual activation frame alignment for target environment.
856  static int ActivationFrameAlignment();
857 
858  // Make sure the stack is aligned. Only emits code in debug mode.
859  void AssertStackIsAligned();
860 
861  void LoadContext(Register dst, int context_chain_length);
862 
863  // Conditionally load the cached Array transitioned map of type
864  // transitioned_kind from the native context if the map in register
865  // map_in_out is the cached Array map in the native context of
866  // expected_kind.
868  ElementsKind expected_kind,
869  ElementsKind transitioned_kind,
870  Register map_in_out,
871  Register scratch,
872  Label* no_map_match);
873 
874  void LoadGlobalFunction(int index, Register function);
875 
876  // Load the initial map from the global function. The registers
877  // function and map can be the same, function is then overwritten.
879  Register map,
880  Register scratch);
881 
883  ExternalReference roots_array_start =
884  ExternalReference::roots_array_start(isolate());
885  li(kRootRegister, Operand(roots_array_start));
886  }
887 
888  // -------------------------------------------------------------------------
889  // JavaScript invokes.
890 
891  // Invoke the JavaScript function code by either calling or jumping.
892  void InvokeCode(Register code,
893  const ParameterCount& expected,
894  const ParameterCount& actual,
896  const CallWrapper& call_wrapper);
897 
898  // Invoke the JavaScript function in the given register. Changes the
899  // current context to the context in the function before invoking.
900  void InvokeFunction(Register function,
901  const ParameterCount& actual,
903  const CallWrapper& call_wrapper);
904 
905  void InvokeFunction(Register function,
906  const ParameterCount& expected,
907  const ParameterCount& actual,
909  const CallWrapper& call_wrapper);
910 
911  void InvokeFunction(Handle<JSFunction> function,
912  const ParameterCount& expected,
913  const ParameterCount& actual,
915  const CallWrapper& call_wrapper);
916 
917 
918  void IsObjectJSObjectType(Register heap_object,
919  Register map,
920  Register scratch,
921  Label* fail);
922 
924  Register scratch,
925  Label* fail);
926 
927  void IsObjectJSStringType(Register object,
928  Register scratch,
929  Label* fail);
930 
931  void IsObjectNameType(Register object,
932  Register scratch,
933  Label* fail);
934 
935 #ifdef ENABLE_DEBUGGER_SUPPORT
936  // -------------------------------------------------------------------------
937  // Debugger Support.
938 
939  void DebugBreak();
940 #endif
941 
942 
943  // -------------------------------------------------------------------------
944  // Exception handling.
945 
946  // Push a new try handler and link into try handler chain.
947  void PushTryHandler(StackHandler::Kind kind, int handler_index);
948 
949  // Unlink the stack handler on top of the stack from the try handler chain.
950  // Must preserve the result register.
951  void PopTryHandler();
952 
953  // Passes thrown value to the handler of top of the try handler chain.
954  void Throw(Register value);
955 
956  // Propagates an uncatchable exception to the top of the current JS stack's
957  // handler chain.
958  void ThrowUncatchable(Register value);
959 
960  // Throw a message string as an exception.
961  void Throw(BailoutReason reason);
962 
963  // Throw a message string as an exception if a condition is not true.
964  void ThrowIf(Condition cc, BailoutReason reason, Register rs, Operand rt);
965 
966  // Copies a fixed number of fields of heap objects from src to dst.
967  void CopyFields(Register dst, Register src, RegList temps, int field_count);
968 
969  // Copies a number of bytes from src to dst. All registers are clobbered. On
970  // exit src and dst will point to the place just after where the last byte was
971  // read or written and length will be zero.
972  void CopyBytes(Register src,
973  Register dst,
974  Register length,
975  Register scratch);
976 
977  // Initialize fields with filler values. Fields starting at |start_offset|
978  // not including end_offset are overwritten with the value in |filler|. At
979  // the end the loop, |start_offset| takes the value of |end_offset|.
980  void InitializeFieldsWithFiller(Register start_offset,
981  Register end_offset,
982  Register filler);
983 
984  // -------------------------------------------------------------------------
985  // Support functions.
986 
987  // Try to get function prototype of a function and puts the value in
988  // the result register. Checks that the function really is a
989  // function and jumps to the miss label if the fast checks fail. The
990  // function register will be untouched; the other registers may be
991  // clobbered.
992  void TryGetFunctionPrototype(Register function,
993  Register result,
994  Register scratch,
995  Label* miss,
996  bool miss_on_bound_function = false);
997 
998  void GetObjectType(Register function,
999  Register map,
1000  Register type_reg);
1001 
1002  // Check if a map for a JSObject indicates that the object has fast elements.
1003  // Jump to the specified label if it does not.
1005  Register scratch,
1006  Label* fail);
1007 
1008  // Check if a map for a JSObject indicates that the object can have both smi
1009  // and HeapObject elements. Jump to the specified label if it does not.
1011  Register scratch,
1012  Label* fail);
1013 
1014  // Check if a map for a JSObject indicates that the object has fast smi only
1015  // elements. Jump to the specified label if it does not.
1017  Register scratch,
1018  Label* fail);
1019 
1020  // Check to see if maybe_number can be stored as a double in
1021  // FastDoubleElements. If it can, store it at the index specified by key in
1022  // the FastDoubleElements array elements. Otherwise jump to fail.
1023  void StoreNumberToDoubleElements(Register value_reg,
1024  Register key_reg,
1025  Register elements_reg,
1026  Register scratch1,
1027  Register scratch2,
1028  Register scratch3,
1029  Label* fail,
1030  int elements_offset = 0);
1031 
1032  // Compare an object's map with the specified map and its transitioned
1033  // elements maps if mode is ALLOW_ELEMENT_TRANSITION_MAPS. Jumps to
1034  // "branch_to" if the result of the comparison is "cond". If multiple map
1035  // compares are required, the compare sequences branches to early_success.
1037  Register scratch,
1038  Handle<Map> map,
1039  Label* early_success,
1040  Condition cond,
1041  Label* branch_to);
1042 
1043  // As above, but the map of the object is already loaded into the register
1044  // which is preserved by the code generated.
1045  void CompareMapAndBranch(Register obj_map,
1046  Handle<Map> map,
1047  Label* early_success,
1048  Condition cond,
1049  Label* branch_to);
1050 
1051  // Check if the map of an object is equal to a specified map and branch to
1052  // label if not. Skip the smi check if not required (object is known to be a
1053  // heap object). If mode is ALLOW_ELEMENT_TRANSITION_MAPS, then also match
1054  // against maps that are ElementsKind transition maps of the specificed map.
1055  void CheckMap(Register obj,
1056  Register scratch,
1057  Handle<Map> map,
1058  Label* fail,
1059  SmiCheckType smi_check_type);
1060 
1061 
1062  void CheckMap(Register obj,
1063  Register scratch,
1064  Heap::RootListIndex index,
1065  Label* fail,
1066  SmiCheckType smi_check_type);
1067 
1068  // Check if the map of an object is equal to a specified map and branch to a
1069  // specified target if equal. Skip the smi check if not required (object is
1070  // known to be a heap object)
1071  void DispatchMap(Register obj,
1072  Register scratch,
1073  Handle<Map> map,
1074  Handle<Code> success,
1075  SmiCheckType smi_check_type);
1076 
1077  // Generates code for reporting that an illegal operation has
1078  // occurred.
1079  void IllegalOperation(int num_arguments);
1080 
1081 
1082  // Load and check the instance type of an object for being a string.
1083  // Loads the type into the second argument register.
1084  // Returns a condition that will be enabled if the object was a string.
1086  Register type,
1087  Register result) {
1090  And(type, type, Operand(kIsNotStringMask));
1091  ASSERT_EQ(0, kStringTag);
1092  return eq;
1093  }
1094 
1095 
1096  // Picks out an array index from the hash field.
1097  // Register use:
1098  // hash - holds the index's hash. Clobbered.
1099  // index - holds the overwritten index on exit.
1100  void IndexFromHash(Register hash, Register index);
1101 
1102  // Get the number of least significant bits from a register.
1103  void GetLeastBitsFromSmi(Register dst, Register src, int num_least_bits);
1104  void GetLeastBitsFromInt32(Register dst, Register src, int mun_least_bits);
1105 
1106  // Load the value of a number object into a FPU double register. If the
1107  // object is not a number a jump to the label not_number is performed
1108  // and the FPU double register is unchanged.
1110  Register object,
1111  FPURegister value,
1112  Register scratch1,
1113  Register scratch2,
1114  Register heap_number_map,
1115  Label* not_number,
1117 
1118  // Load the value of a smi object into a FPU double register. The register
1119  // scratch1 can be the same register as smi in which case smi will hold the
1120  // untagged value afterwards.
1122  FPURegister value,
1123  Register scratch1);
1124 
1125  // -------------------------------------------------------------------------
1126  // Overflow handling functions.
1127  // Usage: first call the appropriate arithmetic function, then call one of the
1128  // jump functions with the overflow_dst register as the second parameter.
1129 
1131  Register left,
1132  Register right,
1133  Register overflow_dst,
1134  Register scratch = at);
1135 
1137  Register left,
1138  Register right,
1139  Register overflow_dst,
1140  Register scratch = at);
1141 
1142  void BranchOnOverflow(Label* label,
1143  Register overflow_check,
1144  BranchDelaySlot bd = PROTECT) {
1145  Branch(label, lt, overflow_check, Operand(zero_reg), bd);
1146  }
1147 
1148  void BranchOnNoOverflow(Label* label,
1149  Register overflow_check,
1150  BranchDelaySlot bd = PROTECT) {
1151  Branch(label, ge, overflow_check, Operand(zero_reg), bd);
1152  }
1153 
1154  void RetOnOverflow(Register overflow_check, BranchDelaySlot bd = PROTECT) {
1155  Ret(lt, overflow_check, Operand(zero_reg), bd);
1156  }
1157 
1158  void RetOnNoOverflow(Register overflow_check, BranchDelaySlot bd = PROTECT) {
1159  Ret(ge, overflow_check, Operand(zero_reg), bd);
1160  }
1161 
1162  // -------------------------------------------------------------------------
1163  // Runtime calls.
1164 
1165  // See comments at the beginning of CEntryStub::Generate.
1166  inline void PrepareCEntryArgs(int num_args) {
1167  li(s0, num_args);
1168  li(s1, (num_args - 1) * kPointerSize);
1169  }
1170 
1171  inline void PrepareCEntryFunction(const ExternalReference& ref) {
1172  li(s2, Operand(ref));
1173  }
1174 
1175 #define COND_ARGS Condition cond = al, Register rs = zero_reg, \
1176 const Operand& rt = Operand(zero_reg), BranchDelaySlot bd = PROTECT
1177 
1178  // Call a code stub.
1179  void CallStub(CodeStub* stub,
1180  TypeFeedbackId ast_id = TypeFeedbackId::None(),
1181  COND_ARGS);
1182 
1183  // Tail call a code stub (jump).
1184  void TailCallStub(CodeStub* stub, COND_ARGS);
1185 
1186 #undef COND_ARGS
1187 
1188  void CallJSExitStub(CodeStub* stub);
1189 
1190  // Call a runtime routine.
1191  void CallRuntime(const Runtime::Function* f,
1192  int num_arguments,
1193  SaveFPRegsMode save_doubles = kDontSaveFPRegs);
1195  const Runtime::Function* function = Runtime::FunctionForId(id);
1196  CallRuntime(function, function->nargs, kSaveFPRegs);
1197  }
1198 
1199  // Convenience function: Same as above, but takes the fid instead.
1201  int num_arguments,
1202  SaveFPRegsMode save_doubles = kDontSaveFPRegs) {
1203  CallRuntime(Runtime::FunctionForId(id), num_arguments, save_doubles);
1204  }
1205 
1206  // Convenience function: call an external reference.
1207  void CallExternalReference(const ExternalReference& ext,
1208  int num_arguments,
1209  BranchDelaySlot bd = PROTECT);
1210 
1211  // Tail call of a runtime routine (jump).
1212  // Like JumpToExternalReference, but also takes care of passing the number
1213  // of parameters.
1214  void TailCallExternalReference(const ExternalReference& ext,
1215  int num_arguments,
1216  int result_size);
1217 
1218  // Convenience function: tail call a runtime routine (jump).
1220  int num_arguments,
1221  int result_size);
1222 
1223  int CalculateStackPassedWords(int num_reg_arguments,
1224  int num_double_arguments);
1225 
1226  // Before calling a C-function from generated code, align arguments on stack
1227  // and add space for the four mips argument slots.
1228  // After aligning the frame, non-register arguments must be stored on the
1229  // stack, after the argument-slots using helper: CFunctionArgumentOperand().
1230  // The argument count assumes all arguments are word sized.
1231  // Some compilers/platforms require the stack to be aligned when calling
1232  // C++ code.
1233  // Needs a scratch register to do some arithmetic. This register will be
1234  // trashed.
1235  void PrepareCallCFunction(int num_reg_arguments,
1236  int num_double_registers,
1237  Register scratch);
1238  void PrepareCallCFunction(int num_reg_arguments,
1239  Register scratch);
1240 
1241  // Arguments 1-4 are placed in registers a0 thru a3 respectively.
1242  // Arguments 5..n are stored to stack using following:
1243  // sw(t0, CFunctionArgumentOperand(5));
1244 
1245  // Calls a C function and cleans up the space for arguments allocated
1246  // by PrepareCallCFunction. The called function is not allowed to trigger a
1247  // garbage collection, since that might move the code and invalidate the
1248  // return address (unless this is somehow accounted for by the called
1249  // function).
1250  void CallCFunction(ExternalReference function, int num_arguments);
1251  void CallCFunction(Register function, int num_arguments);
1252  void CallCFunction(ExternalReference function,
1253  int num_reg_arguments,
1254  int num_double_arguments);
1255  void CallCFunction(Register function,
1256  int num_reg_arguments,
1257  int num_double_arguments);
1260 
1261  // There are two ways of passing double arguments on MIPS, depending on
1262  // whether soft or hard floating point ABI is used. These functions
1263  // abstract parameter passing for the three different ways we call
1264  // C functions from generated code.
1267  void MovToFloatResult(DoubleRegister src);
1268 
1269  // Calls an API function. Allocates HandleScope, extracts returned value
1270  // from handle and propagates exceptions. Restores context. stack_space
1271  // - space to be unwound on exit (includes the call JS arguments space and
1272  // the additional space allocated for the fast call).
1273  void CallApiFunctionAndReturn(Register function_address,
1274  ExternalReference thunk_ref,
1275  int stack_space,
1276  MemOperand return_value_operand,
1277  MemOperand* context_restore_operand);
1278 
1279  // Jump to the builtin routine.
1280  void JumpToExternalReference(const ExternalReference& builtin,
1281  BranchDelaySlot bd = PROTECT);
1282 
1283  // Invoke specified builtin JavaScript function. Adds an entry to
1284  // the unresolved list if the name does not resolve.
1286  InvokeFlag flag,
1287  const CallWrapper& call_wrapper = NullCallWrapper());
1288 
1289  // Store the code object for the given builtin in the target register and
1290  // setup the function in a1.
1292 
1293  // Store the function for the given builtin in the target register.
1295 
1296  struct Unresolved {
1297  int pc;
1298  uint32_t flags; // See Bootstrapper::FixupFlags decoders/encoders.
1299  const char* name;
1300  };
1301 
1303  ASSERT(!code_object_.is_null());
1304  return code_object_;
1305  }
1306 
1307  // Emit code for a truncating division by a constant. The dividend register is
1308  // unchanged and at gets clobbered. Dividend and result must be different.
1309  void TruncatingDiv(Register result, Register dividend, int32_t divisor);
1310 
1311  // -------------------------------------------------------------------------
1312  // StatsCounter support.
1313 
1314  void SetCounter(StatsCounter* counter, int value,
1315  Register scratch1, Register scratch2);
1316  void IncrementCounter(StatsCounter* counter, int value,
1317  Register scratch1, Register scratch2);
1318  void DecrementCounter(StatsCounter* counter, int value,
1319  Register scratch1, Register scratch2);
1320 
1321 
1322  // -------------------------------------------------------------------------
1323  // Debugging.
1324 
1325  // Calls Abort(msg) if the condition cc is not satisfied.
1326  // Use --debug_code to enable.
1327  void Assert(Condition cc, BailoutReason reason, Register rs, Operand rt);
1328  void AssertFastElements(Register elements);
1329 
1330  // Like Assert(), but always enabled.
1331  void Check(Condition cc, BailoutReason reason, Register rs, Operand rt);
1332 
1333  // Print a message to stdout and abort execution.
1334  void Abort(BailoutReason msg);
1335 
1336  // Verify restrictions about code generated in stubs.
1337  void set_generating_stub(bool value) { generating_stub_ = value; }
1338  bool generating_stub() { return generating_stub_; }
1339  void set_has_frame(bool value) { has_frame_ = value; }
1340  bool has_frame() { return has_frame_; }
1341  inline bool AllowThisStubCall(CodeStub* stub);
1342 
1343  // ---------------------------------------------------------------------------
1344  // Number utilities.
1345 
1346  // Check whether the value of reg is a power of two and not zero. If not
1347  // control continues at the label not_power_of_two. If reg is a power of two
1348  // the register scratch contains the value of (reg - 1) when control falls
1349  // through.
1351  Register scratch,
1352  Label* not_power_of_two_or_zero);
1353 
1354  // -------------------------------------------------------------------------
1355  // Smi utilities.
1356 
1357  void SmiTag(Register reg) {
1358  Addu(reg, reg, reg);
1359  }
1360 
1361  // Test for overflow < 0: use BranchOnOverflow() or BranchOnNoOverflow().
1364 
1365  void SmiTag(Register dst, Register src) {
1366  Addu(dst, src, src);
1367  }
1368 
1369  // Try to convert int32 to smi. If the value is to large, preserve
1370  // the original value and jump to not_a_smi. Destroys scratch and
1371  // sets flags.
1372  void TrySmiTag(Register reg, Register scratch, Label* not_a_smi) {
1373  TrySmiTag(reg, reg, scratch, not_a_smi);
1374  }
1376  Register src,
1377  Register scratch,
1378  Label* not_a_smi) {
1379  SmiTagCheckOverflow(at, src, scratch);
1380  BranchOnOverflow(not_a_smi, scratch);
1381  mov(dst, at);
1382  }
1383 
1384  void SmiUntag(Register reg) {
1385  sra(reg, reg, kSmiTagSize);
1386  }
1387 
1388  void SmiUntag(Register dst, Register src) {
1389  sra(dst, src, kSmiTagSize);
1390  }
1391 
1392  // Test if the register contains a smi.
1393  inline void SmiTst(Register value, Register scratch) {
1394  And(scratch, value, Operand(kSmiTagMask));
1395  }
1396  inline void NonNegativeSmiTst(Register value, Register scratch) {
1397  And(scratch, value, Operand(kSmiTagMask | kSmiSignMask));
1398  }
1399 
1400  // Untag the source value into destination and jump if source is a smi.
1401  // Souce and destination can be the same register.
1402  void UntagAndJumpIfSmi(Register dst, Register src, Label* smi_case);
1403 
1404  // Untag the source value into destination and jump if source is not a smi.
1405  // Souce and destination can be the same register.
1406  void UntagAndJumpIfNotSmi(Register dst, Register src, Label* non_smi_case);
1407 
1408  // Jump the register contains a smi.
1409  void JumpIfSmi(Register value,
1410  Label* smi_label,
1411  Register scratch = at,
1412  BranchDelaySlot bd = PROTECT);
1413 
1414  // Jump if the register contains a non-smi.
1415  void JumpIfNotSmi(Register value,
1416  Label* not_smi_label,
1417  Register scratch = at,
1418  BranchDelaySlot bd = PROTECT);
1419 
1420  // Jump if either of the registers contain a non-smi.
1421  void JumpIfNotBothSmi(Register reg1, Register reg2, Label* on_not_both_smi);
1422  // Jump if either of the registers contain a smi.
1423  void JumpIfEitherSmi(Register reg1, Register reg2, Label* on_either_smi);
1424 
1425  // Abort execution if argument is a smi, enabled via --debug-code.
1426  void AssertNotSmi(Register object);
1427  void AssertSmi(Register object);
1428 
1429  // Abort execution if argument is not a string, enabled via --debug-code.
1430  void AssertString(Register object);
1431 
1432  // Abort execution if argument is not a name, enabled via --debug-code.
1433  void AssertName(Register object);
1434 
1435  // Abort execution if argument is not undefined or an AllocationSite, enabled
1436  // via --debug-code.
1437  void AssertUndefinedOrAllocationSite(Register object, Register scratch);
1438 
1439  // Abort execution if reg is not the root value with the given index,
1440  // enabled via --debug-code.
1441  void AssertIsRoot(Register reg, Heap::RootListIndex index);
1442 
1443  // ---------------------------------------------------------------------------
1444  // HeapNumber utilities.
1445 
1446  void JumpIfNotHeapNumber(Register object,
1447  Register heap_number_map,
1448  Register scratch,
1449  Label* on_not_heap_number);
1450 
1451  // -------------------------------------------------------------------------
1452  // String utilities.
1453 
1454  // Generate code to do a lookup in the number string cache. If the number in
1455  // the register object is found in the cache the generated code falls through
1456  // with the result in the result register. The object and the result register
1457  // can be the same. If the number is not found in the cache the code jumps to
1458  // the label not_found with only the content of register object unchanged.
1459  void LookupNumberStringCache(Register object,
1460  Register result,
1461  Register scratch1,
1462  Register scratch2,
1463  Register scratch3,
1464  Label* not_found);
1465 
1466  // Checks if both instance types are sequential ASCII strings and jumps to
1467  // label if either is not.
1469  Register first_object_instance_type,
1470  Register second_object_instance_type,
1471  Register scratch1,
1472  Register scratch2,
1473  Label* failure);
1474 
1475  // Check if instance type is sequential ASCII string and jump to label if
1476  // it is not.
1478  Register scratch,
1479  Label* failure);
1480 
1481  void JumpIfNotUniqueName(Register reg, Label* not_unique_name);
1482 
1483  void EmitSeqStringSetCharCheck(Register string,
1484  Register index,
1485  Register value,
1486  Register scratch,
1487  uint32_t encoding_mask);
1488 
1489  // Test that both first and second are sequential ASCII strings.
1490  // Assume that they are non-smis.
1492  Register second,
1493  Register scratch1,
1494  Register scratch2,
1495  Label* failure);
1496 
1497  // Test that both first and second are sequential ASCII strings.
1498  // Check that they are non-smis.
1500  Register second,
1501  Register scratch1,
1502  Register scratch2,
1503  Label* failure);
1504 
1505  void ClampUint8(Register output_reg, Register input_reg);
1506 
1507  void ClampDoubleToUint8(Register result_reg,
1508  DoubleRegister input_reg,
1509  DoubleRegister temp_double_reg);
1510 
1511 
1512  void LoadInstanceDescriptors(Register map, Register descriptors);
1513  void EnumLength(Register dst, Register map);
1515 
1516  template<typename Field>
1517  void DecodeField(Register reg) {
1518  static const int shift = Field::kShift;
1519  static const int mask = (Field::kMask >> shift) << kSmiTagSize;
1520  srl(reg, reg, shift);
1521  And(reg, reg, Operand(mask));
1522  }
1523 
1524  // Generates function and stub prologue code.
1525  void Prologue(PrologueFrameMode frame_mode);
1526 
1527  // Activation support.
1528  void EnterFrame(StackFrame::Type type);
1529  void LeaveFrame(StackFrame::Type type);
1530 
1531  // Patch the relocated value (lui/ori pair).
1532  void PatchRelocatedValue(Register li_location,
1533  Register scratch,
1534  Register new_value);
1535  // Get the relocatad value (loaded data) from the lui/ori pair.
1536  void GetRelocatedValue(Register li_location,
1537  Register value,
1538  Register scratch);
1539 
1540  // Expects object in a0 and returns map with validated enum cache
1541  // in a0. Assumes that any other register can be used as a scratch.
1542  void CheckEnumCache(Register null_value, Label* call_runtime);
1543 
1544  // AllocationMemento support. Arrays may have an associated
1545  // AllocationMemento object that can be checked for in order to pretransition
1546  // to another type.
1547  // On entry, receiver_reg should point to the array object.
1548  // scratch_reg gets clobbered.
1549  // If allocation info is present, jump to allocation_memento_present.
1551  Register receiver_reg,
1552  Register scratch_reg,
1553  Label* no_memento_found,
1554  Condition cond = al,
1555  Label* allocation_memento_present = NULL);
1556 
1558  Register scratch_reg,
1559  Label* memento_found) {
1560  Label no_memento_found;
1561  TestJSArrayForAllocationMemento(receiver_reg, scratch_reg,
1562  &no_memento_found, eq, memento_found);
1563  bind(&no_memento_found);
1564  }
1565 
1566  // Jumps to found label if a prototype map has dictionary elements.
1567  void JumpIfDictionaryInPrototypeChain(Register object, Register scratch0,
1568  Register scratch1, Label* found);
1569 
1570  private:
1571  void CallCFunctionHelper(Register function,
1572  int num_reg_arguments,
1573  int num_double_arguments);
1574 
1575  void BranchAndLinkShort(int16_t offset, BranchDelaySlot bdslot = PROTECT);
1576  void BranchAndLinkShort(int16_t offset, Condition cond, Register rs,
1577  const Operand& rt,
1578  BranchDelaySlot bdslot = PROTECT);
1579  void BranchAndLinkShort(Label* L, BranchDelaySlot bdslot = PROTECT);
1580  void BranchAndLinkShort(Label* L, Condition cond, Register rs,
1581  const Operand& rt,
1582  BranchDelaySlot bdslot = PROTECT);
1583  void J(Label* L, BranchDelaySlot bdslot);
1584  void Jr(Label* L, BranchDelaySlot bdslot);
1585  void Jalr(Label* L, BranchDelaySlot bdslot);
1586 
1587  // Helper functions for generating invokes.
1588  void InvokePrologue(const ParameterCount& expected,
1589  const ParameterCount& actual,
1590  Handle<Code> code_constant,
1591  Register code_reg,
1592  Label* done,
1593  bool* definitely_mismatches,
1594  InvokeFlag flag,
1595  const CallWrapper& call_wrapper);
1596 
1597  // Get the code for the given builtin. Returns if able to resolve
1598  // the function in the 'resolved' flag.
1599  Handle<Code> ResolveBuiltin(Builtins::JavaScript id, bool* resolved);
1600 
1601  void InitializeNewString(Register string,
1602  Register length,
1603  Heap::RootListIndex map_index,
1604  Register scratch1,
1605  Register scratch2);
1606 
1607  // Helper for implementing JumpIfNotInNewSpace and JumpIfInNewSpace.
1608  void InNewSpace(Register object,
1609  Register scratch,
1610  Condition cond, // eq for new space, ne otherwise.
1611  Label* branch);
1612 
1613  // Helper for finding the mark bits for an address. Afterwards, the
1614  // bitmap register points at the word with the mark bits and the mask
1615  // the position of the first bit. Leaves addr_reg unchanged.
1616  inline void GetMarkBits(Register addr_reg,
1617  Register bitmap_reg,
1618  Register mask_reg);
1619 
1620  // Helper for throwing exceptions. Compute a handler address and jump to
1621  // it. See the implementation for register usage.
1622  void JumpToHandlerEntry();
1623 
1624  // Compute memory operands for safepoint stack slots.
1625  static int SafepointRegisterStackIndex(int reg_code);
1626  MemOperand SafepointRegisterSlot(Register reg);
1627  MemOperand SafepointRegistersAndDoublesSlot(Register reg);
1628 
1629  bool generating_stub_;
1630  bool has_frame_;
1631  // This handle will be patched with the code object on installation.
1632  Handle<Object> code_object_;
1633 
1634  // Needs access to SafepointRegisterStackIndex for compiled frame
1635  // traversal.
1636  friend class StandardFrame;
1637 };
1638 
1639 
1640 // The code patcher is used to patch (typically) small parts of code e.g. for
1641 // debugging and other types of instrumentation. When using the code patcher
1642 // the exact number of bytes specified must be emitted. It is not legal to emit
1643 // relocation information. If any of these constraints are violated it causes
1644 // an assertion to fail.
1645 class CodePatcher {
1646  public:
1647  CodePatcher(byte* address, int instructions);
1648  virtual ~CodePatcher();
1649 
1650  // Macro assembler to emit code.
1651  MacroAssembler* masm() { return &masm_; }
1652 
1653  // Emit an instruction directly.
1654  void Emit(Instr instr);
1655 
1656  // Emit an address directly.
1657  void Emit(Address addr);
1658 
1659  // Change the condition part of an instruction leaving the rest of the current
1660  // instruction unchanged.
1661  void ChangeBranchCondition(Condition cond);
1662 
1663  private:
1664  byte* address_; // The address of the code being patched.
1665  int size_; // Number of bytes of the expected patch size.
1666  MacroAssembler masm_; // Macro assembler used to generate the code.
1667 };
1668 
1669 
1670 
1671 #ifdef GENERATED_CODE_COVERAGE
1672 #define CODE_COVERAGE_STRINGIFY(x) #x
1673 #define CODE_COVERAGE_TOSTRING(x) CODE_COVERAGE_STRINGIFY(x)
1674 #define __FILE_LINE__ __FILE__ ":" CODE_COVERAGE_TOSTRING(__LINE__)
1675 #define ACCESS_MASM(masm) masm->stop(__FILE_LINE__); masm->
1676 #else
1677 #define ACCESS_MASM(masm) masm->
1678 #endif
1679 
1680 } } // namespace v8::internal
1681 
1682 #endif // V8_MIPS_MACRO_ASSEMBLER_MIPS_H_
byte * Address
Definition: globals.h:186
void TrySmiTag(Register reg, Label *not_a_smi)
enable upcoming ES6 features enable harmony block scoping enable harmony enable harmony proxies enable harmony generators enable harmony numeric enable harmony string enable harmony math functions harmony_scoping harmony_symbols harmony_collections harmony_iteration harmony_strings harmony_scoping harmony_maths tracks arrays with only smi values Optimize object Array DOM strings and string pretenure call new trace pretenuring decisions of HAllocate instructions track fields with only smi values track fields with heap values track_fields track_fields Enables optimizations which favor memory size over execution speed use string slices optimization filter maximum number of GVN fix point iterations use function inlining use allocation folding eliminate write barriers targeting allocations in optimized code maximum source size in bytes considered for a single inlining maximum cumulative number of AST nodes considered for inlining crankshaft harvests type feedback from stub cache trace check elimination phase hydrogen tracing filter NULL
Definition: flags.cc:269
void Neg(const Register &rd, const Operand &operand)
const SwVfpRegister s2
void ClampUint8(Register output_reg, Register input_reg)
const int kCArgsSlotsSize
Isolate * isolate() const
Definition: assembler.h:62
void LoadNumber(Register object, LowDwVfpRegister dst, Register heap_number_map, Register scratch, Label *not_number)
void EmitFPUTruncate(FPURoundingMode rounding_mode, Register result, DoubleRegister double_input, Register scratch, DoubleRegister double_scratch, Register except_flag, CheckForInexactConversion check_inexact=kDontCheckForInexactConversion)
const intptr_t kSmiTagMask
Definition: v8.h:5480
const intptr_t kSmiSignMask
Definition: v8globals.h:41
void FlushICache(Register address, unsigned instructions)
void Branch(Label *L, Condition cond, Register rs, Heap::RootListIndex index, BranchDelaySlot bdslot=PROTECT)
static int SlotOffset(int index)
Definition: contexts.h:498
void InvokeFunction(Register function, const ParameterCount &actual, InvokeFlag flag, const CallWrapper &call_wrapper)
void mtc1(Register rt, FPURegister fs)
const Register r3
enable upcoming ES6 features enable harmony block scoping enable harmony enable harmony proxies enable harmony generators enable harmony numeric enable harmony string enable harmony math functions harmony_scoping harmony_symbols harmony_collections harmony_iteration harmony_strings harmony_scoping harmony_maths tracks arrays with only smi values Optimize object Array DOM strings and string pretenure call new trace pretenuring decisions of HAllocate instructions track fields with only smi values track fields with heap values track_fields track_fields Enables optimizations which favor memory size over execution speed use string slices optimization filter maximum number of GVN fix point iterations use function inlining use allocation folding eliminate write barriers targeting allocations in optimized code maximum source size in bytes considered for a single inlining maximum cumulative number of AST nodes considered for inlining crankshaft harvests type feedback from stub cache trace check elimination phase hydrogen tracing filter trace hydrogen to given file name trace inlining decisions trace store elimination trace all use positions trace global value numbering trace hydrogen escape analysis trace the tracking of allocation sites trace map generalization environment for every instruction deoptimize every n garbage collections put a break point before deoptimizing deoptimize uncommon cases use on stack replacement trace array bounds check elimination perform array index dehoisting use load elimination use store elimination use constant folding eliminate unreachable code number of stress runs when picking a function to watch for shared function not JSFunction itself flushes the cache of optimized code for closures on every GC functions with arguments object maximum number of escape analysis fix point iterations allow uint32 values on optimize frames if they are used only in safe operations track concurrent recompilation artificial compilation delay in ms concurrent on stack replacement do not emit check maps for constant values that have a leaf map
Definition: flags.cc:350
void SmiTag(Register dst, Register src)
CodePatcher(byte *address, int instructions, FlushICache flush_cache=FLUSH)
void AllocateTwoByteSlicedString(Register result, Register length, Register scratch1, Register scratch2, Label *gc_required)
void mov(Register rd, Register rt)
void IncrementalMarkingRecordWriteHelper(Register object, Register value, Register address)
const Register cp
void LoadNumberAsInt32Double(Register object, DwVfpRegister double_dst, Register heap_number_map, Register scratch, LowDwVfpRegister double_scratch, Label *not_int32)
void Push(Register src1, Register src2, Register src3, Register src4)
void JumpIfInNewSpace(Register object, Register scratch, Label *branch)
void AssertString(Register object)
void sw(Register rd, const MemOperand &rs)
void AdduAndCheckForOverflow(Register dst, Register left, Register right, Register overflow_dst, Register scratch=at)
void IsObjectJSStringType(Register object, Register scratch, Label *fail)
void mov_d(FPURegister fd, FPURegister fs)
static TypeFeedbackId None()
Definition: utils.h:1149
void JumpToExternalReference(const ExternalReference &builtin)
void Pop(Register src1, Register src2, Register src3)
void Cvt_d_uw(FPURegister fd, FPURegister fs, FPURegister scratch)
void UntagAndJumpIfSmi(Register dst, Register src, Label *smi_case)
void LoadInstanceDescriptors(Register map, Register descriptors)
void AllocateAsciiString(Register result, Register length, Register scratch1, Register scratch2, Register scratch3, Label *gc_required)
void JumpIfNotBothSequentialAsciiStrings(Register first, Register second, Register scratch1, Register scratch2, Label *not_flat_ascii_strings)
void LoadFromNumberDictionary(Label *miss, Register elements, Register key, Register result, Register t0, Register t1, Register t2)
void JumpIfDictionaryInPrototypeChain(Register object, Register scratch0, Register scratch1, Label *found)
void or_(Register dst, int32_t imm32)
void CheckMap(Register obj, Register scratch, Handle< Map > map, Label *fail, SmiCheckType smi_check_type)
void Store(Register src, const MemOperand &dst, Representation r)
void SubuAndCheckForOverflow(Register dst, Register left, Register right, Register overflow_dst, Register scratch=at)
void GetBuiltinEntry(Register target, Builtins::JavaScript id)
void JumpIfSmi(Register value, Label *smi_label)
void MovFromFloatParameter(DwVfpRegister dst)
void DispatchMap(Register obj, Register scratch, Handle< Map > map, Handle< Code > success, SmiCheckType smi_check_type)
TypeImpl< ZoneTypeConfig > Type
bool AllowThisStubCall(CodeStub *stub)
int int32_t
Definition: unicode.cc:47
uint32_t RegList
Definition: frames.h:41
void JumpIfNotPowerOfTwoOrZero(Register reg, Register scratch, Label *not_power_of_two_or_zero)
void EnterFrame(StackFrame::Type type, bool load_constant_pool=false)
void StoreToSafepointRegisterSlot(Register src, Register dst)
void LeaveExitFrame(bool save_doubles, Register argument_count, bool restore_context)
void FmoveHigh(Register dst_high, FPURegister src)
void CheckFastObjectElements(Register map, Register scratch, Label *fail)
void j(Condition cc, Label *L, Label::Distance distance=Label::kFar)
static const Function * FunctionForId(FunctionId id)
Definition: runtime.cc:15154
void Swap(Register reg1, Register reg2, Register scratch=no_reg, Condition cond=al)
void InvokeCode(Register code, const ParameterCount &expected, const ParameterCount &actual, InvokeFlag flag, const CallWrapper &call_wrapper)
bool is(FPURegister creg) const
void MultiPopReversed(RegList regs)
void ThrowIf(Condition cc, BailoutReason reason)
#define ASSERT(condition)
Definition: checks.h:329
#define DECLARE_BRANCH_PROTOTYPES(Name)
void AssertNotSmi(Register object)
void RecordWriteField(Register object, int offset, Register value, Register scratch, LinkRegisterStatus lr_status, SaveFPRegsMode save_fp, RememberedSetAction remembered_set_action=EMIT_REMEMBERED_SET, SmiCheck smi_check=INLINE_SMI_CHECK)
unsigned short uint16_t
Definition: unicode.cc:46
void SmiTagCheckOverflow(Register reg, Register overflow)
void PushTryHandler(StackHandler::Kind kind, int handler_index)
void LoadTransitionedArrayMapConditional(ElementsKind expected_kind, ElementsKind transitioned_kind, Register map_in_out, Register scratch, Label *no_map_match)
void And(Register dst, Register src1, const Operand &src2, Condition cond=al)
void Usw(Register rd, const MemOperand &rs)
#define COND_ARGS
static bool IsMarkedCode(Instr instr, int type)
void NumberOfOwnDescriptors(Register dst, Register map)
void Ext(Register rt, Register rs, uint16_t pos, uint16_t size)
MemOperand GlobalObjectOperand()
void IncrementCounter(StatsCounter *counter, int value, Register scratch1, Register scratch2)
void Move(FPURegister dst, Register src_low, Register src_high)
const Register r2
void RetOnOverflow(Register overflow_check, BranchDelaySlot bd=PROTECT)
void Mul(const Register &rd, const Register &rn, const Register &rm)
void MarkCode(NopMarkerTypes type)
void Load(Register dst, const MemOperand &src, Representation r)
MemOperand ContextOperand(Register context, int index)
void RetOnNoOverflow(Register overflow_check, BranchDelaySlot bd=PROTECT)
void AssertSmi(Register object)
void JumpIfNotUniqueName(Register reg, Label *not_unique_name)
void DecrementCounter(StatsCounter *counter, int value, Register scratch1, Register scratch2)
void StoreToSafepointRegistersAndDoublesSlot(Register src, Register dst)
void TruncatingDiv(Register result, Register dividend, int32_t divisor)
void EmitSeqStringSetCharCheck(Register string, Register index, Register value, uint32_t encoding_mask)
kInstanceClassNameOffset flag
Definition: objects-inl.h:5115
void Ulw(Register rd, const MemOperand &rs)
void Movn(Register rd, Register rs, Register rt)
void Abort(BailoutReason msg)
const Register kRootRegister
void IsObjectNameType(Register object, Register scratch, Label *fail)
void Movz(Register rd, Register rs, Register rt)
uint8_t byte
Definition: globals.h:185
void PrepareCEntryFunction(const ExternalReference &ref)
void MultiPush(RegList regs)
void JumpIfInstanceTypeIsNotSequentialAscii(Register type, Register scratch, Label *failure)
void SmiToDoubleFPURegister(Register smi, FPURegister value, Register scratch1)
void MovFromFloatResult(DwVfpRegister dst)
void JumpIfNotHeapNumber(Register object, Register heap_number_map, Register scratch, Label *on_not_heap_number)
const Register sp
void Pref(int32_t hint, const MemOperand &rs)
void MultiPop(RegList regs)
void JumpIfNotInNewSpace(Register object, Register scratch, Label *branch)
void IsObjectJSObjectType(Register heap_object, Register map, Register scratch, Label *fail)
void BranchOnNoOverflow(Label *label, Register overflow_check, BranchDelaySlot bd=PROTECT)
enable upcoming ES6 features enable harmony block scoping enable harmony enable harmony proxies enable harmony generators enable harmony numeric enable harmony string enable harmony math functions harmony_scoping harmony_symbols harmony_collections harmony_iteration harmony_strings harmony_scoping harmony_maths tracks arrays with only smi values Optimize object Array DOM strings and string pretenure call new trace pretenuring decisions of HAllocate instructions track fields with only smi values track fields with heap values track_fields track_fields Enables optimizations which favor memory size over execution speed use string slices optimization filter maximum number of GVN fix point iterations use function inlining use allocation folding eliminate write barriers targeting allocations in optimized code maximum source size in bytes considered for a single inlining maximum cumulative number of AST nodes considered for inlining crankshaft harvests type feedback from stub cache trace check elimination phase hydrogen tracing filter trace hydrogen to given file name trace inlining decisions trace store elimination trace all use positions trace global value numbering trace hydrogen escape analysis trace the tracking of allocation sites trace map generalization environment for every instruction deoptimize every n garbage collections put a break point before deoptimizing deoptimize uncommon cases use on stack replacement trace array bounds check elimination perform array index dehoisting use load elimination use store elimination use constant folding eliminate unreachable code number of stress runs when picking a function to watch for shared function not JSFunction itself flushes the cache of optimized code for closures on every GC functions with arguments object maximum number of escape analysis fix point iterations allow uint32 values on optimize frames if they are used only in safe operations track concurrent recompilation artificial compilation delay in ms concurrent on stack replacement do not emit check maps for constant values that have a leaf deoptimize the optimized code if the layout of the maps changes number of stack frames inspected by the profiler percentage of ICs that must have type info to allow optimization extra verbose compilation tracing generate extra emit comments in code disassembly enable use of SSE3 instructions if available enable use of CMOV instruction if available enable use of VFP3 instructions if available enable use of NEON instructions if enable use of SDIV and UDIV instructions if enable loading bit constant by means of movw movt instruction enable unaligned accesses for enable use of d16 d31 registers on ARM this requires VFP3 force all emitted branches to be in long mode(MIPS only)") DEFINE_string(expose_natives_as
enable upcoming ES6 features enable harmony block scoping enable harmony enable harmony proxies enable harmony generators enable harmony numeric enable harmony string enable harmony math functions harmony_scoping harmony_symbols harmony_collections harmony_iteration harmony_strings harmony_scoping harmony_maths tracks arrays with only smi values Optimize object size
Definition: flags.cc:211
void sra(Register rt, Register rd, uint16_t sa)
void TestJSArrayForAllocationMemento(Register receiver_reg, Register scratch_reg, Label *no_memento_found)
void EnumLength(Register dst, Register map)
static int ActivationFrameAlignment()
void TruncateNumberToI(Register object, Register result, Register heap_number_map, Register scratch1, Label *not_int32)
void lbu(Register rd, const MemOperand &rs)
void MovToFloatResult(DwVfpRegister src)
void CheckFastElements(Register map, Register scratch, Label *fail)
enable upcoming ES6 features enable harmony block scoping enable harmony enable harmony proxies enable harmony generators enable harmony numeric enable harmony string enable harmony math functions harmony_scoping harmony_symbols harmony_collections harmony_iteration harmony_strings harmony_scoping harmony_maths tracks arrays with only smi values Optimize object Array DOM strings and string pretenure call new trace pretenuring decisions of HAllocate instructions track fields with only smi values track fields with heap values track_fields track_fields Enables optimizations which favor memory size over execution speed use string slices optimization filter maximum number of GVN fix point iterations use function inlining use allocation folding eliminate write barriers targeting allocations in optimized code maximum source size in bytes considered for a single inlining maximum cumulative number of AST nodes considered for inlining crankshaft harvests type feedback from stub cache trace check elimination phase hydrogen tracing filter trace hydrogen to given file name trace inlining decisions trace store elimination trace all use positions trace global value numbering trace hydrogen escape analysis trace the tracking of allocation sites trace map generalization environment for every instruction deoptimize every n garbage collections put a break point before deoptimizing deoptimize uncommon cases use on stack replacement trace array bounds check elimination perform array index dehoisting use load elimination use store elimination use constant folding eliminate unreachable code number of stress runs when picking a function to watch for shared function not JSFunction itself flushes the cache of optimized code for closures on every GC functions with arguments object maximum number of escape analysis fix point iterations allow uint32 values on optimize frames if they are used only in safe operations track concurrent recompilation artificial compilation delay in ms concurrent on stack replacement do not emit check maps for constant values that have a leaf deoptimize the optimized code if the layout of the maps changes number of stack frames inspected by the profiler percentage of ICs that must have type info to allow optimization extra verbose compilation tracing generate extra emit comments in code disassembly enable use of SSE3 instructions if available enable use of CMOV instruction if available enable use of VFP3 instructions if available enable use of NEON instructions if enable use of SDIV and UDIV instructions if enable loading bit constant by means of movw movt instruction enable unaligned accesses for enable use of d16 d31 registers on ARM this requires VFP3 force all emitted branches to be in long expose natives in global object expose freeBuffer extension expose gc extension under the specified name expose externalize string extension number of stack frames to capture disable builtin natives files print name of functions for which code is generated use random jit cookie to mask large constants trace lazy optimization use adaptive optimizations always try to OSR functions trace optimize function deoptimization minimum length for automatic enable preparsing maximum number of optimization attempts before giving up cache prototype transitions trace debugging JSON request response trace out of bounds accesses to external arrays trace_js_array_abuse automatically set the debug break flag when debugger commands are in the queue abort by crashing maximum length of function source code printed in a stack trace max size of the new max size of the old max size of executable always perform global GCs print one trace line following each garbage collection do not print trace line after scavenger collection print statistics of the maximum memory committed for the heap in only print modified registers Don t break for ASM_UNIMPLEMENTED_BREAK macros print stack trace when an illegal exception is thrown randomize hashes to avoid predictable hash Fixed seed to use to hash property Print the time it takes to deserialize the snapshot testing_bool_flag testing_int_flag string flag tmp file in which to serialize heap Print the time it takes to lazily compile hydrogen code stubs concurrent_recompilation concurrent_sweeping Print usage including flags
Definition: flags.cc:665
const int kRsFieldMask
void LoadGlobalFunction(int index, Register function)
void CheckPageFlag(Register object, Register scratch, int mask, Condition cc, Label *condition_met)
void TryGetFunctionPrototype(Register function, Register result, Register scratch, Label *miss, bool miss_on_bound_function=false)
void TrySmiTag(Register reg, Register scratch, Label *not_a_smi)
const int kRtFieldMask
PrologueFrameMode
Definition: frames.h:957
void Emit(Instr instr)
void ChangeBranchCondition(Condition cond)
void SmiTst(Register value, Register scratch)
const int kOpcodeMask
const int kPointerSize
Definition: globals.h:268
void CallStub(CodeStub *stub, TypeFeedbackId ast_id=TypeFeedbackId::None(), Condition cond=al)
void CallCFunction(ExternalReference function, int num_arguments)
void AllocateAsciiConsString(Register result, Register length, Register scratch1, Register scratch2, Label *gc_required)
void IsInstanceJSObjectType(Register map, Register scratch, Label *fail)
void CheckFastSmiElements(Register map, Register scratch, Label *fail)
const int kHeapObjectTag
Definition: v8.h:5473
void Jump(Register target, Condition cond=al)
void RecordWrite(Register object, Register address, Register value, LinkRegisterStatus lr_status, SaveFPRegsMode save_fp, RememberedSetAction remembered_set_action=EMIT_REMEMBERED_SET, SmiCheck smi_check=INLINE_SMI_CHECK)
void JumpIfDataObject(Register value, Register scratch, Label *not_data_object)
void TruncateHeapNumberToI(Register result, Register object)
const int kRtShift
void Push(Register src1, Register src2)
void Allocate(int object_size, Register result, Register scratch1, Register scratch2, Label *gc_required, AllocationFlags flags)
void AllocateHeapNumber(Register result, Register scratch1, Register scratch2, Register heap_number_map, Label *gc_required, TaggingMode tagging_mode=TAG_RESULT)
void CopyBytes(Register src, Register dst, Register length, Register scratch)
void Throw(Register value)
void Move(FPURegister dst, FPURegister src)
void Move(Register dst, Handle< Object > value)
enable upcoming ES6 features enable harmony block scoping enable harmony enable harmony proxies enable harmony generators enable harmony numeric enable harmony string enable harmony math functions harmony_scoping harmony_symbols harmony_collections harmony_iteration harmony_strings harmony_scoping harmony_maths tracks arrays with only smi values Optimize object Array DOM strings and string pretenure call new trace pretenuring decisions of HAllocate instructions track fields with only smi values track fields with heap values track_fields track_fields Enables optimizations which favor memory size over execution speed use string slices optimization filter maximum number of GVN fix point iterations use function inlining use allocation folding eliminate write barriers targeting allocations in optimized code maximum source size in bytes considered for a single inlining maximum cumulative number of AST nodes considered for inlining crankshaft harvests type feedback from stub cache trace check elimination phase hydrogen tracing filter trace hydrogen to given file name trace inlining decisions trace store elimination trace all use positions trace global value numbering trace hydrogen escape analysis trace the tracking of allocation sites trace map generalization environment for every instruction deoptimize every n garbage collections put a break point before deoptimizing deoptimize uncommon cases use on stack replacement trace array bounds check elimination perform array index dehoisting use load elimination use store elimination use constant folding eliminate unreachable code number of stress runs when picking a function to watch for shared function not JSFunction itself flushes the cache of optimized code for closures on every GC functions with arguments object maximum number of escape analysis fix point iterations allow uint32 values on optimize frames if they are used only in safe operations track concurrent recompilation artificial compilation delay in ms concurrent on stack replacement do not emit check maps for constant values that have a leaf deoptimize the optimized code if the layout of the maps changes number of stack frames inspected by the profiler percentage of ICs that must have type info to allow optimization extra verbose compilation tracing generate extra code(assertions) for debugging") DEFINE_bool(code_comments
void Ins(Register rt, Register rs, uint16_t pos, uint16_t size)
void Movt(Register rd, Register rs, uint16_t cc=0)
const int kCArgSlotCount
void srl(Register rd, Register rt, uint16_t sa)
void SetCounter(StatsCounter *counter, int value, Register scratch1, Register scratch2)
void GetRelocatedValue(Register li_location, Register value, Register scratch)
void Floor_w_d(FPURegister fd, FPURegister fs)
const SwVfpRegister s0
void SmiUntag(Register dst, Register src)
void GetLeastBitsFromInt32(Register dst, Register src, int mun_least_bits)
const int kSaShift
MacroAssembler(Isolate *isolate, void *buffer, int size)
const uint32_t kStringTag
Definition: objects.h:598
void LoadContext(Register dst, int context_chain_length)
Condition IsObjectStringType(Register obj, Register type, Register result)
void CallExternalReference(const ExternalReference &ext, int num_arguments)
static int CallSize(Register target, Condition cond=al)
void CallApiFunctionAndReturn(Register function_address, ExternalReference thunk_ref, int stack_space, MemOperand return_value_operand, MemOperand *context_restore_operand)
void AssertFastElements(Register elements)
void GetLeastBitsFromSmi(Register dst, Register src, int num_least_bits)
const int kSaFieldMask
void CheckMapDeprecated(Handle< Map > map, Register scratch, Label *if_deprecated)
void CompareMapAndBranch(Register obj, Register scratch, Handle< Map > map, Label *early_success, Condition cond, Label *branch_to)
void JumpIfNotBothSmi(Register reg1, Register reg2, Label *on_not_both_smi)
void JumpIfBlack(Register object, Register scratch0, Register scratch1, Label *on_black)
void lw(Register rd, const MemOperand &rs)
void ClampDoubleToUint8(Register result_reg, DwVfpRegister input_reg, LowDwVfpRegister double_scratch)
void AllocateTwoByteConsString(Register result, Register length, Register scratch1, Register scratch2, Label *gc_required)
void Pop(Register src1, Register src2)
static bool IsNop(Instr instr, int type=NON_MARKING_NOP)
void Drop(int count, Condition cond=al)
const SwVfpRegister s1
InvokeFlag
void GetBuiltinFunction(Register target, Builtins::JavaScript id)
void NonNegativeSmiTst(Register value, Register scratch)
void Movf(Register rd, Register rs, uint16_t cc=0)
void IllegalOperation(int num_arguments)
AllocationFlags
enable upcoming ES6 features enable harmony block scoping enable harmony enable harmony proxies enable harmony generators enable harmony numeric enable harmony string enable harmony math functions harmony_scoping harmony_symbols harmony_collections harmony_iteration harmony_strings harmony_scoping harmony_maths tracks arrays with only smi values Optimize object Array shift
void ObjectToDoubleFPURegister(Register object, FPURegister value, Register scratch1, Register scratch2, Register heap_number_map, Label *not_number, ObjectToDoubleFlags flags=NO_OBJECT_TO_DOUBLE_FLAGS)
void CheckAccessGlobalProxy(Register holder_reg, Register scratch, Label *miss)
void CopyFields(Register dst, Register src, LowDwVfpRegister double_scratch, int field_count)
static const int kMapOffset
Definition: objects.h:1890
int ToNumber(Register reg)
bool is(Register reg) const
void LookupNumberStringCache(Register object, Register result, Register scratch1, Register scratch2, Register scratch3, Label *not_found)
void TruncateDoubleToI(Register result, DwVfpRegister double_input)
const uint32_t kIsNotStringMask
Definition: objects.h:597
Register GetRegisterThatIsNotOneOf(Register reg1, Register reg2=no_reg, Register reg3=no_reg, Register reg4=no_reg, Register reg5=no_reg, Register reg6=no_reg)
const Register r1
void Clz(const Register &rd, const Register &rn)
void li(Register rd, Operand j, LiFlags mode=OPTIMIZE_SIZE)
void CallRuntimeSaveDoubles(Runtime::FunctionId id)
Handle< T > handle(T *t, Isolate *isolate)
Definition: handles.h:103
void ThrowUncatchable(Register value)
void Trunc_uw_d(FPURegister fd, FPURegister fs, FPURegister scratch)
void TrySmiTag(Register dst, Register src, Register scratch, Label *not_a_smi)
MemOperand CFunctionArgumentOperand(int index)
void StoreRoot(Register source, Heap::RootListIndex index, Condition cond=al)
MemOperand FieldMemOperand(Register object, int offset)
void PrepareCallCFunction(int num_reg_arguments, int num_double_registers, Register scratch)
void GetObjectType(Register function, Register map, Register type_reg)
void MovToFloatParameters(DwVfpRegister src1, DwVfpRegister src2)
void LoadNumberAsInt32(Register object, Register dst, Register heap_number_map, Register scratch, DwVfpRegister double_scratch0, LowDwVfpRegister double_scratch1, Label *not_int32)
void LoadGlobalFunctionInitialMap(Register function, Register map, Register scratch)
void GetNumberHash(Register t0, Register scratch)
void hint(SystemHint code)
void CallRuntime(const Runtime::Function *f, int num_arguments, SaveFPRegsMode save_doubles=kDontSaveFPRegs)
void MultiPopReversedFPU(RegList regs)
void Ror(const Register &rd, const Register &rs, unsigned shift)
const int kSmiTagSize
Definition: v8.h:5479
static int GetCodeMarker(Instr instr)
void li(Register rd, int32_t j, LiFlags mode=OPTIMIZE_SIZE)
void JumpIfNonSmisNotBothSequentialAsciiStrings(Register object1, Register object2, Register scratch1, Register scratch2, Label *failure)
void mfc1(Register rt, FPURegister fs)
void JumpIfBothInstanceTypesAreNotSequentialAscii(Register first_object_instance_type, Register second_object_instance_type, Register scratch1, Register scratch2, Label *failure)
void MovToFloatParameter(DwVfpRegister src)
void UndoAllocationInNewSpace(Register object, Register scratch)
void Ret(BranchDelaySlot bd, Condition cond=al, Register rs=zero_reg, const Operand &rt=Operand(zero_reg))
void Prologue(PrologueFrameMode frame_mode)
void LoadFromSafepointRegisterSlot(Register dst, Register src)
const int kRsShift
void Push(Register src, Condition cond, Register tst1, Register tst2)
#define ASSERT_EQ(v1, v2)
Definition: checks.h:330
void JumpIfJSArrayHasAllocationMemento(Register receiver_reg, Register scratch_reg, Label *memento_found)
void Call(Register target, Condition cond=al)
void Trunc_w_d(FPURegister fd, FPURegister fs)
void FmoveLow(Register dst_low, FPURegister src)
void AllocateAsciiSlicedString(Register result, Register length, Register scratch1, Register scratch2, Label *gc_required)
void Check(Condition cond, BailoutReason reason)
void CallRuntime(Runtime::FunctionId id, int num_arguments, SaveFPRegsMode save_doubles=kDontSaveFPRegs)
void MultiPushFPU(RegList regs)
void JumpIfNotSmi(Register value, Label *not_smi_label)
void TryInlineTruncateDoubleToI(Register result, DwVfpRegister input, Label *done)
void MultiPushReversedFPU(RegList regs)
void BranchF(BranchDelaySlot bd, Label *target, Label *nan, Condition cc, FPURegister cmp1, FPURegister cmp2)
void Assert(Condition cond, BailoutReason reason)
void InvokeBuiltin(Builtins::JavaScript id, InvokeFlag flag, const CallWrapper &call_wrapper=NullCallWrapper())
void StoreNumberToDoubleElements(Register value_reg, Register key_reg, Register elements_reg, Register scratch1, LowDwVfpRegister double_scratch, Label *fail, int elements_offset=0)
void TailCallStub(CodeStub *stub, Condition cond=al)
HeapObject * obj
void UntagAndJumpIfNotSmi(Register dst, Register src, Label *non_smi_case)
void AssertIsRoot(Register reg, Heap::RootListIndex index)
void AssertName(Register object)
const Register no_reg
void EnsureNotWhite(Register object, Register scratch1, Register scratch2, Register scratch3, Label *object_is_white_and_not_data)
int CalculateStackPassedWords(int num_reg_arguments, int num_double_arguments)
void CallJSExitStub(CodeStub *stub)
int LeaveFrame(StackFrame::Type type)
void JumpIfEitherSmi(Register reg1, Register reg2, Label *on_either_smi)
void PatchRelocatedValue(Register li_location, Register scratch, Register new_value)
static FPURegister from_code(int code)
void IndexFromHash(Register hash, Register index)
void Round_w_d(FPURegister fd, FPURegister fs)
void TailCallExternalReference(const ExternalReference &ext, int num_arguments, int result_size)
signed short int16_t
Definition: unicode.cc:45
void EnterExitFrame(bool save_doubles, int stack_space=0)
void MultiPushReversed(RegList regs)
void InitializeFieldsWithFiller(Register start_offset, Register end_offset, Register filler)
void RecordWriteContextSlot(Register context, int offset, Register value, Register scratch, RAStatus ra_status, SaveFPRegsMode save_fp, RememberedSetAction remembered_set_action=EMIT_REMEMBERED_SET, SmiCheck smi_check=INLINE_SMI_CHECK)
void TailCallRuntime(Runtime::FunctionId fid, int num_arguments, int result_size)
void AllocateTwoByteString(Register result, Register length, Register scratch1, Register scratch2, Register scratch3, Label *gc_required)
void LoadRoot(Register destination, Heap::RootListIndex index, Condition cond=al)
void MultiPopFPU(RegList regs)
void RememberedSetHelper(Register object, Register addr, Register scratch, SaveFPRegsMode save_fp, RememberedSetFinalAction and_then)
void Ceil_w_d(FPURegister fd, FPURegister fs)
void BranchF(Label *target, Label *nan, Condition cc, FPURegister cmp1, FPURegister cmp2, BranchDelaySlot bd=PROTECT)
void HasColor(Register object, Register scratch0, Register scratch1, Label *has_color, int first_bit, int second_bit)
void BranchOnOverflow(Label *label, Register overflow_check, BranchDelaySlot bd=PROTECT)
bool AreAliased(const CPURegister &reg1, const CPURegister &reg2, const CPURegister &reg3=NoReg, const CPURegister &reg4=NoReg, const CPURegister &reg5=NoReg, const CPURegister &reg6=NoReg, const CPURegister &reg7=NoReg, const CPURegister &reg8=NoReg)
void CheckEnumCache(Register null_value, Label *call_runtime)
static const int kInstanceTypeOffset
Definition: objects.h:6459
void AssertUndefinedOrAllocationSite(Register object, Register scratch)
void AllocateHeapNumberWithValue(Register result, DwVfpRegister value, Register scratch1, Register scratch2, Register heap_number_map, Label *gc_required)
const Register r4
void Move(Register dst_low, Register dst_high, FPURegister src)
void Move(Register dst, Register src)
void Push(Register src1, Register src2, Register src3)