Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(848)

Side by Side Diff: src/mips/macro-assembler-mips.h

Issue 6965006: Update mips infrastructure files. (Closed) Base URL: http://github.com/v8/v8.git@bleeding_edge
Patch Set: Fix additional style issues. Created 9 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2010 the V8 project authors. All rights reserved. 1 // Copyright 2011 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
11 // with the distribution. 11 // with the distribution.
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
45 // but won't touch other registers except in special cases. 45 // but won't touch other registers except in special cases.
46 // 46 //
47 // Per the MIPS ABI, register t9 must be used for indirect function call 47 // Per the MIPS ABI, register t9 must be used for indirect function call
48 // via 'jalr t9' or 'jr t9' instructions. This is relied upon by gcc when 48 // via 'jalr t9' or 'jr t9' instructions. This is relied upon by gcc when
49 // trying to update gp register for position-independent-code. Whenever 49 // trying to update gp register for position-independent-code. Whenever
50 // MIPS generated code calls C code, it must be via t9 register. 50 // MIPS generated code calls C code, it must be via t9 register.
51 51
52 // Registers aliases 52 // Registers aliases
53 // cp is assumed to be a callee saved register. 53 // cp is assumed to be a callee saved register.
54 const Register roots = s6; // Roots array pointer. 54 const Register roots = s6; // Roots array pointer.
55 const Register cp = s7; // JavaScript context pointer 55 const Register cp = s7; // JavaScript context pointer.
56 const Register fp = s8_fp; // Alias fp 56 const Register fp = s8_fp; // Alias for fp.
57 // Register used for condition evaluation. 57 // Registers used for condition evaluation.
58 const Register condReg1 = s4; 58 const Register condReg1 = s4;
59 const Register condReg2 = s5; 59 const Register condReg2 = s5;
60 60
61 61
62 // Flags used for the AllocateInNewSpace functions. 62 // Flags used for the AllocateInNewSpace functions.
63 enum AllocationFlags { 63 enum AllocationFlags {
64 // No special flags. 64 // No special flags.
65 NO_ALLOCATION_FLAGS = 0, 65 NO_ALLOCATION_FLAGS = 0,
66 // Return the pointer to the allocated already tagged as a heap object. 66 // Return the pointer to the allocated already tagged as a heap object.
67 TAG_OBJECT = 1 << 0, 67 TAG_OBJECT = 1 << 0,
(...skipping 17 matching lines...) Expand all
85 85
86 // Allow programmer to use Branch Delay Slot of Branches, Jumps, Calls. 86 // Allow programmer to use Branch Delay Slot of Branches, Jumps, Calls.
87 enum BranchDelaySlot { 87 enum BranchDelaySlot {
88 USE_DELAY_SLOT, 88 USE_DELAY_SLOT,
89 PROTECT 89 PROTECT
90 }; 90 };
91 91
92 // MacroAssembler implements a collection of frequently used macros. 92 // MacroAssembler implements a collection of frequently used macros.
93 class MacroAssembler: public Assembler { 93 class MacroAssembler: public Assembler {
94 public: 94 public:
95 MacroAssembler(void* buffer, int size); 95 // The isolate parameter can be NULL if the macro assembler should
96 // not use isolate-dependent functionality. In this case, it's the
97 // responsibility of the caller to never invoke such function on the
98 // macro assembler.
99 MacroAssembler(Isolate* isolate, void* buffer, int size);
96 100
97 // Arguments macros 101 // Arguments macros.
98 #define COND_TYPED_ARGS Condition cond, Register r1, const Operand& r2 102 #define COND_TYPED_ARGS Condition cond, Register r1, const Operand& r2
99 #define COND_ARGS cond, r1, r2 103 #define COND_ARGS cond, r1, r2
100 104
101 // ** Prototypes 105 // Prototypes.
102 106
103 // * Prototypes for functions with no target (eg Ret()). 107 // Prototypes for functions with no target (eg Ret()).
104 #define DECLARE_NOTARGET_PROTOTYPE(Name) \ 108 #define DECLARE_NOTARGET_PROTOTYPE(Name) \
105 void Name(BranchDelaySlot bd = PROTECT); \ 109 void Name(BranchDelaySlot bd = PROTECT); \
106 void Name(COND_TYPED_ARGS, BranchDelaySlot bd = PROTECT); \ 110 void Name(COND_TYPED_ARGS, BranchDelaySlot bd = PROTECT); \
107 inline void Name(BranchDelaySlot bd, COND_TYPED_ARGS) { \ 111 inline void Name(BranchDelaySlot bd, COND_TYPED_ARGS) { \
108 Name(COND_ARGS, bd); \ 112 Name(COND_ARGS, bd); \
109 } 113 }
110 114
111 // * Prototypes for functions with a target. 115 // Prototypes for functions with a target.
112 116
113 // Cases when relocation may be needed. 117 // Cases when relocation may be needed.
114 #define DECLARE_RELOC_PROTOTYPE(Name, target_type) \ 118 #define DECLARE_RELOC_PROTOTYPE(Name, target_type) \
115 void Name(target_type target, \ 119 void Name(target_type target, \
116 RelocInfo::Mode rmode, \ 120 RelocInfo::Mode rmode, \
117 BranchDelaySlot bd = PROTECT); \ 121 BranchDelaySlot bd = PROTECT); \
118 inline void Name(BranchDelaySlot bd, \ 122 inline void Name(BranchDelaySlot bd, \
119 target_type target, \ 123 target_type target, \
120 RelocInfo::Mode rmode) { \ 124 RelocInfo::Mode rmode) { \
121 Name(target, rmode, bd); \ 125 Name(target, rmode, bd); \
(...skipping 17 matching lines...) Expand all
139 } \ 143 } \
140 void Name(target_type target, \ 144 void Name(target_type target, \
141 COND_TYPED_ARGS, \ 145 COND_TYPED_ARGS, \
142 BranchDelaySlot bd = PROTECT); \ 146 BranchDelaySlot bd = PROTECT); \
143 inline void Name(BranchDelaySlot bd, \ 147 inline void Name(BranchDelaySlot bd, \
144 target_type target, \ 148 target_type target, \
145 COND_TYPED_ARGS) { \ 149 COND_TYPED_ARGS) { \
146 Name(target, COND_ARGS, bd); \ 150 Name(target, COND_ARGS, bd); \
147 } 151 }
148 152
149 // ** Target prototypes. 153 // Target prototypes.
150 154
151 #define DECLARE_JUMP_CALL_PROTOTYPES(Name) \ 155 #define DECLARE_JUMP_CALL_PROTOTYPES(Name) \
152 DECLARE_NORELOC_PROTOTYPE(Name, Register) \ 156 DECLARE_NORELOC_PROTOTYPE(Name, Register) \
153 DECLARE_NORELOC_PROTOTYPE(Name, const Operand&) \ 157 DECLARE_NORELOC_PROTOTYPE(Name, const Operand&) \
154 DECLARE_RELOC_PROTOTYPE(Name, byte*) \ 158 DECLARE_RELOC_PROTOTYPE(Name, byte*) \
155 DECLARE_RELOC_PROTOTYPE(Name, Handle<Code>) 159 DECLARE_RELOC_PROTOTYPE(Name, Handle<Code>)
156 160
157 #define DECLARE_BRANCH_PROTOTYPES(Name) \ 161 #define DECLARE_BRANCH_PROTOTYPES(Name) \
158 DECLARE_NORELOC_PROTOTYPE(Name, Label*) \ 162 DECLARE_NORELOC_PROTOTYPE(Name, Label*) \
159 DECLARE_NORELOC_PROTOTYPE(Name, int16_t) 163 DECLARE_NORELOC_PROTOTYPE(Name, int16_t)
160 164
161 165
162 DECLARE_JUMP_CALL_PROTOTYPES(Jump) 166 DECLARE_JUMP_CALL_PROTOTYPES(Jump)
163 DECLARE_JUMP_CALL_PROTOTYPES(Call) 167 DECLARE_JUMP_CALL_PROTOTYPES(Call)
164 168
165 DECLARE_BRANCH_PROTOTYPES(Branch) 169 DECLARE_BRANCH_PROTOTYPES(Branch)
166 DECLARE_BRANCH_PROTOTYPES(BranchAndLink) 170 DECLARE_BRANCH_PROTOTYPES(BranchAndLink)
167 171
168 DECLARE_NOTARGET_PROTOTYPE(Ret) 172 DECLARE_NOTARGET_PROTOTYPE(Ret)
169 173
170 #undef COND_TYPED_ARGS 174 #undef COND_TYPED_ARGS
171 #undef COND_ARGS 175 #undef COND_ARGS
172 #undef DECLARE_NOTARGET_PROTOTYPE 176 #undef DECLARE_NOTARGET_PROTOTYPE
173 #undef DECLARE_NORELOC_PROTOTYPE 177 #undef DECLARE_NORELOC_PROTOTYPE
174 #undef DECLARE_RELOC_PROTOTYPE 178 #undef DECLARE_RELOC_PROTOTYPE
175 #undef DECLARE_JUMP_CALL_PROTOTYPES 179 #undef DECLARE_JUMP_CALL_PROTOTYPES
176 #undef DECLARE_BRANCH_PROTOTYPES 180 #undef DECLARE_BRANCH_PROTOTYPES
177 181
182 void CallWithAstId(Handle<Code> code,
183 RelocInfo::Mode rmode,
184 unsigned ast_id,
185 Condition cond = al,
186 Register r1 = zero_reg,
187 const Operand& r2 = Operand(zero_reg));
188
189 int CallSize(Register reg);
190 int CallSize(Handle<Code> code, RelocInfo::Mode rmode);
191
178 // Emit code to discard a non-negative number of pointer-sized elements 192 // Emit code to discard a non-negative number of pointer-sized elements
179 // from the stack, clobbering only the sp register. 193 // from the stack, clobbering only the sp register.
180 void Drop(int count, 194 void Drop(int count,
181 Condition cond = cc_always, 195 Condition cond = cc_always,
182 Register reg = no_reg, 196 Register reg = no_reg,
183 const Operand& op = Operand(no_reg)); 197 const Operand& op = Operand(no_reg));
184 198
185 void DropAndRet(int drop = 0, 199 void DropAndRet(int drop = 0,
186 Condition cond = cc_always, 200 Condition cond = cc_always,
187 Register reg = no_reg, 201 Register reg = no_reg,
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
249 // [address] dirty. The object address must be in the first 8K of an 263 // [address] dirty. The object address must be in the first 8K of an
250 // allocated page. All 3 registers are clobbered by the operation, 264 // allocated page. All 3 registers are clobbered by the operation,
251 // as well as the ip register. RecordWrite updates the write barrier 265 // as well as the ip register. RecordWrite updates the write barrier
252 // even when storing smis. 266 // even when storing smis.
253 void RecordWrite(Register object, 267 void RecordWrite(Register object,
254 Register address, 268 Register address,
255 Register scratch); 269 Register scratch);
256 270
257 271
258 // --------------------------------------------------------------------------- 272 // ---------------------------------------------------------------------------
259 // Inline caching support 273 // Inline caching support.
260 274
261 // Generate code for checking access rights - used for security checks 275 // Generate code for checking access rights - used for security checks
262 // on access to global objects across environments. The holder register 276 // on access to global objects across environments. The holder register
263 // is left untouched, whereas both scratch registers are clobbered. 277 // is left untouched, whereas both scratch registers are clobbered.
264 void CheckAccessGlobalProxy(Register holder_reg, 278 void CheckAccessGlobalProxy(Register holder_reg,
265 Register scratch, 279 Register scratch,
266 Label* miss); 280 Label* miss);
267 281
268 inline void MarkCode(NopMarkerTypes type) { 282 inline void MarkCode(NopMarkerTypes type) {
269 nop(type); 283 nop(type);
(...skipping 23 matching lines...) Expand all
293 int type = 307 int type =
294 (sllzz && FIRST_IC_MARKER <= sa && sa < LAST_CODE_MARKER) ? sa : -1; 308 (sllzz && FIRST_IC_MARKER <= sa && sa < LAST_CODE_MARKER) ? sa : -1;
295 ASSERT((type == -1) || 309 ASSERT((type == -1) ||
296 ((FIRST_IC_MARKER <= type) && (type < LAST_CODE_MARKER))); 310 ((FIRST_IC_MARKER <= type) && (type < LAST_CODE_MARKER)));
297 return type; 311 return type;
298 } 312 }
299 313
300 314
301 315
302 // --------------------------------------------------------------------------- 316 // ---------------------------------------------------------------------------
303 // Allocation support 317 // Allocation support.
304 318
305 // Allocate an object in new space. The object_size is specified 319 // Allocate an object in new space. The object_size is specified
306 // either in bytes or in words if the allocation flag SIZE_IN_WORDS 320 // either in bytes or in words if the allocation flag SIZE_IN_WORDS
307 // is passed. If the new space is exhausted control continues at the 321 // is passed. If the new space is exhausted control continues at the
308 // gc_required label. The allocated object is returned in result. If 322 // gc_required label. The allocated object is returned in result. If
309 // the flag tag_allocated_object is true the result is tagged as as 323 // the flag tag_allocated_object is true the result is tagged as as
310 // a heap object. All registers are clobbered also when control 324 // a heap object. All registers are clobbered also when control
311 // continues at the gc_required label. 325 // continues at the gc_required label.
312 void AllocateInNewSpace(int object_size, 326 void AllocateInNewSpace(int object_size,
313 Register result, 327 Register result,
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
360 Register scratch2, 374 Register scratch2,
361 Register heap_number_map, 375 Register heap_number_map,
362 Label* gc_required); 376 Label* gc_required);
363 void AllocateHeapNumberWithValue(Register result, 377 void AllocateHeapNumberWithValue(Register result,
364 FPURegister value, 378 FPURegister value,
365 Register scratch1, 379 Register scratch1,
366 Register scratch2, 380 Register scratch2,
367 Label* gc_required); 381 Label* gc_required);
368 382
369 // --------------------------------------------------------------------------- 383 // ---------------------------------------------------------------------------
370 // Instruction macros 384 // Instruction macros.
371 385
372 #define DEFINE_INSTRUCTION(instr) \ 386 #define DEFINE_INSTRUCTION(instr) \
373 void instr(Register rd, Register rs, const Operand& rt); \ 387 void instr(Register rd, Register rs, const Operand& rt); \
374 void instr(Register rd, Register rs, Register rt) { \ 388 void instr(Register rd, Register rs, Register rt) { \
375 instr(rd, rs, Operand(rt)); \ 389 instr(rd, rs, Operand(rt)); \
376 } \ 390 } \
377 void instr(Register rs, Register rt, int32_t j) { \ 391 void instr(Register rs, Register rt, int32_t j) { \
378 instr(rs, rt, Operand(j)); \ 392 instr(rs, rt, Operand(j)); \
379 } 393 }
380 394
(...skipping 11 matching lines...) Expand all
392 DEFINE_INSTRUCTION(Mul); 406 DEFINE_INSTRUCTION(Mul);
393 DEFINE_INSTRUCTION2(Mult); 407 DEFINE_INSTRUCTION2(Mult);
394 DEFINE_INSTRUCTION2(Multu); 408 DEFINE_INSTRUCTION2(Multu);
395 DEFINE_INSTRUCTION2(Div); 409 DEFINE_INSTRUCTION2(Div);
396 DEFINE_INSTRUCTION2(Divu); 410 DEFINE_INSTRUCTION2(Divu);
397 411
398 DEFINE_INSTRUCTION(And); 412 DEFINE_INSTRUCTION(And);
399 DEFINE_INSTRUCTION(Or); 413 DEFINE_INSTRUCTION(Or);
400 DEFINE_INSTRUCTION(Xor); 414 DEFINE_INSTRUCTION(Xor);
401 DEFINE_INSTRUCTION(Nor); 415 DEFINE_INSTRUCTION(Nor);
416 DEFINE_INSTRUCTION2(Neg);
402 417
403 DEFINE_INSTRUCTION(Slt); 418 DEFINE_INSTRUCTION(Slt);
404 DEFINE_INSTRUCTION(Sltu); 419 DEFINE_INSTRUCTION(Sltu);
405 420
406 // MIPS32 R2 instruction macro. 421 // MIPS32 R2 instruction macro.
407 DEFINE_INSTRUCTION(Ror); 422 DEFINE_INSTRUCTION(Ror);
408 423
409 #undef DEFINE_INSTRUCTION 424 #undef DEFINE_INSTRUCTION
410 #undef DEFINE_INSTRUCTION2 425 #undef DEFINE_INSTRUCTION2
411 426
412 427
413 //------------Pseudo-instructions------------- 428 // ---------------------------------------------------------------------------
429 // Pseudo-instructions.
414 430
415 void mov(Register rd, Register rt) { or_(rd, rt, zero_reg); } 431 void mov(Register rd, Register rt) { or_(rd, rt, zero_reg); }
416 432
417 433 // Load int32 in the rd register.
418 // load int32 in the rd register
419 void li(Register rd, Operand j, bool gen2instr = false); 434 void li(Register rd, Operand j, bool gen2instr = false);
420 inline void li(Register rd, int32_t j, bool gen2instr = false) { 435 inline void li(Register rd, int32_t j, bool gen2instr = false) {
421 li(rd, Operand(j), gen2instr); 436 li(rd, Operand(j), gen2instr);
422 } 437 }
423 inline void li(Register dst, Handle<Object> value, bool gen2instr = false) { 438 inline void li(Register dst, Handle<Object> value, bool gen2instr = false) {
424 li(dst, Operand(value), gen2instr); 439 li(dst, Operand(value), gen2instr);
425 } 440 }
426 441
427 // Exception-generating instructions and debugging support 442 // Exception-generating instructions and debugging support.
428 void stop(const char* msg); 443 void stop(const char* msg);
429 444
430
431 // Push multiple registers on the stack. 445 // Push multiple registers on the stack.
432 // Registers are saved in numerical order, with higher numbered registers 446 // Registers are saved in numerical order, with higher numbered registers
433 // saved in higher memory addresses 447 // saved in higher memory addresses.
434 void MultiPush(RegList regs); 448 void MultiPush(RegList regs);
435 void MultiPushReversed(RegList regs); 449 void MultiPushReversed(RegList regs);
436 450
437 void Push(Register src) { 451 // Lower case push() for compatibility with arch-independent code.
452 void push(Register src) {
438 Addu(sp, sp, Operand(-kPointerSize)); 453 Addu(sp, sp, Operand(-kPointerSize));
439 sw(src, MemOperand(sp, 0)); 454 sw(src, MemOperand(sp, 0));
440 } 455 }
441 456
442 // Push two registers. Pushes leftmost register first (to highest address). 457 // Push two registers. Pushes leftmost register first (to highest address).
443 void Push(Register src1, Register src2, Condition cond = al) { 458 void Push(Register src1, Register src2) {
444 ASSERT(cond == al); // Do not support conditional versions yet.
445 Subu(sp, sp, Operand(2 * kPointerSize)); 459 Subu(sp, sp, Operand(2 * kPointerSize));
446 sw(src1, MemOperand(sp, 1 * kPointerSize)); 460 sw(src1, MemOperand(sp, 1 * kPointerSize));
447 sw(src2, MemOperand(sp, 0 * kPointerSize)); 461 sw(src2, MemOperand(sp, 0 * kPointerSize));
448 } 462 }
449 463
450 // Push three registers. Pushes leftmost register first (to highest address). 464 // Push three registers. Pushes leftmost register first (to highest address).
451 void Push(Register src1, Register src2, Register src3, Condition cond = al) { 465 void Push(Register src1, Register src2, Register src3) {
452 ASSERT(cond == al); // Do not support conditional versions yet. 466 Subu(sp, sp, Operand(3 * kPointerSize));
453 Addu(sp, sp, Operand(3 * -kPointerSize));
454 sw(src1, MemOperand(sp, 2 * kPointerSize)); 467 sw(src1, MemOperand(sp, 2 * kPointerSize));
455 sw(src2, MemOperand(sp, 1 * kPointerSize)); 468 sw(src2, MemOperand(sp, 1 * kPointerSize));
456 sw(src3, MemOperand(sp, 0 * kPointerSize)); 469 sw(src3, MemOperand(sp, 0 * kPointerSize));
457 } 470 }
458 471
459 // Push four registers. Pushes leftmost register first (to highest address). 472 // Push four registers. Pushes leftmost register first (to highest address).
460 void Push(Register src1, Register src2, 473 void Push(Register src1, Register src2, Register src3, Register src4) {
461 Register src3, Register src4, Condition cond = al) { 474 Subu(sp, sp, Operand(4 * kPointerSize));
462 ASSERT(cond == al); // Do not support conditional versions yet.
463 Addu(sp, sp, Operand(4 * -kPointerSize));
464 sw(src1, MemOperand(sp, 3 * kPointerSize)); 475 sw(src1, MemOperand(sp, 3 * kPointerSize));
465 sw(src2, MemOperand(sp, 2 * kPointerSize)); 476 sw(src2, MemOperand(sp, 2 * kPointerSize));
466 sw(src3, MemOperand(sp, 1 * kPointerSize)); 477 sw(src3, MemOperand(sp, 1 * kPointerSize));
467 sw(src4, MemOperand(sp, 0 * kPointerSize)); 478 sw(src4, MemOperand(sp, 0 * kPointerSize));
468 } 479 }
469 480
470 inline void push(Register src) { Push(src); }
471 inline void pop(Register src) { Pop(src); }
472
473 void Push(Register src, Condition cond, Register tst1, Register tst2) { 481 void Push(Register src, Condition cond, Register tst1, Register tst2) {
474 // Since we don't have conditionnal execution we use a Branch. 482 // Since we don't have conditional execution we use a Branch.
475 Branch(3, cond, tst1, Operand(tst2)); 483 Branch(3, cond, tst1, Operand(tst2));
476 Addu(sp, sp, Operand(-kPointerSize)); 484 Subu(sp, sp, Operand(kPointerSize));
477 sw(src, MemOperand(sp, 0)); 485 sw(src, MemOperand(sp, 0));
478 } 486 }
479 487
480
481 // Pops multiple values from the stack and load them in the 488 // Pops multiple values from the stack and load them in the
482 // registers specified in regs. Pop order is the opposite as in MultiPush. 489 // registers specified in regs. Pop order is the opposite as in MultiPush.
483 void MultiPop(RegList regs); 490 void MultiPop(RegList regs);
484 void MultiPopReversed(RegList regs); 491 void MultiPopReversed(RegList regs);
485 void Pop(Register dst) { 492
493 // Lower case pop() for compatibility with arch-independent code.
494 void pop(Register dst) {
486 lw(dst, MemOperand(sp, 0)); 495 lw(dst, MemOperand(sp, 0));
487 Addu(sp, sp, Operand(kPointerSize)); 496 Addu(sp, sp, Operand(kPointerSize));
488 } 497 }
498
499 // Pop two registers. Pops rightmost register first (from lower address).
500 void Pop(Register src1, Register src2) {
501 ASSERT(!src1.is(src2));
502 lw(src2, MemOperand(sp, 0 * kPointerSize));
503 lw(src1, MemOperand(sp, 1 * kPointerSize));
504 Addu(sp, sp, 2 * kPointerSize);
505 }
506
489 void Pop(uint32_t count = 1) { 507 void Pop(uint32_t count = 1) {
490 Addu(sp, sp, Operand(count * kPointerSize)); 508 Addu(sp, sp, Operand(count * kPointerSize));
491 } 509 }
492 510
493 // --------------------------------------------------------------------------- 511 // ---------------------------------------------------------------------------
494 // These functions are only used by crankshaft, so they are currently 512 // These functions are only used by crankshaft, so they are currently
495 // unimplemented. 513 // unimplemented.
496 514
497 // Push and pop the registers that can hold pointers, as defined by the 515 // Push and pop the registers that can hold pointers, as defined by the
498 // RegList constant kSafepointSavedRegisters. 516 // RegList constant kSafepointSavedRegisters.
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
535 // dest. If the HeapNumber does not fit into a 32bits signed integer branch 553 // dest. If the HeapNumber does not fit into a 32bits signed integer branch
536 // to not_int32 label. If FPU is available double_scratch is used but not 554 // to not_int32 label. If FPU is available double_scratch is used but not
537 // scratch2. 555 // scratch2.
538 void ConvertToInt32(Register source, 556 void ConvertToInt32(Register source,
539 Register dest, 557 Register dest,
540 Register scratch, 558 Register scratch,
541 Register scratch2, 559 Register scratch2,
542 FPURegister double_scratch, 560 FPURegister double_scratch,
543 Label *not_int32); 561 Label *not_int32);
544 562
563 // Helper for EmitECMATruncate.
564 // This will truncate a floating-point value outside of the singed 32bit
565 // integer range to a 32bit signed integer.
566 // Expects the double value loaded in input_high and input_low.
567 // Exits with the answer in 'result'.
568 // Note that this code does not work for values in the 32bit range!
569 void EmitOutOfInt32RangeTruncate(Register result,
570 Register input_high,
571 Register input_low,
572 Register scratch);
573
545 // ------------------------------------------------------------------------- 574 // -------------------------------------------------------------------------
546 // Activation frames 575 // Activation frames.
547 576
548 void EnterInternalFrame() { EnterFrame(StackFrame::INTERNAL); } 577 void EnterInternalFrame() { EnterFrame(StackFrame::INTERNAL); }
549 void LeaveInternalFrame() { LeaveFrame(StackFrame::INTERNAL); } 578 void LeaveInternalFrame() { LeaveFrame(StackFrame::INTERNAL); }
550 579
551 void EnterConstructFrame() { EnterFrame(StackFrame::CONSTRUCT); } 580 void EnterConstructFrame() { EnterFrame(StackFrame::CONSTRUCT); }
552 void LeaveConstructFrame() { LeaveFrame(StackFrame::CONSTRUCT); } 581 void LeaveConstructFrame() { LeaveFrame(StackFrame::CONSTRUCT); }
553 582
554 // Enter exit frame. 583 // Enter exit frame.
555 // Expects the number of arguments in register a0 and 584 // Expects the number of arguments in register a0 and
556 // the builtin function to call in register a1. 585 // the builtin function to call in register a1.
(...skipping 16 matching lines...) Expand all
573 602
574 void LoadGlobalFunction(int index, Register function); 603 void LoadGlobalFunction(int index, Register function);
575 604
576 // Load the initial map from the global function. The registers 605 // Load the initial map from the global function. The registers
577 // function and map can be the same, function is then overwritten. 606 // function and map can be the same, function is then overwritten.
578 void LoadGlobalFunctionInitialMap(Register function, 607 void LoadGlobalFunctionInitialMap(Register function,
579 Register map, 608 Register map,
580 Register scratch); 609 Register scratch);
581 610
582 // ------------------------------------------------------------------------- 611 // -------------------------------------------------------------------------
583 // JavaScript invokes 612 // JavaScript invokes.
584 613
585 // Invoke the JavaScript function code by either calling or jumping. 614 // Invoke the JavaScript function code by either calling or jumping.
586 void InvokeCode(Register code, 615 void InvokeCode(Register code,
587 const ParameterCount& expected, 616 const ParameterCount& expected,
588 const ParameterCount& actual, 617 const ParameterCount& actual,
589 InvokeFlag flag, 618 InvokeFlag flag,
590 const CallWrapper& call_wrapper = NullCallWrapper()); 619 const CallWrapper& call_wrapper = NullCallWrapper());
591 620
592 void InvokeCode(Handle<Code> code, 621 void InvokeCode(Handle<Code> code,
593 const ParameterCount& expected, 622 const ParameterCount& expected,
(...skipping 21 matching lines...) Expand all
615 void IsInstanceJSObjectType(Register map, 644 void IsInstanceJSObjectType(Register map,
616 Register scratch, 645 Register scratch,
617 Label* fail); 646 Label* fail);
618 647
619 void IsObjectJSStringType(Register object, 648 void IsObjectJSStringType(Register object,
620 Register scratch, 649 Register scratch,
621 Label* fail); 650 Label* fail);
622 651
623 #ifdef ENABLE_DEBUGGER_SUPPORT 652 #ifdef ENABLE_DEBUGGER_SUPPORT
624 // ------------------------------------------------------------------------- 653 // -------------------------------------------------------------------------
625 // Debugger Support 654 // Debugger Support.
626 655
627 void DebugBreak(); 656 void DebugBreak();
628 #endif 657 #endif
629 658
630 659
631 // ------------------------------------------------------------------------- 660 // -------------------------------------------------------------------------
632 // Exception handling 661 // Exception handling.
633 662
634 // Push a new try handler and link into try handler chain. 663 // Push a new try handler and link into try handler chain.
635 // The return address must be passed in register ra. 664 // The return address must be passed in register ra.
636 // Clobber t0, t1, t2. 665 // Clobber t0, t1, t2.
637 void PushTryHandler(CodeLocation try_location, HandlerType type); 666 void PushTryHandler(CodeLocation try_location, HandlerType type);
638 667
639 // Unlink the stack handler on top of the stack from the try handler chain. 668 // Unlink the stack handler on top of the stack from the try handler chain.
640 // Must preserve the result register. 669 // Must preserve the result register.
641 void PopTryHandler(); 670 void PopTryHandler();
642 671
643 // Copies a fixed number of fields of heap objects from src to dst. 672 // Copies a fixed number of fields of heap objects from src to dst.
644 void CopyFields(Register dst, Register src, RegList temps, int field_count); 673 void CopyFields(Register dst, Register src, RegList temps, int field_count);
645 674
675 // Copies a number of bytes from src to dst. All registers are clobbered. On
676 // exit src and dst will point to the place just after where the last byte was
677 // read or written and length will be zero.
678 void CopyBytes(Register src,
679 Register dst,
680 Register length,
681 Register scratch);
682
646 // ------------------------------------------------------------------------- 683 // -------------------------------------------------------------------------
647 // Support functions. 684 // Support functions.
648 685
649 // Try to get function prototype of a function and puts the value in 686 // Try to get function prototype of a function and puts the value in
650 // the result register. Checks that the function really is a 687 // the result register. Checks that the function really is a
651 // function and jumps to the miss label if the fast checks fail. The 688 // function and jumps to the miss label if the fast checks fail. The
652 // function register will be untouched; the other registers may be 689 // function register will be untouched; the other registers may be
653 // clobbered. 690 // clobbered.
654 void TryGetFunctionPrototype(Register function, 691 void TryGetFunctionPrototype(Register function,
655 Register result, 692 Register result,
656 Register scratch, 693 Register scratch,
657 Label* miss); 694 Label* miss);
658 695
659 void GetObjectType(Register function, 696 void GetObjectType(Register function,
660 Register map, 697 Register map,
661 Register type_reg); 698 Register type_reg);
662 699
663 // Check if the map of an object is equal to a specified map (either 700 // Check if the map of an object is equal to a specified map (either
664 // given directly or as an index into the root list) and branch to 701 // given directly or as an index into the root list) and branch to
665 // label if not. Skip the smi check if not required (object is known 702 // label if not. Skip the smi check if not required (object is known
666 // to be a heap object) 703 // to be a heap object).
667 void CheckMap(Register obj, 704 void CheckMap(Register obj,
668 Register scratch, 705 Register scratch,
669 Handle<Map> map, 706 Handle<Map> map,
670 Label* fail, 707 Label* fail,
671 bool is_heap_object); 708 bool is_heap_object);
672 709
673 void CheckMap(Register obj, 710 void CheckMap(Register obj,
674 Register scratch, 711 Register scratch,
675 Heap::RootListIndex index, 712 Heap::RootListIndex index,
676 Label* fail, 713 Label* fail,
677 bool is_heap_object); 714 bool is_heap_object);
678 715
679 // Generates code for reporting that an illegal operation has 716 // Generates code for reporting that an illegal operation has
680 // occurred. 717 // occurred.
681 void IllegalOperation(int num_arguments); 718 void IllegalOperation(int num_arguments);
682 719
683 // Picks out an array index from the hash field. 720 // Picks out an array index from the hash field.
684 // Register use: 721 // Register use:
685 // hash - holds the index's hash. Clobbered. 722 // hash - holds the index's hash. Clobbered.
686 // index - holds the overwritten index on exit. 723 // index - holds the overwritten index on exit.
687 void IndexFromHash(Register hash, Register index); 724 void IndexFromHash(Register hash, Register index);
688 725
726 // Get the number of least significant bits from a register.
727 void GetLeastBitsFromSmi(Register dst, Register src, int num_least_bits);
728 void GetLeastBitsFromInt32(Register dst, Register src, int mun_least_bits);
729
689 // Load the value of a number object into a FPU double register. If the 730 // Load the value of a number object into a FPU double register. If the
690 // object is not a number a jump to the label not_number is performed 731 // object is not a number a jump to the label not_number is performed
691 // and the FPU double register is unchanged. 732 // and the FPU double register is unchanged.
692 void ObjectToDoubleFPURegister( 733 void ObjectToDoubleFPURegister(
693 Register object, 734 Register object,
694 FPURegister value, 735 FPURegister value,
695 Register scratch1, 736 Register scratch1,
696 Register scratch2, 737 Register scratch2,
697 Register heap_number_map, 738 Register heap_number_map,
698 Label* not_number, 739 Label* not_number,
699 ObjectToDoubleFlags flags = NO_OBJECT_TO_DOUBLE_FLAGS); 740 ObjectToDoubleFlags flags = NO_OBJECT_TO_DOUBLE_FLAGS);
700 741
701 // Load the value of a smi object into a FPU double register. The register 742 // Load the value of a smi object into a FPU double register. The register
702 // scratch1 can be the same register as smi in which case smi will hold the 743 // scratch1 can be the same register as smi in which case smi will hold the
703 // untagged value afterwards. 744 // untagged value afterwards.
704 void SmiToDoubleFPURegister(Register smi, 745 void SmiToDoubleFPURegister(Register smi,
705 FPURegister value, 746 FPURegister value,
706 Register scratch1); 747 Register scratch1);
707 748
708 // ------------------------------------------------------------------------- 749 // -------------------------------------------------------------------------
709 // Runtime calls 750 // Overflow handling functions.
751 // Usage: first call the appropriate arithmetic function, then call one of the
752 // jump functions with the overflow_dst register as the second parameter.
753
754 void AdduAndCheckForOverflow(Register dst,
755 Register left,
756 Register right,
757 Register overflow_dst,
758 Register scratch = at);
759
760 void SubuAndCheckForOverflow(Register dst,
761 Register left,
762 Register right,
763 Register overflow_dst,
764 Register scratch = at);
765
766 void BranchOnOverflow(Label* label,
767 Register overflow_check,
768 BranchDelaySlot bd = PROTECT) {
769 Branch(label, lt, overflow_check, Operand(zero_reg), bd);
770 }
771
772 void BranchOnNoOverflow(Label* label,
773 Register overflow_check,
774 BranchDelaySlot bd = PROTECT) {
775 Branch(label, ge, overflow_check, Operand(zero_reg), bd);
776 }
777
778 void RetOnOverflow(Register overflow_check, BranchDelaySlot bd = PROTECT) {
779 Ret(lt, overflow_check, Operand(zero_reg), bd);
780 }
781
782 void RetOnNoOverflow(Register overflow_check, BranchDelaySlot bd = PROTECT) {
783 Ret(ge, overflow_check, Operand(zero_reg), bd);
784 }
785
786 // -------------------------------------------------------------------------
787 // Runtime calls.
710 788
711 // Call a code stub. 789 // Call a code stub.
712 void CallStub(CodeStub* stub, Condition cond = cc_always, 790 void CallStub(CodeStub* stub, Condition cond = cc_always,
713 Register r1 = zero_reg, const Operand& r2 = Operand(zero_reg)); 791 Register r1 = zero_reg, const Operand& r2 = Operand(zero_reg));
714 792
715 // Tail call a code stub (jump). 793 // Tail call a code stub (jump).
716 void TailCallStub(CodeStub* stub); 794 void TailCallStub(CodeStub* stub);
717 795
718 void CallJSExitStub(CodeStub* stub); 796 void CallJSExitStub(CodeStub* stub);
719 797
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
756 // sw(t0, CFunctionArgumentOperand(5)); 834 // sw(t0, CFunctionArgumentOperand(5));
757 835
758 // Calls a C function and cleans up the space for arguments allocated 836 // Calls a C function and cleans up the space for arguments allocated
759 // by PrepareCallCFunction. The called function is not allowed to trigger a 837 // by PrepareCallCFunction. The called function is not allowed to trigger a
760 // garbage collection, since that might move the code and invalidate the 838 // garbage collection, since that might move the code and invalidate the
761 // return address (unless this is somehow accounted for by the called 839 // return address (unless this is somehow accounted for by the called
762 // function). 840 // function).
763 void CallCFunction(ExternalReference function, int num_arguments); 841 void CallCFunction(ExternalReference function, int num_arguments);
764 void CallCFunction(Register function, Register scratch, int num_arguments); 842 void CallCFunction(Register function, Register scratch, int num_arguments);
765 843
844 void GetCFunctionDoubleResult(const DoubleRegister dst);
845
766 // Jump to the builtin routine. 846 // Jump to the builtin routine.
767 void JumpToExternalReference(const ExternalReference& builtin); 847 void JumpToExternalReference(const ExternalReference& builtin);
768 848
769 // Invoke specified builtin JavaScript function. Adds an entry to 849 // Invoke specified builtin JavaScript function. Adds an entry to
770 // the unresolved list if the name does not resolve. 850 // the unresolved list if the name does not resolve.
771 void InvokeBuiltin(Builtins::JavaScript id, 851 void InvokeBuiltin(Builtins::JavaScript id,
772 InvokeFlag flag, 852 InvokeFlag flag,
773 const CallWrapper& call_wrapper = NullCallWrapper()); 853 const CallWrapper& call_wrapper = NullCallWrapper());
774 854
775 // Store the code object for the given builtin in the target register and 855 // Store the code object for the given builtin in the target register and
776 // setup the function in a1. 856 // setup the function in a1.
777 void GetBuiltinEntry(Register target, Builtins::JavaScript id); 857 void GetBuiltinEntry(Register target, Builtins::JavaScript id);
778 858
779 // Store the function for the given builtin in the target register. 859 // Store the function for the given builtin in the target register.
780 void GetBuiltinFunction(Register target, Builtins::JavaScript id); 860 void GetBuiltinFunction(Register target, Builtins::JavaScript id);
781 861
782 struct Unresolved { 862 struct Unresolved {
783 int pc; 863 int pc;
784 uint32_t flags; // see Bootstrapper::FixupFlags decoders/encoders. 864 uint32_t flags; // See Bootstrapper::FixupFlags decoders/encoders.
785 const char* name; 865 const char* name;
786 }; 866 };
787 867
788 Handle<Object> CodeObject() { return code_object_; } 868 Handle<Object> CodeObject() {
869 ASSERT(!code_object_.is_null());
870 return code_object_;
871 }
789 872
790 // ------------------------------------------------------------------------- 873 // -------------------------------------------------------------------------
791 // StatsCounter support 874 // StatsCounter support.
792 875
793 void SetCounter(StatsCounter* counter, int value, 876 void SetCounter(StatsCounter* counter, int value,
794 Register scratch1, Register scratch2); 877 Register scratch1, Register scratch2);
795 void IncrementCounter(StatsCounter* counter, int value, 878 void IncrementCounter(StatsCounter* counter, int value,
796 Register scratch1, Register scratch2); 879 Register scratch1, Register scratch2);
797 void DecrementCounter(StatsCounter* counter, int value, 880 void DecrementCounter(StatsCounter* counter, int value,
798 Register scratch1, Register scratch2); 881 Register scratch1, Register scratch2);
799 882
800 883
801 // ------------------------------------------------------------------------- 884 // -------------------------------------------------------------------------
802 // Debugging 885 // Debugging.
803 886
804 // Calls Abort(msg) if the condition cc is not satisfied. 887 // Calls Abort(msg) if the condition cc is not satisfied.
805 // Use --debug_code to enable. 888 // Use --debug_code to enable.
806 void Assert(Condition cc, const char* msg, Register rs, Operand rt); 889 void Assert(Condition cc, const char* msg, Register rs, Operand rt);
807 void AssertRegisterIsRoot(Register reg, Heap::RootListIndex index); 890 void AssertRegisterIsRoot(Register reg, Heap::RootListIndex index);
808 void AssertFastElements(Register elements); 891 void AssertFastElements(Register elements);
809 892
810 // Like Assert(), but always enabled. 893 // Like Assert(), but always enabled.
811 void Check(Condition cc, const char* msg, Register rs, Operand rt); 894 void Check(Condition cc, const char* msg, Register rs, Operand rt);
812 895
813 // Print a message to stdout and abort execution. 896 // Print a message to stdout and abort execution.
814 void Abort(const char* msg); 897 void Abort(const char* msg);
815 898
816 // Verify restrictions about code generated in stubs. 899 // Verify restrictions about code generated in stubs.
817 void set_generating_stub(bool value) { generating_stub_ = value; } 900 void set_generating_stub(bool value) { generating_stub_ = value; }
818 bool generating_stub() { return generating_stub_; } 901 bool generating_stub() { return generating_stub_; }
819 void set_allow_stub_calls(bool value) { allow_stub_calls_ = value; } 902 void set_allow_stub_calls(bool value) { allow_stub_calls_ = value; }
820 bool allow_stub_calls() { return allow_stub_calls_; } 903 bool allow_stub_calls() { return allow_stub_calls_; }
821 904
822 // --------------------------------------------------------------------------- 905 // ---------------------------------------------------------------------------
823 // Number utilities 906 // Number utilities.
824 907
825 // Check whether the value of reg is a power of two and not zero. If not 908 // Check whether the value of reg is a power of two and not zero. If not
826 // control continues at the label not_power_of_two. If reg is a power of two 909 // control continues at the label not_power_of_two. If reg is a power of two
827 // the register scratch contains the value of (reg - 1) when control falls 910 // the register scratch contains the value of (reg - 1) when control falls
828 // through. 911 // through.
829 void JumpIfNotPowerOfTwoOrZero(Register reg, 912 void JumpIfNotPowerOfTwoOrZero(Register reg,
830 Register scratch, 913 Register scratch,
831 Label* not_power_of_two_or_zero); 914 Label* not_power_of_two_or_zero);
832 915
833 // ------------------------------------------------------------------------- 916 // -------------------------------------------------------------------------
834 // Smi utilities 917 // Smi utilities.
835 918
836 // Try to convert int32 to smi. If the value is to large, preserve 919 // Try to convert int32 to smi. If the value is to large, preserve
837 // the original value and jump to not_a_smi. Destroys scratch and 920 // the original value and jump to not_a_smi. Destroys scratch and
838 // sets flags. 921 // sets flags.
839 // This is only used by crankshaft atm so it is unimplemented on MIPS. 922 // This is only used by crankshaft atm so it is unimplemented on MIPS.
840 void TrySmiTag(Register reg, Label* not_a_smi, Register scratch) { 923 void TrySmiTag(Register reg, Label* not_a_smi, Register scratch) {
841 UNIMPLEMENTED_MIPS(); 924 UNIMPLEMENTED_MIPS();
842 } 925 }
843 926
844 void SmiTag(Register reg) { 927 void SmiTag(Register reg) {
(...skipping 30 matching lines...) Expand all
875 958
876 // Jump if either of the registers contain a non-smi. 959 // Jump if either of the registers contain a non-smi.
877 void JumpIfNotBothSmi(Register reg1, Register reg2, Label* on_not_both_smi); 960 void JumpIfNotBothSmi(Register reg1, Register reg2, Label* on_not_both_smi);
878 // Jump if either of the registers contain a smi. 961 // Jump if either of the registers contain a smi.
879 void JumpIfEitherSmi(Register reg1, Register reg2, Label* on_either_smi); 962 void JumpIfEitherSmi(Register reg1, Register reg2, Label* on_either_smi);
880 963
881 // Abort execution if argument is a smi. Used in debug code. 964 // Abort execution if argument is a smi. Used in debug code.
882 void AbortIfSmi(Register object); 965 void AbortIfSmi(Register object);
883 void AbortIfNotSmi(Register object); 966 void AbortIfNotSmi(Register object);
884 967
968 // Abort execution if argument is a string. Used in debug code.
969 void AbortIfNotString(Register object);
970
885 // Abort execution if argument is not the root value with the given index. 971 // Abort execution if argument is not the root value with the given index.
886 void AbortIfNotRootValue(Register src, 972 void AbortIfNotRootValue(Register src,
887 Heap::RootListIndex root_value_index, 973 Heap::RootListIndex root_value_index,
888 const char* message); 974 const char* message);
889 975
890 // --------------------------------------------------------------------------- 976 // ---------------------------------------------------------------------------
891 // HeapNumber utilities 977 // HeapNumber utilities.
892 978
893 void JumpIfNotHeapNumber(Register object, 979 void JumpIfNotHeapNumber(Register object,
894 Register heap_number_map, 980 Register heap_number_map,
895 Register scratch, 981 Register scratch,
896 Label* on_not_heap_number); 982 Label* on_not_heap_number);
897 983
898 // ------------------------------------------------------------------------- 984 // -------------------------------------------------------------------------
899 // String utilities 985 // String utilities.
900 986
901 // Checks if both instance types are sequential ASCII strings and jumps to 987 // Checks if both instance types are sequential ASCII strings and jumps to
902 // label if either is not. 988 // label if either is not.
903 void JumpIfBothInstanceTypesAreNotSequentialAscii( 989 void JumpIfBothInstanceTypesAreNotSequentialAscii(
904 Register first_object_instance_type, 990 Register first_object_instance_type,
905 Register second_object_instance_type, 991 Register second_object_instance_type,
906 Register scratch1, 992 Register scratch1,
907 Register scratch2, 993 Register scratch2,
908 Label* failure); 994 Label* failure);
909 995
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
970 Register scratch2); 1056 Register scratch2);
971 1057
972 1058
973 bool generating_stub_; 1059 bool generating_stub_;
974 bool allow_stub_calls_; 1060 bool allow_stub_calls_;
975 // This handle will be patched with the code object on installation. 1061 // This handle will be patched with the code object on installation.
976 Handle<Object> code_object_; 1062 Handle<Object> code_object_;
977 }; 1063 };
978 1064
979 1065
980 #ifdef ENABLE_DEBUGGER_SUPPORT
981 // The code patcher is used to patch (typically) small parts of code e.g. for 1066 // The code patcher is used to patch (typically) small parts of code e.g. for
982 // debugging and other types of instrumentation. When using the code patcher 1067 // debugging and other types of instrumentation. When using the code patcher
983 // the exact number of bytes specified must be emitted. It is not legal to emit 1068 // the exact number of bytes specified must be emitted. It is not legal to emit
984 // relocation information. If any of these constraints are violated it causes 1069 // relocation information. If any of these constraints are violated it causes
985 // an assertion to fail. 1070 // an assertion to fail.
986 class CodePatcher { 1071 class CodePatcher {
987 public: 1072 public:
988 CodePatcher(byte* address, int instructions); 1073 CodePatcher(byte* address, int instructions);
989 virtual ~CodePatcher(); 1074 virtual ~CodePatcher();
990 1075
991 // Macro assembler to emit code. 1076 // Macro assembler to emit code.
992 MacroAssembler* masm() { return &masm_; } 1077 MacroAssembler* masm() { return &masm_; }
993 1078
994 // Emit an instruction directly. 1079 // Emit an instruction directly.
995 void Emit(Instr x); 1080 void Emit(Instr instr);
996 1081
997 // Emit an address directly. 1082 // Emit an address directly.
998 void Emit(Address addr); 1083 void Emit(Address addr);
999 1084
1085 // Change the condition part of an instruction leaving the rest of the current
1086 // instruction unchanged.
1087 void ChangeBranchCondition(Condition cond);
1088
1000 private: 1089 private:
1001 byte* address_; // The address of the code being patched. 1090 byte* address_; // The address of the code being patched.
1002 int instructions_; // Number of instructions of the expected patch size. 1091 int instructions_; // Number of instructions of the expected patch size.
1003 int size_; // Number of bytes of the expected patch size. 1092 int size_; // Number of bytes of the expected patch size.
1004 MacroAssembler masm_; // Macro assembler used to generate the code. 1093 MacroAssembler masm_; // Macro assembler used to generate the code.
1005 }; 1094 };
1006 #endif // ENABLE_DEBUGGER_SUPPORT
1007 1095
1008 1096
1009 // ----------------------------------------------------------------------------- 1097 // -----------------------------------------------------------------------------
1010 // Static helper functions. 1098 // Static helper functions.
1011 1099
1012 static MemOperand ContextOperand(Register context, int index) { 1100 static MemOperand ContextOperand(Register context, int index) {
1013 return MemOperand(context, Context::SlotOffset(index)); 1101 return MemOperand(context, Context::SlotOffset(index));
1014 } 1102 }
1015 1103
1016 1104
1017 static inline MemOperand GlobalObjectOperand() { 1105 static inline MemOperand GlobalObjectOperand() {
1018 return ContextOperand(cp, Context::GLOBAL_INDEX); 1106 return ContextOperand(cp, Context::GLOBAL_INDEX);
1019 } 1107 }
1020 1108
1021 1109
1022 // Generate a MemOperand for loading a field from an object. 1110 // Generate a MemOperand for loading a field from an object.
1023 static inline MemOperand FieldMemOperand(Register object, int offset) { 1111 static inline MemOperand FieldMemOperand(Register object, int offset) {
1024 return MemOperand(object, offset - kHeapObjectTag); 1112 return MemOperand(object, offset - kHeapObjectTag);
1025 } 1113 }
1026 1114
1027 1115
1116 // Generate a MemOperand for storing arguments 5..N on the stack
1117 // when calling CallCFunction().
1118 static inline MemOperand CFunctionArgumentOperand(int index) {
1119 ASSERT(index > StandardFrameConstants::kCArgSlotCount);
1120 // Argument 5 takes the slot just past the four Arg-slots.
1121 int offset =
1122 (index - 5) * kPointerSize + StandardFrameConstants::kCArgsSlotsSize;
1123 return MemOperand(sp, offset);
1124 }
1125
1028 1126
1029 #ifdef GENERATED_CODE_COVERAGE 1127 #ifdef GENERATED_CODE_COVERAGE
1030 #define CODE_COVERAGE_STRINGIFY(x) #x 1128 #define CODE_COVERAGE_STRINGIFY(x) #x
1031 #define CODE_COVERAGE_TOSTRING(x) CODE_COVERAGE_STRINGIFY(x) 1129 #define CODE_COVERAGE_TOSTRING(x) CODE_COVERAGE_STRINGIFY(x)
1032 #define __FILE_LINE__ __FILE__ ":" CODE_COVERAGE_TOSTRING(__LINE__) 1130 #define __FILE_LINE__ __FILE__ ":" CODE_COVERAGE_TOSTRING(__LINE__)
1033 #define ACCESS_MASM(masm) masm->stop(__FILE_LINE__); masm-> 1131 #define ACCESS_MASM(masm) masm->stop(__FILE_LINE__); masm->
1034 #else 1132 #else
1035 #define ACCESS_MASM(masm) masm-> 1133 #define ACCESS_MASM(masm) masm->
1036 #endif 1134 #endif
1037 1135
1038 } } // namespace v8::internal 1136 } } // namespace v8::internal
1039 1137
1040 #endif // V8_MIPS_MACRO_ASSEMBLER_MIPS_H_ 1138 #endif // V8_MIPS_MACRO_ASSEMBLER_MIPS_H_
1041 1139
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698