OLD | NEW |
1 // Copyright 2009 the V8 project authors. All rights reserved. | 1 // Copyright 2009 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 |
(...skipping 222 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
233 // registers. | 233 // registers. |
234 static void LoadInt32Operand(MacroAssembler* masm, | 234 static void LoadInt32Operand(MacroAssembler* masm, |
235 const Operand& src, | 235 const Operand& src, |
236 Register dst); | 236 Register dst); |
237 | 237 |
238 // Test if operands are smi or number objects (fp). Requirements: | 238 // Test if operands are smi or number objects (fp). Requirements: |
239 // operand_1 in rax, operand_2 in rdx; falls through on float or smi | 239 // operand_1 in rax, operand_2 in rdx; falls through on float or smi |
240 // operands, jumps to the non_float label otherwise. | 240 // operands, jumps to the non_float label otherwise. |
241 static void CheckNumberOperands(MacroAssembler* masm, | 241 static void CheckNumberOperands(MacroAssembler* masm, |
242 Label* non_float); | 242 Label* non_float); |
243 | |
244 // Allocate a heap number in new space with undefined value. | |
245 // Returns tagged pointer in result, or jumps to need_gc if new space is full. | |
246 static void AllocateHeapNumber(MacroAssembler* masm, | |
247 Label* need_gc, | |
248 Register scratch, | |
249 Register result); | |
250 }; | 243 }; |
251 | 244 |
252 | 245 |
253 // ----------------------------------------------------------------------------- | 246 // ----------------------------------------------------------------------------- |
254 // CodeGenerator implementation. | 247 // CodeGenerator implementation. |
255 | 248 |
256 CodeGenerator::CodeGenerator(int buffer_size, | 249 CodeGenerator::CodeGenerator(int buffer_size, |
257 Handle<Script> script, | 250 Handle<Script> script, |
258 bool is_eval) | 251 bool is_eval) |
259 : is_eval_(is_eval), | 252 : is_eval_(is_eval), |
(...skipping 3708 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3968 Result eax_reg = allocator()->Allocate(rax); | 3961 Result eax_reg = allocator()->Allocate(rax); |
3969 ASSERT(eax_reg.is_valid()); | 3962 ASSERT(eax_reg.is_valid()); |
3970 __ fnstsw_ax(); | 3963 __ fnstsw_ax(); |
3971 __ testl(rax, Immediate(0x0400)); // Bit 10 is condition flag C2. | 3964 __ testl(rax, Immediate(0x0400)); // Bit 10 is condition flag C2. |
3972 eax_reg.Unuse(); | 3965 eax_reg.Unuse(); |
3973 call_runtime.Branch(not_zero); | 3966 call_runtime.Branch(not_zero); |
3974 | 3967 |
3975 // Allocate heap number for result if possible. | 3968 // Allocate heap number for result if possible. |
3976 Result scratch = allocator()->Allocate(); | 3969 Result scratch = allocator()->Allocate(); |
3977 Result heap_number = allocator()->Allocate(); | 3970 Result heap_number = allocator()->Allocate(); |
3978 FloatingPointHelper::AllocateHeapNumber(masm_, | 3971 __ AllocateHeapNumber(heap_number.reg(), |
3979 call_runtime.entry_label(), | 3972 scratch.reg(), |
3980 scratch.reg(), | 3973 call_runtime.entry_label()); |
3981 heap_number.reg()); | |
3982 scratch.Unuse(); | 3974 scratch.Unuse(); |
3983 | 3975 |
3984 // Store the result in the allocated heap number. | 3976 // Store the result in the allocated heap number. |
3985 __ fstp_d(FieldOperand(heap_number.reg(), HeapNumber::kValueOffset)); | 3977 __ fstp_d(FieldOperand(heap_number.reg(), HeapNumber::kValueOffset)); |
3986 // Replace the extra copy of the argument with the result. | 3978 // Replace the extra copy of the argument with the result. |
3987 frame_->SetElementAt(0, &heap_number); | 3979 frame_->SetElementAt(0, &heap_number); |
3988 done.Jump(); | 3980 done.Jump(); |
3989 | 3981 |
3990 call_runtime.Bind(); | 3982 call_runtime.Bind(); |
3991 // Free ST(0) which was not popped before calling into the runtime. | 3983 // Free ST(0) which was not popped before calling into the runtime. |
(...skipping 2364 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6356 __ j(not_equal, &slow); | 6348 __ j(not_equal, &slow); |
6357 // Operand is a float, negate its value by flipping sign bit. | 6349 // Operand is a float, negate its value by flipping sign bit. |
6358 __ movq(rdx, FieldOperand(rax, HeapNumber::kValueOffset)); | 6350 __ movq(rdx, FieldOperand(rax, HeapNumber::kValueOffset)); |
6359 __ movq(kScratchRegister, Immediate(0x01)); | 6351 __ movq(kScratchRegister, Immediate(0x01)); |
6360 __ shl(kScratchRegister, Immediate(63)); | 6352 __ shl(kScratchRegister, Immediate(63)); |
6361 __ xor_(rdx, kScratchRegister); // Flip sign. | 6353 __ xor_(rdx, kScratchRegister); // Flip sign. |
6362 // rdx is value to store. | 6354 // rdx is value to store. |
6363 if (overwrite_) { | 6355 if (overwrite_) { |
6364 __ movq(FieldOperand(rax, HeapNumber::kValueOffset), rdx); | 6356 __ movq(FieldOperand(rax, HeapNumber::kValueOffset), rdx); |
6365 } else { | 6357 } else { |
6366 FloatingPointHelper::AllocateHeapNumber(masm, &slow, rbx, rcx); | 6358 __ AllocateHeapNumber(rcx, rbx, &slow); |
6367 // rcx: allocated 'empty' number | 6359 // rcx: allocated 'empty' number |
6368 __ movq(FieldOperand(rcx, HeapNumber::kValueOffset), rdx); | 6360 __ movq(FieldOperand(rcx, HeapNumber::kValueOffset), rdx); |
6369 __ movq(rax, rcx); | 6361 __ movq(rax, rcx); |
6370 } | 6362 } |
6371 | 6363 |
6372 __ bind(&done); | 6364 __ bind(&done); |
6373 __ StubReturn(1); | 6365 __ StubReturn(1); |
6374 } | 6366 } |
6375 | 6367 |
6376 | 6368 |
(...skipping 826 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7203 __ pop(rax); | 7195 __ pop(rax); |
7204 __ Push(Smi::FromInt(0)); | 7196 __ Push(Smi::FromInt(0)); |
7205 __ push(rax); | 7197 __ push(rax); |
7206 | 7198 |
7207 // Do tail-call to runtime routine. | 7199 // Do tail-call to runtime routine. |
7208 Runtime::Function* f = Runtime::FunctionForId(Runtime::kStackGuard); | 7200 Runtime::Function* f = Runtime::FunctionForId(Runtime::kStackGuard); |
7209 __ TailCallRuntime(ExternalReference(f), 1, f->result_size); | 7201 __ TailCallRuntime(ExternalReference(f), 1, f->result_size); |
7210 } | 7202 } |
7211 | 7203 |
7212 | 7204 |
7213 void FloatingPointHelper::AllocateHeapNumber(MacroAssembler* masm, | |
7214 Label* need_gc, | |
7215 Register scratch, | |
7216 Register result) { | |
7217 // Allocate heap number in new space. | |
7218 __ AllocateInNewSpace(HeapNumber::kSize, | |
7219 result, | |
7220 scratch, | |
7221 no_reg, | |
7222 need_gc, | |
7223 TAG_OBJECT); | |
7224 | |
7225 // Set the map and tag the result. | |
7226 __ LoadRoot(kScratchRegister, Heap::kHeapNumberMapRootIndex); | |
7227 __ movq(FieldOperand(result, HeapObject::kMapOffset), kScratchRegister); | |
7228 } | |
7229 | |
7230 | |
7231 void FloatingPointHelper::LoadFloatOperand(MacroAssembler* masm, | 7205 void FloatingPointHelper::LoadFloatOperand(MacroAssembler* masm, |
7232 Register number) { | 7206 Register number) { |
7233 Label load_smi, done; | 7207 Label load_smi, done; |
7234 | 7208 |
7235 __ JumpIfSmi(number, &load_smi); | 7209 __ JumpIfSmi(number, &load_smi); |
7236 __ fld_d(FieldOperand(number, HeapNumber::kValueOffset)); | 7210 __ fld_d(FieldOperand(number, HeapNumber::kValueOffset)); |
7237 __ jmp(&done); | 7211 __ jmp(&done); |
7238 | 7212 |
7239 __ bind(&load_smi); | 7213 __ bind(&load_smi); |
7240 __ SmiToInteger32(number, number); | 7214 __ SmiToInteger32(number, number); |
(...skipping 239 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7480 switch (mode_) { | 7454 switch (mode_) { |
7481 case OVERWRITE_LEFT: | 7455 case OVERWRITE_LEFT: |
7482 __ movq(rax, rdx); | 7456 __ movq(rax, rdx); |
7483 // Fall through! | 7457 // Fall through! |
7484 case OVERWRITE_RIGHT: | 7458 case OVERWRITE_RIGHT: |
7485 // If the argument in rax is already an object, we skip the | 7459 // If the argument in rax is already an object, we skip the |
7486 // allocation of a heap number. | 7460 // allocation of a heap number. |
7487 __ JumpIfNotSmi(rax, &skip_allocation); | 7461 __ JumpIfNotSmi(rax, &skip_allocation); |
7488 // Fall through! | 7462 // Fall through! |
7489 case NO_OVERWRITE: | 7463 case NO_OVERWRITE: |
7490 FloatingPointHelper::AllocateHeapNumber(masm, | 7464 __ AllocateHeapNumber(rax, rcx, &call_runtime); |
7491 &call_runtime, | |
7492 rcx, | |
7493 rax); | |
7494 __ bind(&skip_allocation); | 7465 __ bind(&skip_allocation); |
7495 break; | 7466 break; |
7496 default: UNREACHABLE(); | 7467 default: UNREACHABLE(); |
7497 } | 7468 } |
7498 // xmm4 and xmm5 are volatile XMM registers. | 7469 // xmm4 and xmm5 are volatile XMM registers. |
7499 FloatingPointHelper::LoadFloatOperands(masm, xmm4, xmm5); | 7470 FloatingPointHelper::LoadFloatOperands(masm, xmm4, xmm5); |
7500 | 7471 |
7501 switch (op_) { | 7472 switch (op_) { |
7502 case Token::ADD: __ addsd(xmm4, xmm5); break; | 7473 case Token::ADD: __ addsd(xmm4, xmm5); break; |
7503 case Token::SUB: __ subsd(xmm4, xmm5); break; | 7474 case Token::SUB: __ subsd(xmm4, xmm5); break; |
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7599 switch (mode_) { | 7570 switch (mode_) { |
7600 case OVERWRITE_LEFT: | 7571 case OVERWRITE_LEFT: |
7601 case OVERWRITE_RIGHT: | 7572 case OVERWRITE_RIGHT: |
7602 // If the operand was an object, we skip the | 7573 // If the operand was an object, we skip the |
7603 // allocation of a heap number. | 7574 // allocation of a heap number. |
7604 __ movq(rax, Operand(rsp, mode_ == OVERWRITE_RIGHT ? | 7575 __ movq(rax, Operand(rsp, mode_ == OVERWRITE_RIGHT ? |
7605 1 * kPointerSize : 2 * kPointerSize)); | 7576 1 * kPointerSize : 2 * kPointerSize)); |
7606 __ JumpIfNotSmi(rax, &skip_allocation); | 7577 __ JumpIfNotSmi(rax, &skip_allocation); |
7607 // Fall through! | 7578 // Fall through! |
7608 case NO_OVERWRITE: | 7579 case NO_OVERWRITE: |
7609 FloatingPointHelper::AllocateHeapNumber(masm, &call_runtime, | 7580 __ AllocateHeapNumber(rax, rcx, &call_runtime); |
7610 rcx, rax); | |
7611 __ bind(&skip_allocation); | 7581 __ bind(&skip_allocation); |
7612 break; | 7582 break; |
7613 default: UNREACHABLE(); | 7583 default: UNREACHABLE(); |
7614 } | 7584 } |
7615 // Store the result in the HeapNumber and return. | 7585 // Store the result in the HeapNumber and return. |
7616 __ movq(Operand(rsp, 1 * kPointerSize), rbx); | 7586 __ movq(Operand(rsp, 1 * kPointerSize), rbx); |
7617 __ fild_s(Operand(rsp, 1 * kPointerSize)); | 7587 __ fild_s(Operand(rsp, 1 * kPointerSize)); |
7618 __ fstp_d(FieldOperand(rax, HeapNumber::kValueOffset)); | 7588 __ fstp_d(FieldOperand(rax, HeapNumber::kValueOffset)); |
7619 __ ret(2 * kPointerSize); | 7589 __ ret(2 * kPointerSize); |
7620 } | 7590 } |
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7692 int CompareStub::MinorKey() { | 7662 int CompareStub::MinorKey() { |
7693 // Encode the two parameters in a unique 16 bit value. | 7663 // Encode the two parameters in a unique 16 bit value. |
7694 ASSERT(static_cast<unsigned>(cc_) < (1 << 15)); | 7664 ASSERT(static_cast<unsigned>(cc_) < (1 << 15)); |
7695 return (static_cast<unsigned>(cc_) << 1) | (strict_ ? 1 : 0); | 7665 return (static_cast<unsigned>(cc_) << 1) | (strict_ ? 1 : 0); |
7696 } | 7666 } |
7697 | 7667 |
7698 | 7668 |
7699 #undef __ | 7669 #undef __ |
7700 | 7670 |
7701 } } // namespace v8::internal | 7671 } } // namespace v8::internal |
OLD | NEW |