| OLD | NEW |
| 1 // Copyright 2006-2009 the V8 project authors. All rights reserved. | 1 // Copyright 2006-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 5372 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5383 // Load number and duplicate it. | 5383 // Load number and duplicate it. |
| 5384 Load(args->at(0)); | 5384 Load(args->at(0)); |
| 5385 frame_->Dup(); | 5385 frame_->Dup(); |
| 5386 | 5386 |
| 5387 // Get the number into an unaliased register and load it onto the | 5387 // Get the number into an unaliased register and load it onto the |
| 5388 // floating point stack still leaving one copy on the frame. | 5388 // floating point stack still leaving one copy on the frame. |
| 5389 Result number = frame_->Pop(); | 5389 Result number = frame_->Pop(); |
| 5390 number.ToRegister(); | 5390 number.ToRegister(); |
| 5391 frame_->Spill(number.reg()); | 5391 frame_->Spill(number.reg()); |
| 5392 FloatingPointHelper::LoadFloatOperand(masm_, number.reg()); | 5392 FloatingPointHelper::LoadFloatOperand(masm_, number.reg()); |
| 5393 |
| 5394 // Check whether the exponent is so big that performing a sine or |
| 5395 // cosine operation could result in inaccurate results or an |
| 5396 // exception. In that case call the runtime routine. |
| 5397 __ and_(number.reg(), HeapNumber::kExponentMask); |
| 5398 __ cmp(Operand(number.reg()), Immediate(kTwoToThePowerOf63Exponent)); |
| 5399 call_runtime.Branch(greater_equal, not_taken); |
| 5393 number.Unuse(); | 5400 number.Unuse(); |
| 5394 | 5401 |
| 5395 // Perform the operation on the number. | 5402 // Perform the operation on the number. This will succeed since we |
| 5403 // already checked that it is in range. |
| 5396 switch (op) { | 5404 switch (op) { |
| 5397 case SIN: | 5405 case SIN: |
| 5398 __ fsin(); | 5406 __ fsin(); |
| 5399 break; | 5407 break; |
| 5400 case COS: | 5408 case COS: |
| 5401 __ fcos(); | 5409 __ fcos(); |
| 5402 break; | 5410 break; |
| 5403 } | 5411 } |
| 5404 | 5412 |
| 5405 // Go slow case if argument to operation is out of range. | |
| 5406 Result eax_reg = allocator_->Allocate(eax); | |
| 5407 ASSERT(eax_reg.is_valid()); | |
| 5408 __ fnstsw_ax(); | |
| 5409 __ sahf(); | |
| 5410 eax_reg.Unuse(); | |
| 5411 call_runtime.Branch(parity_even, not_taken); | |
| 5412 | |
| 5413 // Allocate heap number for result if possible. | 5413 // Allocate heap number for result if possible. |
| 5414 Result scratch1 = allocator()->Allocate(); | 5414 Result scratch1 = allocator()->Allocate(); |
| 5415 Result scratch2 = allocator()->Allocate(); | 5415 Result scratch2 = allocator()->Allocate(); |
| 5416 Result heap_number = allocator()->Allocate(); | 5416 Result heap_number = allocator()->Allocate(); |
| 5417 __ AllocateHeapNumber(heap_number.reg(), | 5417 __ AllocateHeapNumber(heap_number.reg(), |
| 5418 scratch1.reg(), | 5418 scratch1.reg(), |
| 5419 scratch2.reg(), | 5419 scratch2.reg(), |
| 5420 call_runtime.entry_label()); | 5420 call_runtime.entry_label()); |
| 5421 scratch1.Unuse(); | 5421 scratch1.Unuse(); |
| 5422 scratch2.Unuse(); | 5422 scratch2.Unuse(); |
| (...skipping 2035 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7458 Register scratch = ebx; | 7458 Register scratch = ebx; |
| 7459 Register scratch2 = edi; | 7459 Register scratch2 = edi; |
| 7460 // Get exponent word. | 7460 // Get exponent word. |
| 7461 __ mov(scratch, FieldOperand(source, HeapNumber::kExponentOffset)); | 7461 __ mov(scratch, FieldOperand(source, HeapNumber::kExponentOffset)); |
| 7462 // Get exponent alone in scratch2. | 7462 // Get exponent alone in scratch2. |
| 7463 __ mov(scratch2, scratch); | 7463 __ mov(scratch2, scratch); |
| 7464 __ and_(scratch2, HeapNumber::kExponentMask); | 7464 __ and_(scratch2, HeapNumber::kExponentMask); |
| 7465 if (use_sse3) { | 7465 if (use_sse3) { |
| 7466 CpuFeatures::Scope scope(SSE3); | 7466 CpuFeatures::Scope scope(SSE3); |
| 7467 // Check whether the exponent is too big for a 64 bit signed integer. | 7467 // Check whether the exponent is too big for a 64 bit signed integer. |
| 7468 const uint32_t too_big_exponent = | 7468 __ cmp(Operand(scratch2), |
| 7469 (HeapNumber::kExponentBias + 63) << HeapNumber::kExponentShift; | 7469 Immediate(CodeGenerator::kTwoToThePowerOf63Exponent)); |
| 7470 __ cmp(Operand(scratch2), Immediate(too_big_exponent)); | |
| 7471 __ j(greater_equal, conversion_failure); | 7470 __ j(greater_equal, conversion_failure); |
| 7472 // Load x87 register with heap number. | 7471 // Load x87 register with heap number. |
| 7473 __ fld_d(FieldOperand(source, HeapNumber::kValueOffset)); | 7472 __ fld_d(FieldOperand(source, HeapNumber::kValueOffset)); |
| 7474 // Reserve space for 64 bit answer. | 7473 // Reserve space for 64 bit answer. |
| 7475 __ sub(Operand(esp), Immediate(sizeof(uint64_t))); // Nolint. | 7474 __ sub(Operand(esp), Immediate(sizeof(uint64_t))); // Nolint. |
| 7476 // Do conversion, which cannot fail because we checked the exponent. | 7475 // Do conversion, which cannot fail because we checked the exponent. |
| 7477 __ fisttp_d(Operand(esp, 0)); | 7476 __ fisttp_d(Operand(esp, 0)); |
| 7478 __ mov(ecx, Operand(esp, 0)); // Load low word of answer into ecx. | 7477 __ mov(ecx, Operand(esp, 0)); // Load low word of answer into ecx. |
| 7479 __ add(Operand(esp), Immediate(sizeof(uint64_t))); // Nolint. | 7478 __ add(Operand(esp), Immediate(sizeof(uint64_t))); // Nolint. |
| 7480 } else { | 7479 } else { |
| (...skipping 1478 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8959 __ add(Operand(dest), Immediate(2)); | 8958 __ add(Operand(dest), Immediate(2)); |
| 8960 } | 8959 } |
| 8961 __ sub(Operand(count), Immediate(1)); | 8960 __ sub(Operand(count), Immediate(1)); |
| 8962 __ j(not_zero, &loop); | 8961 __ j(not_zero, &loop); |
| 8963 } | 8962 } |
| 8964 | 8963 |
| 8965 | 8964 |
| 8966 #undef __ | 8965 #undef __ |
| 8967 | 8966 |
| 8968 } } // namespace v8::internal | 8967 } } // namespace v8::internal |
| OLD | NEW |