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