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