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

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

Issue 7060010: Merge bleeding edge into the GC branch up to 7948. The asserts (Closed) Base URL: http://v8.googlecode.com/svn/branches/experimental/gc/
Patch Set: 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 | Annotate | Revision Log
« no previous file with comments | « src/mips/lithium-mips.h ('k') | src/mips/macro-assembler-mips.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 // argc - argument count to be dropped by LeaveExitFrame.
556 // the builtin function to call in register a1. 585 // save_doubles - saves FPU registers on stack, currently disabled.
557 // On output hold_argc, hold_function, and hold_argv are setup. 586 // stack_space - extra stack space.
558 void EnterExitFrame(Register hold_argc, 587 void EnterExitFrame(bool save_doubles,
559 Register hold_argv, 588 int stack_space = 0);
560 Register hold_function,
561 bool save_doubles);
562 589
563 // Leave the current exit frame. Expects the return value in v0. 590 // Leave the current exit frame.
564 void LeaveExitFrame(bool save_doubles); 591 void LeaveExitFrame(bool save_doubles, Register arg_count);
565
566 // Align the stack by optionally pushing a Smi zero.
567 void AlignStack(int offset); // TODO(mips) : remove this function.
568 592
569 // Get the actual activation frame alignment for target environment. 593 // Get the actual activation frame alignment for target environment.
570 static int ActivationFrameAlignment(); 594 static int ActivationFrameAlignment();
571 595
596 // Make sure the stack is aligned. Only emits code in debug mode.
597 void AssertStackIsAligned();
598
572 void LoadContext(Register dst, int context_chain_length); 599 void LoadContext(Register dst, int context_chain_length);
573 600
574 void LoadGlobalFunction(int index, Register function); 601 void LoadGlobalFunction(int index, Register function);
575 602
576 // Load the initial map from the global function. The registers 603 // Load the initial map from the global function. The registers
577 // function and map can be the same, function is then overwritten. 604 // function and map can be the same, function is then overwritten.
578 void LoadGlobalFunctionInitialMap(Register function, 605 void LoadGlobalFunctionInitialMap(Register function,
579 Register map, 606 Register map,
580 Register scratch); 607 Register scratch);
581 608
582 // ------------------------------------------------------------------------- 609 // -------------------------------------------------------------------------
583 // JavaScript invokes 610 // JavaScript invokes.
584 611
585 // Invoke the JavaScript function code by either calling or jumping. 612 // Invoke the JavaScript function code by either calling or jumping.
586 void InvokeCode(Register code, 613 void InvokeCode(Register code,
587 const ParameterCount& expected, 614 const ParameterCount& expected,
588 const ParameterCount& actual, 615 const ParameterCount& actual,
589 InvokeFlag flag, 616 InvokeFlag flag,
590 const CallWrapper& call_wrapper = NullCallWrapper()); 617 const CallWrapper& call_wrapper = NullCallWrapper());
591 618
592 void InvokeCode(Handle<Code> code, 619 void InvokeCode(Handle<Code> code,
593 const ParameterCount& expected, 620 const ParameterCount& expected,
(...skipping 21 matching lines...) Expand all
615 void IsInstanceJSObjectType(Register map, 642 void IsInstanceJSObjectType(Register map,
616 Register scratch, 643 Register scratch,
617 Label* fail); 644 Label* fail);
618 645
619 void IsObjectJSStringType(Register object, 646 void IsObjectJSStringType(Register object,
620 Register scratch, 647 Register scratch,
621 Label* fail); 648 Label* fail);
622 649
623 #ifdef ENABLE_DEBUGGER_SUPPORT 650 #ifdef ENABLE_DEBUGGER_SUPPORT
624 // ------------------------------------------------------------------------- 651 // -------------------------------------------------------------------------
625 // Debugger Support 652 // Debugger Support.
626 653
627 void DebugBreak(); 654 void DebugBreak();
628 #endif 655 #endif
629 656
630 657
631 // ------------------------------------------------------------------------- 658 // -------------------------------------------------------------------------
632 // Exception handling 659 // Exception handling.
633 660
634 // Push a new try handler and link into try handler chain. 661 // Push a new try handler and link into try handler chain.
635 // The return address must be passed in register ra. 662 // The return address must be passed in register ra.
636 // Clobber t0, t1, t2. 663 // Clobber t0, t1, t2.
637 void PushTryHandler(CodeLocation try_location, HandlerType type); 664 void PushTryHandler(CodeLocation try_location, HandlerType type);
638 665
639 // Unlink the stack handler on top of the stack from the try handler chain. 666 // Unlink the stack handler on top of the stack from the try handler chain.
640 // Must preserve the result register. 667 // Must preserve the result register.
641 void PopTryHandler(); 668 void PopTryHandler();
642 669
670 // Passes thrown value (in v0) to the handler of top of the try handler chain.
671 void Throw(Register value);
672
673 // Propagates an uncatchable exception to the top of the current JS stack's
674 // handler chain.
675 void ThrowUncatchable(UncatchableExceptionType type, Register value);
676
643 // Copies a fixed number of fields of heap objects from src to dst. 677 // 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); 678 void CopyFields(Register dst, Register src, RegList temps, int field_count);
645 679
680 // Copies a number of bytes from src to dst. All registers are clobbered. On
681 // exit src and dst will point to the place just after where the last byte was
682 // read or written and length will be zero.
683 void CopyBytes(Register src,
684 Register dst,
685 Register length,
686 Register scratch);
687
646 // ------------------------------------------------------------------------- 688 // -------------------------------------------------------------------------
647 // Support functions. 689 // Support functions.
648 690
649 // Try to get function prototype of a function and puts the value in 691 // Try to get function prototype of a function and puts the value in
650 // the result register. Checks that the function really is a 692 // the result register. Checks that the function really is a
651 // function and jumps to the miss label if the fast checks fail. The 693 // function and jumps to the miss label if the fast checks fail. The
652 // function register will be untouched; the other registers may be 694 // function register will be untouched; the other registers may be
653 // clobbered. 695 // clobbered.
654 void TryGetFunctionPrototype(Register function, 696 void TryGetFunctionPrototype(Register function,
655 Register result, 697 Register result,
656 Register scratch, 698 Register scratch,
657 Label* miss); 699 Label* miss);
658 700
659 void GetObjectType(Register function, 701 void GetObjectType(Register function,
660 Register map, 702 Register map,
661 Register type_reg); 703 Register type_reg);
662 704
663 // Check if the map of an object is equal to a specified map (either 705 // 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 706 // 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 707 // label if not. Skip the smi check if not required (object is known
666 // to be a heap object) 708 // to be a heap object).
667 void CheckMap(Register obj, 709 void CheckMap(Register obj,
668 Register scratch, 710 Register scratch,
669 Handle<Map> map, 711 Handle<Map> map,
670 Label* fail, 712 Label* fail,
671 bool is_heap_object); 713 bool is_heap_object);
672 714
673 void CheckMap(Register obj, 715 void CheckMap(Register obj,
674 Register scratch, 716 Register scratch,
675 Heap::RootListIndex index, 717 Heap::RootListIndex index,
676 Label* fail, 718 Label* fail,
677 bool is_heap_object); 719 bool is_heap_object);
678 720
679 // Generates code for reporting that an illegal operation has 721 // Generates code for reporting that an illegal operation has
680 // occurred. 722 // occurred.
681 void IllegalOperation(int num_arguments); 723 void IllegalOperation(int num_arguments);
682 724
683 // Picks out an array index from the hash field. 725 // Picks out an array index from the hash field.
684 // Register use: 726 // Register use:
685 // hash - holds the index's hash. Clobbered. 727 // hash - holds the index's hash. Clobbered.
686 // index - holds the overwritten index on exit. 728 // index - holds the overwritten index on exit.
687 void IndexFromHash(Register hash, Register index); 729 void IndexFromHash(Register hash, Register index);
688 730
731 // Get the number of least significant bits from a register.
732 void GetLeastBitsFromSmi(Register dst, Register src, int num_least_bits);
733 void GetLeastBitsFromInt32(Register dst, Register src, int mun_least_bits);
734
689 // Load the value of a number object into a FPU double register. If the 735 // 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 736 // object is not a number a jump to the label not_number is performed
691 // and the FPU double register is unchanged. 737 // and the FPU double register is unchanged.
692 void ObjectToDoubleFPURegister( 738 void ObjectToDoubleFPURegister(
693 Register object, 739 Register object,
694 FPURegister value, 740 FPURegister value,
695 Register scratch1, 741 Register scratch1,
696 Register scratch2, 742 Register scratch2,
697 Register heap_number_map, 743 Register heap_number_map,
698 Label* not_number, 744 Label* not_number,
699 ObjectToDoubleFlags flags = NO_OBJECT_TO_DOUBLE_FLAGS); 745 ObjectToDoubleFlags flags = NO_OBJECT_TO_DOUBLE_FLAGS);
700 746
701 // Load the value of a smi object into a FPU double register. The register 747 // 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 748 // scratch1 can be the same register as smi in which case smi will hold the
703 // untagged value afterwards. 749 // untagged value afterwards.
704 void SmiToDoubleFPURegister(Register smi, 750 void SmiToDoubleFPURegister(Register smi,
705 FPURegister value, 751 FPURegister value,
706 Register scratch1); 752 Register scratch1);
707 753
708 // ------------------------------------------------------------------------- 754 // -------------------------------------------------------------------------
709 // Runtime calls 755 // Overflow handling functions.
756 // Usage: first call the appropriate arithmetic function, then call one of the
757 // jump functions with the overflow_dst register as the second parameter.
758
759 void AdduAndCheckForOverflow(Register dst,
760 Register left,
761 Register right,
762 Register overflow_dst,
763 Register scratch = at);
764
765 void SubuAndCheckForOverflow(Register dst,
766 Register left,
767 Register right,
768 Register overflow_dst,
769 Register scratch = at);
770
771 void BranchOnOverflow(Label* label,
772 Register overflow_check,
773 BranchDelaySlot bd = PROTECT) {
774 Branch(label, lt, overflow_check, Operand(zero_reg), bd);
775 }
776
777 void BranchOnNoOverflow(Label* label,
778 Register overflow_check,
779 BranchDelaySlot bd = PROTECT) {
780 Branch(label, ge, overflow_check, Operand(zero_reg), bd);
781 }
782
783 void RetOnOverflow(Register overflow_check, BranchDelaySlot bd = PROTECT) {
784 Ret(lt, overflow_check, Operand(zero_reg), bd);
785 }
786
787 void RetOnNoOverflow(Register overflow_check, BranchDelaySlot bd = PROTECT) {
788 Ret(ge, overflow_check, Operand(zero_reg), bd);
789 }
790
791 // -------------------------------------------------------------------------
792 // Runtime calls.
710 793
711 // Call a code stub. 794 // Call a code stub.
712 void CallStub(CodeStub* stub, Condition cond = cc_always, 795 void CallStub(CodeStub* stub, Condition cond = cc_always,
713 Register r1 = zero_reg, const Operand& r2 = Operand(zero_reg)); 796 Register r1 = zero_reg, const Operand& r2 = Operand(zero_reg));
714 797
798 // Call a code stub and return the code object called. Try to generate
799 // the code if necessary. Do not perform a GC but instead return a retry
800 // after GC failure.
801 MUST_USE_RESULT MaybeObject* TryCallStub(CodeStub* stub,
802 Condition cond = cc_always,
803 Register r1 = zero_reg,
804 const Operand& r2 =
805 Operand(zero_reg));
806
715 // Tail call a code stub (jump). 807 // Tail call a code stub (jump).
716 void TailCallStub(CodeStub* stub); 808 void TailCallStub(CodeStub* stub);
717 809
810 // Tail call a code stub (jump) and return the code object called. Try to
811 // generate the code if necessary. Do not perform a GC but instead return
812 // a retry after GC failure.
813 MUST_USE_RESULT MaybeObject* TryTailCallStub(CodeStub* stub,
814 Condition cond = cc_always,
815 Register r1 = zero_reg,
816 const Operand& r2 =
817 Operand(zero_reg));
818
718 void CallJSExitStub(CodeStub* stub); 819 void CallJSExitStub(CodeStub* stub);
719 820
720 // Call a runtime routine. 821 // Call a runtime routine.
721 void CallRuntime(const Runtime::Function* f, int num_arguments); 822 void CallRuntime(const Runtime::Function* f, int num_arguments);
722 void CallRuntimeSaveDoubles(Runtime::FunctionId id); 823 void CallRuntimeSaveDoubles(Runtime::FunctionId id);
723 824
724 // Convenience function: Same as above, but takes the fid instead. 825 // Convenience function: Same as above, but takes the fid instead.
725 void CallRuntime(Runtime::FunctionId fid, int num_arguments); 826 void CallRuntime(Runtime::FunctionId fid, int num_arguments);
726 827
727 // Convenience function: call an external reference. 828 // Convenience function: call an external reference.
728 void CallExternalReference(const ExternalReference& ext, 829 void CallExternalReference(const ExternalReference& ext,
729 int num_arguments); 830 int num_arguments);
730 831
731 // Tail call of a runtime routine (jump). 832 // Tail call of a runtime routine (jump).
732 // Like JumpToExternalReference, but also takes care of passing the number 833 // Like JumpToExternalReference, but also takes care of passing the number
733 // of parameters. 834 // of parameters.
734 void TailCallExternalReference(const ExternalReference& ext, 835 void TailCallExternalReference(const ExternalReference& ext,
735 int num_arguments, 836 int num_arguments,
736 int result_size); 837 int result_size);
737 838
839 // Tail call of a runtime routine (jump). Try to generate the code if
840 // necessary. Do not perform a GC but instead return a retry after GC
841 // failure.
842 MUST_USE_RESULT MaybeObject* TryTailCallExternalReference(
843 const ExternalReference& ext, int num_arguments, int result_size);
844
738 // Convenience function: tail call a runtime routine (jump). 845 // Convenience function: tail call a runtime routine (jump).
739 void TailCallRuntime(Runtime::FunctionId fid, 846 void TailCallRuntime(Runtime::FunctionId fid,
740 int num_arguments, 847 int num_arguments,
741 int result_size); 848 int result_size);
742 849
743 // Before calling a C-function from generated code, align arguments on stack 850 // Before calling a C-function from generated code, align arguments on stack
744 // and add space for the four mips argument slots. 851 // and add space for the four mips argument slots.
745 // After aligning the frame, non-register arguments must be stored on the 852 // After aligning the frame, non-register arguments must be stored on the
746 // stack, after the argument-slots using helper: CFunctionArgumentOperand(). 853 // stack, after the argument-slots using helper: CFunctionArgumentOperand().
747 // The argument count assumes all arguments are word sized. 854 // The argument count assumes all arguments are word sized.
748 // Some compilers/platforms require the stack to be aligned when calling 855 // Some compilers/platforms require the stack to be aligned when calling
749 // C++ code. 856 // C++ code.
750 // Needs a scratch register to do some arithmetic. This register will be 857 // Needs a scratch register to do some arithmetic. This register will be
751 // trashed. 858 // trashed.
752 void PrepareCallCFunction(int num_arguments, Register scratch); 859 void PrepareCallCFunction(int num_arguments, Register scratch);
753 860
754 // Arguments 1-4 are placed in registers a0 thru a3 respectively. 861 // Arguments 1-4 are placed in registers a0 thru a3 respectively.
755 // Arguments 5..n are stored to stack using following: 862 // Arguments 5..n are stored to stack using following:
756 // sw(t0, CFunctionArgumentOperand(5)); 863 // sw(t0, CFunctionArgumentOperand(5));
757 864
758 // Calls a C function and cleans up the space for arguments allocated 865 // Calls a C function and cleans up the space for arguments allocated
759 // by PrepareCallCFunction. The called function is not allowed to trigger a 866 // by PrepareCallCFunction. The called function is not allowed to trigger a
760 // garbage collection, since that might move the code and invalidate the 867 // garbage collection, since that might move the code and invalidate the
761 // return address (unless this is somehow accounted for by the called 868 // return address (unless this is somehow accounted for by the called
762 // function). 869 // function).
763 void CallCFunction(ExternalReference function, int num_arguments); 870 void CallCFunction(ExternalReference function, int num_arguments);
764 void CallCFunction(Register function, Register scratch, int num_arguments); 871 void CallCFunction(Register function, Register scratch, int num_arguments);
872 void GetCFunctionDoubleResult(const DoubleRegister dst);
873
874 // Calls an API function. Allocates HandleScope, extracts returned value
875 // from handle and propagates exceptions. Restores context.
876 MaybeObject* TryCallApiFunctionAndReturn(ExternalReference function,
877 int stack_space);
765 878
766 // Jump to the builtin routine. 879 // Jump to the builtin routine.
767 void JumpToExternalReference(const ExternalReference& builtin); 880 void JumpToExternalReference(const ExternalReference& builtin);
768 881
882 MaybeObject* TryJumpToExternalReference(const ExternalReference& ext);
883
769 // Invoke specified builtin JavaScript function. Adds an entry to 884 // Invoke specified builtin JavaScript function. Adds an entry to
770 // the unresolved list if the name does not resolve. 885 // the unresolved list if the name does not resolve.
771 void InvokeBuiltin(Builtins::JavaScript id, 886 void InvokeBuiltin(Builtins::JavaScript id,
772 InvokeFlag flag, 887 InvokeFlag flag,
773 const CallWrapper& call_wrapper = NullCallWrapper()); 888 const CallWrapper& call_wrapper = NullCallWrapper());
774 889
775 // Store the code object for the given builtin in the target register and 890 // Store the code object for the given builtin in the target register and
776 // setup the function in a1. 891 // setup the function in a1.
777 void GetBuiltinEntry(Register target, Builtins::JavaScript id); 892 void GetBuiltinEntry(Register target, Builtins::JavaScript id);
778 893
779 // Store the function for the given builtin in the target register. 894 // Store the function for the given builtin in the target register.
780 void GetBuiltinFunction(Register target, Builtins::JavaScript id); 895 void GetBuiltinFunction(Register target, Builtins::JavaScript id);
781 896
782 struct Unresolved { 897 struct Unresolved {
783 int pc; 898 int pc;
784 uint32_t flags; // see Bootstrapper::FixupFlags decoders/encoders. 899 uint32_t flags; // See Bootstrapper::FixupFlags decoders/encoders.
785 const char* name; 900 const char* name;
786 }; 901 };
787 902
788 Handle<Object> CodeObject() { return code_object_; } 903 Handle<Object> CodeObject() {
904 ASSERT(!code_object_.is_null());
905 return code_object_;
906 }
789 907
790 // ------------------------------------------------------------------------- 908 // -------------------------------------------------------------------------
791 // StatsCounter support 909 // StatsCounter support.
792 910
793 void SetCounter(StatsCounter* counter, int value, 911 void SetCounter(StatsCounter* counter, int value,
794 Register scratch1, Register scratch2); 912 Register scratch1, Register scratch2);
795 void IncrementCounter(StatsCounter* counter, int value, 913 void IncrementCounter(StatsCounter* counter, int value,
796 Register scratch1, Register scratch2); 914 Register scratch1, Register scratch2);
797 void DecrementCounter(StatsCounter* counter, int value, 915 void DecrementCounter(StatsCounter* counter, int value,
798 Register scratch1, Register scratch2); 916 Register scratch1, Register scratch2);
799 917
800 918
801 // ------------------------------------------------------------------------- 919 // -------------------------------------------------------------------------
802 // Debugging 920 // Debugging.
803 921
804 // Calls Abort(msg) if the condition cc is not satisfied. 922 // Calls Abort(msg) if the condition cc is not satisfied.
805 // Use --debug_code to enable. 923 // Use --debug_code to enable.
806 void Assert(Condition cc, const char* msg, Register rs, Operand rt); 924 void Assert(Condition cc, const char* msg, Register rs, Operand rt);
807 void AssertRegisterIsRoot(Register reg, Heap::RootListIndex index); 925 void AssertRegisterIsRoot(Register reg, Heap::RootListIndex index);
808 void AssertFastElements(Register elements); 926 void AssertFastElements(Register elements);
809 927
810 // Like Assert(), but always enabled. 928 // Like Assert(), but always enabled.
811 void Check(Condition cc, const char* msg, Register rs, Operand rt); 929 void Check(Condition cc, const char* msg, Register rs, Operand rt);
812 930
813 // Print a message to stdout and abort execution. 931 // Print a message to stdout and abort execution.
814 void Abort(const char* msg); 932 void Abort(const char* msg);
815 933
816 // Verify restrictions about code generated in stubs. 934 // Verify restrictions about code generated in stubs.
817 void set_generating_stub(bool value) { generating_stub_ = value; } 935 void set_generating_stub(bool value) { generating_stub_ = value; }
818 bool generating_stub() { return generating_stub_; } 936 bool generating_stub() { return generating_stub_; }
819 void set_allow_stub_calls(bool value) { allow_stub_calls_ = value; } 937 void set_allow_stub_calls(bool value) { allow_stub_calls_ = value; }
820 bool allow_stub_calls() { return allow_stub_calls_; } 938 bool allow_stub_calls() { return allow_stub_calls_; }
821 939
822 // --------------------------------------------------------------------------- 940 // ---------------------------------------------------------------------------
823 // Number utilities 941 // Number utilities.
824 942
825 // Check whether the value of reg is a power of two and not zero. If not 943 // 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 944 // 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 945 // the register scratch contains the value of (reg - 1) when control falls
828 // through. 946 // through.
829 void JumpIfNotPowerOfTwoOrZero(Register reg, 947 void JumpIfNotPowerOfTwoOrZero(Register reg,
830 Register scratch, 948 Register scratch,
831 Label* not_power_of_two_or_zero); 949 Label* not_power_of_two_or_zero);
832 950
833 // ------------------------------------------------------------------------- 951 // -------------------------------------------------------------------------
834 // Smi utilities 952 // Smi utilities.
835 953
836 // Try to convert int32 to smi. If the value is to large, preserve 954 // 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 955 // the original value and jump to not_a_smi. Destroys scratch and
838 // sets flags. 956 // sets flags.
839 // This is only used by crankshaft atm so it is unimplemented on MIPS. 957 // This is only used by crankshaft atm so it is unimplemented on MIPS.
840 void TrySmiTag(Register reg, Label* not_a_smi, Register scratch) { 958 void TrySmiTag(Register reg, Label* not_a_smi, Register scratch) {
841 UNIMPLEMENTED_MIPS(); 959 UNIMPLEMENTED_MIPS();
842 } 960 }
843 961
844 void SmiTag(Register reg) { 962 void SmiTag(Register reg) {
(...skipping 30 matching lines...) Expand all
875 993
876 // Jump if either of the registers contain a non-smi. 994 // Jump if either of the registers contain a non-smi.
877 void JumpIfNotBothSmi(Register reg1, Register reg2, Label* on_not_both_smi); 995 void JumpIfNotBothSmi(Register reg1, Register reg2, Label* on_not_both_smi);
878 // Jump if either of the registers contain a smi. 996 // Jump if either of the registers contain a smi.
879 void JumpIfEitherSmi(Register reg1, Register reg2, Label* on_either_smi); 997 void JumpIfEitherSmi(Register reg1, Register reg2, Label* on_either_smi);
880 998
881 // Abort execution if argument is a smi. Used in debug code. 999 // Abort execution if argument is a smi. Used in debug code.
882 void AbortIfSmi(Register object); 1000 void AbortIfSmi(Register object);
883 void AbortIfNotSmi(Register object); 1001 void AbortIfNotSmi(Register object);
884 1002
1003 // Abort execution if argument is a string. Used in debug code.
1004 void AbortIfNotString(Register object);
1005
885 // Abort execution if argument is not the root value with the given index. 1006 // Abort execution if argument is not the root value with the given index.
886 void AbortIfNotRootValue(Register src, 1007 void AbortIfNotRootValue(Register src,
887 Heap::RootListIndex root_value_index, 1008 Heap::RootListIndex root_value_index,
888 const char* message); 1009 const char* message);
889 1010
890 // --------------------------------------------------------------------------- 1011 // ---------------------------------------------------------------------------
891 // HeapNumber utilities 1012 // HeapNumber utilities.
892 1013
893 void JumpIfNotHeapNumber(Register object, 1014 void JumpIfNotHeapNumber(Register object,
894 Register heap_number_map, 1015 Register heap_number_map,
895 Register scratch, 1016 Register scratch,
896 Label* on_not_heap_number); 1017 Label* on_not_heap_number);
897 1018
898 // ------------------------------------------------------------------------- 1019 // -------------------------------------------------------------------------
899 // String utilities 1020 // String utilities.
900 1021
901 // Checks if both instance types are sequential ASCII strings and jumps to 1022 // Checks if both instance types are sequential ASCII strings and jumps to
902 // label if either is not. 1023 // label if either is not.
903 void JumpIfBothInstanceTypesAreNotSequentialAscii( 1024 void JumpIfBothInstanceTypesAreNotSequentialAscii(
904 Register first_object_instance_type, 1025 Register first_object_instance_type,
905 Register second_object_instance_type, 1026 Register second_object_instance_type,
906 Register scratch1, 1027 Register scratch1,
907 Register scratch2, 1028 Register scratch2,
908 Label* failure); 1029 Label* failure);
909 1030
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
970 Register scratch2); 1091 Register scratch2);
971 1092
972 1093
973 bool generating_stub_; 1094 bool generating_stub_;
974 bool allow_stub_calls_; 1095 bool allow_stub_calls_;
975 // This handle will be patched with the code object on installation. 1096 // This handle will be patched with the code object on installation.
976 Handle<Object> code_object_; 1097 Handle<Object> code_object_;
977 }; 1098 };
978 1099
979 1100
980 #ifdef ENABLE_DEBUGGER_SUPPORT
981 // The code patcher is used to patch (typically) small parts of code e.g. for 1101 // 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 1102 // 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 1103 // 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 1104 // relocation information. If any of these constraints are violated it causes
985 // an assertion to fail. 1105 // an assertion to fail.
986 class CodePatcher { 1106 class CodePatcher {
987 public: 1107 public:
988 CodePatcher(byte* address, int instructions); 1108 CodePatcher(byte* address, int instructions);
989 virtual ~CodePatcher(); 1109 virtual ~CodePatcher();
990 1110
991 // Macro assembler to emit code. 1111 // Macro assembler to emit code.
992 MacroAssembler* masm() { return &masm_; } 1112 MacroAssembler* masm() { return &masm_; }
993 1113
994 // Emit an instruction directly. 1114 // Emit an instruction directly.
995 void Emit(Instr x); 1115 void Emit(Instr instr);
996 1116
997 // Emit an address directly. 1117 // Emit an address directly.
998 void Emit(Address addr); 1118 void Emit(Address addr);
999 1119
1120 // Change the condition part of an instruction leaving the rest of the current
1121 // instruction unchanged.
1122 void ChangeBranchCondition(Condition cond);
1123
1000 private: 1124 private:
1001 byte* address_; // The address of the code being patched. 1125 byte* address_; // The address of the code being patched.
1002 int instructions_; // Number of instructions of the expected patch size. 1126 int instructions_; // Number of instructions of the expected patch size.
1003 int size_; // Number of bytes of the expected patch size. 1127 int size_; // Number of bytes of the expected patch size.
1004 MacroAssembler masm_; // Macro assembler used to generate the code. 1128 MacroAssembler masm_; // Macro assembler used to generate the code.
1005 }; 1129 };
1006 #endif // ENABLE_DEBUGGER_SUPPORT
1007 1130
1008 1131
1009 // ----------------------------------------------------------------------------- 1132 // -----------------------------------------------------------------------------
1010 // Static helper functions. 1133 // Static helper functions.
1011 1134
1012 static MemOperand ContextOperand(Register context, int index) { 1135 static MemOperand ContextOperand(Register context, int index) {
1013 return MemOperand(context, Context::SlotOffset(index)); 1136 return MemOperand(context, Context::SlotOffset(index));
1014 } 1137 }
1015 1138
1016 1139
1017 static inline MemOperand GlobalObjectOperand() { 1140 static inline MemOperand GlobalObjectOperand() {
1018 return ContextOperand(cp, Context::GLOBAL_INDEX); 1141 return ContextOperand(cp, Context::GLOBAL_INDEX);
1019 } 1142 }
1020 1143
1021 1144
1022 // Generate a MemOperand for loading a field from an object. 1145 // Generate a MemOperand for loading a field from an object.
1023 static inline MemOperand FieldMemOperand(Register object, int offset) { 1146 static inline MemOperand FieldMemOperand(Register object, int offset) {
1024 return MemOperand(object, offset - kHeapObjectTag); 1147 return MemOperand(object, offset - kHeapObjectTag);
1025 } 1148 }
1026 1149
1027 1150
1151 // Generate a MemOperand for storing arguments 5..N on the stack
1152 // when calling CallCFunction().
1153 static inline MemOperand CFunctionArgumentOperand(int index) {
1154 ASSERT(index > StandardFrameConstants::kCArgSlotCount);
1155 // Argument 5 takes the slot just past the four Arg-slots.
1156 int offset =
1157 (index - 5) * kPointerSize + StandardFrameConstants::kCArgsSlotsSize;
1158 return MemOperand(sp, offset);
1159 }
1160
1028 1161
1029 #ifdef GENERATED_CODE_COVERAGE 1162 #ifdef GENERATED_CODE_COVERAGE
1030 #define CODE_COVERAGE_STRINGIFY(x) #x 1163 #define CODE_COVERAGE_STRINGIFY(x) #x
1031 #define CODE_COVERAGE_TOSTRING(x) CODE_COVERAGE_STRINGIFY(x) 1164 #define CODE_COVERAGE_TOSTRING(x) CODE_COVERAGE_STRINGIFY(x)
1032 #define __FILE_LINE__ __FILE__ ":" CODE_COVERAGE_TOSTRING(__LINE__) 1165 #define __FILE_LINE__ __FILE__ ":" CODE_COVERAGE_TOSTRING(__LINE__)
1033 #define ACCESS_MASM(masm) masm->stop(__FILE_LINE__); masm-> 1166 #define ACCESS_MASM(masm) masm->stop(__FILE_LINE__); masm->
1034 #else 1167 #else
1035 #define ACCESS_MASM(masm) masm-> 1168 #define ACCESS_MASM(masm) masm->
1036 #endif 1169 #endif
1037 1170
1038 } } // namespace v8::internal 1171 } } // namespace v8::internal
1039 1172
1040 #endif // V8_MIPS_MACRO_ASSEMBLER_MIPS_H_ 1173 #endif // V8_MIPS_MACRO_ASSEMBLER_MIPS_H_
1041 1174
OLDNEW
« no previous file with comments | « src/mips/lithium-mips.h ('k') | src/mips/macro-assembler-mips.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698