| 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 |