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 |