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 5357 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5368 // Restore stack pointer from callee-saved register edi. | 5368 // Restore stack pointer from callee-saved register edi. |
5369 if (kFrameAlignment > 0) { | 5369 if (kFrameAlignment > 0) { |
5370 __ mov(esp, Operand(edi)); | 5370 __ mov(esp, Operand(edi)); |
5371 } | 5371 } |
5372 | 5372 |
5373 Result result = allocator_->Allocate(eax); | 5373 Result result = allocator_->Allocate(eax); |
5374 frame_->Push(&result); | 5374 frame_->Push(&result); |
5375 } | 5375 } |
5376 | 5376 |
5377 | 5377 |
5378 void CodeGenerator::GenerateFastMathOp(MathOp op, ZoneList<Expression*>* args) { | |
5379 JumpTarget done; | |
5380 JumpTarget call_runtime; | |
5381 ASSERT(args->length() == 1); | |
5382 | |
5383 // Load number and duplicate it. | |
5384 Load(args->at(0)); | |
5385 frame_->Dup(); | |
5386 | |
5387 // Get the number into an unaliased register and load it onto the | |
5388 // floating point stack still leaving one copy on the frame. | |
5389 Result number = frame_->Pop(); | |
5390 number.ToRegister(); | |
5391 frame_->Spill(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); | |
5400 number.Unuse(); | |
5401 | |
5402 // Perform the operation on the number. This will succeed since we | |
5403 // already checked that it is in range. | |
5404 switch (op) { | |
5405 case SIN: | |
5406 __ fsin(); | |
5407 break; | |
5408 case COS: | |
5409 __ fcos(); | |
5410 break; | |
5411 } | |
5412 | |
5413 // Allocate heap number for result if possible. | |
5414 Result scratch1 = allocator()->Allocate(); | |
5415 Result scratch2 = allocator()->Allocate(); | |
5416 Result heap_number = allocator()->Allocate(); | |
5417 __ AllocateHeapNumber(heap_number.reg(), | |
5418 scratch1.reg(), | |
5419 scratch2.reg(), | |
5420 call_runtime.entry_label()); | |
5421 scratch1.Unuse(); | |
5422 scratch2.Unuse(); | |
5423 | |
5424 // Store the result in the allocated heap number. | |
5425 __ fstp_d(FieldOperand(heap_number.reg(), HeapNumber::kValueOffset)); | |
5426 // Replace the extra copy of the argument with the result. | |
5427 frame_->SetElementAt(0, &heap_number); | |
5428 done.Jump(); | |
5429 | |
5430 call_runtime.Bind(); | |
5431 // Free ST(0) which was not popped before calling into the runtime. | |
5432 __ ffree(0); | |
5433 Result answer; | |
5434 switch (op) { | |
5435 case SIN: | |
5436 answer = frame_->CallRuntime(Runtime::kMath_sin, 1); | |
5437 break; | |
5438 case COS: | |
5439 answer = frame_->CallRuntime(Runtime::kMath_cos, 1); | |
5440 break; | |
5441 } | |
5442 frame_->Push(&answer); | |
5443 done.Bind(); | |
5444 } | |
5445 | |
5446 | |
5447 void CodeGenerator::GenerateStringAdd(ZoneList<Expression*>* args) { | 5378 void CodeGenerator::GenerateStringAdd(ZoneList<Expression*>* args) { |
5448 ASSERT_EQ(2, args->length()); | 5379 ASSERT_EQ(2, args->length()); |
5449 | 5380 |
5450 Load(args->at(0)); | 5381 Load(args->at(0)); |
5451 Load(args->at(1)); | 5382 Load(args->at(1)); |
5452 | 5383 |
5453 StringAddStub stub(NO_STRING_ADD_FLAGS); | 5384 StringAddStub stub(NO_STRING_ADD_FLAGS); |
5454 Result answer = frame_->CallStub(&stub, 2); | 5385 Result answer = frame_->CallStub(&stub, 2); |
5455 frame_->Push(&answer); | 5386 frame_->Push(&answer); |
5456 } | 5387 } |
(...skipping 2001 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7458 Register scratch = ebx; | 7389 Register scratch = ebx; |
7459 Register scratch2 = edi; | 7390 Register scratch2 = edi; |
7460 // Get exponent word. | 7391 // Get exponent word. |
7461 __ mov(scratch, FieldOperand(source, HeapNumber::kExponentOffset)); | 7392 __ mov(scratch, FieldOperand(source, HeapNumber::kExponentOffset)); |
7462 // Get exponent alone in scratch2. | 7393 // Get exponent alone in scratch2. |
7463 __ mov(scratch2, scratch); | 7394 __ mov(scratch2, scratch); |
7464 __ and_(scratch2, HeapNumber::kExponentMask); | 7395 __ and_(scratch2, HeapNumber::kExponentMask); |
7465 if (use_sse3) { | 7396 if (use_sse3) { |
7466 CpuFeatures::Scope scope(SSE3); | 7397 CpuFeatures::Scope scope(SSE3); |
7467 // Check whether the exponent is too big for a 64 bit signed integer. | 7398 // Check whether the exponent is too big for a 64 bit signed integer. |
7468 __ cmp(Operand(scratch2), | 7399 static const uint32_t kTooBigExponent = |
7469 Immediate(CodeGenerator::kTwoToThePowerOf63Exponent)); | 7400 (HeapNumber::kExponentBias + 63) << HeapNumber::kExponentShift; |
| 7401 __ cmp(Operand(scratch2), Immediate(kTooBigExponent)); |
7470 __ j(greater_equal, conversion_failure); | 7402 __ j(greater_equal, conversion_failure); |
7471 // Load x87 register with heap number. | 7403 // Load x87 register with heap number. |
7472 __ fld_d(FieldOperand(source, HeapNumber::kValueOffset)); | 7404 __ fld_d(FieldOperand(source, HeapNumber::kValueOffset)); |
7473 // Reserve space for 64 bit answer. | 7405 // Reserve space for 64 bit answer. |
7474 __ sub(Operand(esp), Immediate(sizeof(uint64_t))); // Nolint. | 7406 __ sub(Operand(esp), Immediate(sizeof(uint64_t))); // Nolint. |
7475 // Do conversion, which cannot fail because we checked the exponent. | 7407 // Do conversion, which cannot fail because we checked the exponent. |
7476 __ fisttp_d(Operand(esp, 0)); | 7408 __ fisttp_d(Operand(esp, 0)); |
7477 __ mov(ecx, Operand(esp, 0)); // Load low word of answer into ecx. | 7409 __ mov(ecx, Operand(esp, 0)); // Load low word of answer into ecx. |
7478 __ add(Operand(esp), Immediate(sizeof(uint64_t))); // Nolint. | 7410 __ add(Operand(esp), Immediate(sizeof(uint64_t))); // Nolint. |
7479 } else { | 7411 } else { |
(...skipping 1478 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
8958 __ add(Operand(dest), Immediate(2)); | 8890 __ add(Operand(dest), Immediate(2)); |
8959 } | 8891 } |
8960 __ sub(Operand(count), Immediate(1)); | 8892 __ sub(Operand(count), Immediate(1)); |
8961 __ j(not_zero, &loop); | 8893 __ j(not_zero, &loop); |
8962 } | 8894 } |
8963 | 8895 |
8964 | 8896 |
8965 #undef __ | 8897 #undef __ |
8966 | 8898 |
8967 } } // namespace v8::internal | 8899 } } // namespace v8::internal |
OLD | NEW |