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 151 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
162 | 162 |
163 private: | 163 private: |
164 Token::Value op_; | 164 Token::Value op_; |
165 Register dst_; | 165 Register dst_; |
166 Register src_; | 166 Register src_; |
167 Smi* value_; | 167 Smi* value_; |
168 OverwriteMode overwrite_mode_; | 168 OverwriteMode overwrite_mode_; |
169 }; | 169 }; |
170 | 170 |
171 | 171 |
172 class FloatingPointHelper : public AllStatic { | |
173 public: | |
174 // Code pattern for loading a floating point value. Input value must | |
175 // be either a smi or a heap number object (fp value). Requirements: | |
176 // operand on TOS+1. Returns operand as floating point number on FPU | |
177 // stack. | |
178 static void LoadFloatOperand(MacroAssembler* masm, Register scratch); | |
Lasse Reichstein
2009/08/06 12:49:39
Add an empty line after declarations.
| |
179 // Code pattern for loading a floating point value. Input value must | |
180 // be either a smi or a heap number object (fp value). Requirements: | |
181 // operand in src register. Returns operand as floating point number | |
182 // in XMM register | |
183 static void LoadFloatOperand(MacroAssembler* masm, | |
184 Register src, | |
185 XMMRegister dst); | |
186 // Code pattern for loading floating point values. Input values must | |
187 // be either smi or heap number objects (fp values). Requirements: | |
188 // operand_1 on TOS+1 , operand_2 on TOS+2; Returns operands as | |
189 // floating point numbers in XMM registers. | |
190 static void LoadFloatOperands(MacroAssembler* masm, | |
191 XMMRegister dst1, | |
192 XMMRegister dst2); | |
193 | |
194 // Code pattern for loading floating point values onto the fp stack. | |
195 // Input values must be either smi or heap number objects (fp values). | |
196 // Requirements: | |
197 // Register version: operands in registers lhs and rhs. | |
198 // Stack version: operands on TOS+1 and TOS+2. | |
199 // Returns operands as floating point numbers on fp stack. | |
200 static void LoadFloatOperands(MacroAssembler* masm); | |
201 static void LoadFloatOperands(MacroAssembler* masm, | |
202 Register lhs, | |
203 Register rhs); | |
204 | |
205 // Code pattern for loading a floating point value and converting it | |
206 // to a 32 bit integer. Input value must be either a smi or a heap number | |
207 // object. | |
208 // Returns operands as 32-bit sign extended integers in a general purpose | |
209 // registers. | |
210 static void LoadInt32Operand(MacroAssembler* masm, | |
211 const Operand& src, | |
212 Register dst); | |
213 | |
214 // Test if operands are smi or number objects (fp). Requirements: | |
Lasse Reichstein
2009/08/06 12:49:39
Unclear whether it tests (is smi or is heapnumber)
| |
215 // operand_1 in rax, operand_2 in rdx; falls through on float | |
216 // operands, jumps to the non_float label otherwise. | |
217 static void CheckFloatOperands(MacroAssembler* masm, | |
218 Label* non_float); | |
219 // Allocate a heap number in new space with undefined value. | |
220 // Returns tagged pointer in result, or jumps to need_gc if new space is full. | |
221 static void AllocateHeapNumber(MacroAssembler* masm, | |
222 Label* need_gc, | |
223 Register scratch, | |
224 Register result); | |
225 }; | |
226 | |
227 | |
172 // ----------------------------------------------------------------------------- | 228 // ----------------------------------------------------------------------------- |
173 // CodeGenerator implementation. | 229 // CodeGenerator implementation. |
174 | 230 |
175 CodeGenerator::CodeGenerator(int buffer_size, | 231 CodeGenerator::CodeGenerator(int buffer_size, |
176 Handle<Script> script, | 232 Handle<Script> script, |
177 bool is_eval) | 233 bool is_eval) |
178 : is_eval_(is_eval), | 234 : is_eval_(is_eval), |
179 script_(script), | 235 script_(script), |
180 deferred_(8), | 236 deferred_(8), |
181 masm_(new MacroAssembler(NULL, buffer_size)), | 237 masm_(new MacroAssembler(NULL, buffer_size)), |
(...skipping 3342 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3524 __ movq(rsp, rbx); | 3580 __ movq(rsp, rbx); |
3525 } | 3581 } |
3526 | 3582 |
3527 __ pop(rsi); | 3583 __ pop(rsi); |
3528 Result result = allocator_->Allocate(rax); | 3584 Result result = allocator_->Allocate(rax); |
3529 frame_->Push(&result); | 3585 frame_->Push(&result); |
3530 } | 3586 } |
3531 | 3587 |
3532 | 3588 |
3533 void CodeGenerator::GenerateFastMathOp(MathOp op, ZoneList<Expression*>* args) { | 3589 void CodeGenerator::GenerateFastMathOp(MathOp op, ZoneList<Expression*>* args) { |
3534 // TODO(X64): Use inline floating point in the fast case. | 3590 JumpTarget done; |
3591 JumpTarget call_runtime; | |
3535 ASSERT(args->length() == 1); | 3592 ASSERT(args->length() == 1); |
3536 | 3593 |
3537 // Load number. | 3594 // Load number and duplicate it. |
3538 Load(args->at(0)); | 3595 Load(args->at(0)); |
3596 frame_->Dup(); | |
3597 | |
3598 // Get the number into an unaliased register and load it onto the | |
3599 // floating point stack still leaving one copy on the frame. | |
3600 Result number = frame_->Pop(); | |
3601 number.ToRegister(); | |
3602 frame_->Spill(number.reg()); | |
3603 FloatingPointHelper::LoadFloatOperand(masm_, number.reg()); | |
3604 number.Unuse(); | |
3605 | |
3606 // Perform the operation on the number. | |
3607 switch (op) { | |
3608 case SIN: | |
3609 __ fsin(); | |
3610 break; | |
3611 case COS: | |
3612 __ fcos(); | |
3613 break; | |
3614 } | |
3615 | |
3616 // Go slow case if argument to operation is out of range. | |
3617 __ fnstsw_ax(); | |
3618 __ sahf(); | |
Lasse Reichstein
2009/08/06 12:49:39
Using sahf is theoretically unsafe (not supported
| |
3619 call_runtime.Branch(parity_even); | |
3620 | |
3621 // Allocate heap number for result if possible. | |
3622 Result scratch = allocator()->Allocate(); | |
3623 Result heap_number = allocator()->Allocate(); | |
3624 FloatingPointHelper::AllocateHeapNumber(masm_, | |
3625 call_runtime.entry_label(), | |
3626 scratch.reg(), | |
3627 heap_number.reg()); | |
3628 scratch.Unuse(); | |
3629 | |
3630 // Store the result in the allocated heap number. | |
3631 __ fstp_d(FieldOperand(heap_number.reg(), HeapNumber::kValueOffset)); | |
3632 // Replace the extra copy of the argument with the result. | |
3633 frame_->SetElementAt(0, &heap_number); | |
3634 done.Jump(); | |
3635 | |
3636 call_runtime.Bind(); | |
3637 // Free ST(0) which was not popped before calling into the runtime. | |
3638 __ ffree(0); | |
3539 Result answer; | 3639 Result answer; |
3540 switch (op) { | 3640 switch (op) { |
3541 case SIN: | 3641 case SIN: |
3542 answer = frame_->CallRuntime(Runtime::kMath_sin, 1); | 3642 answer = frame_->CallRuntime(Runtime::kMath_sin, 1); |
3543 break; | 3643 break; |
3544 case COS: | 3644 case COS: |
3545 answer = frame_->CallRuntime(Runtime::kMath_cos, 1); | 3645 answer = frame_->CallRuntime(Runtime::kMath_cos, 1); |
3546 break; | 3646 break; |
3547 } | 3647 } |
3548 frame_->Push(&answer); | 3648 frame_->Push(&answer); |
3649 done.Bind(); | |
3549 } | 3650 } |
3550 | 3651 |
3551 | 3652 |
3552 void CodeGenerator::GenerateClassOf(ZoneList<Expression*>* args) { | 3653 void CodeGenerator::GenerateClassOf(ZoneList<Expression*>* args) { |
3553 ASSERT(args->length() == 1); | 3654 ASSERT(args->length() == 1); |
3554 JumpTarget leave, null, function, non_function_constructor; | 3655 JumpTarget leave, null, function, non_function_constructor; |
3555 Load(args->at(0)); // Load the object. | 3656 Load(args->at(0)); // Load the object. |
3556 Result obj = frame_->Pop(); | 3657 Result obj = frame_->Pop(); |
3557 obj.ToRegister(); | 3658 obj.ToRegister(); |
3558 frame_->Spill(obj.reg()); | 3659 frame_->Spill(obj.reg()); |
(...skipping 1040 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
4599 right_side = Result(right_reg); | 4700 right_side = Result(right_reg); |
4600 __ cmpl(left_side.reg(), right_side.reg()); | 4701 __ cmpl(left_side.reg(), right_side.reg()); |
4601 right_side.Unuse(); | 4702 right_side.Unuse(); |
4602 left_side.Unuse(); | 4703 left_side.Unuse(); |
4603 dest->Split(cc); | 4704 dest->Split(cc); |
4604 } | 4705 } |
4605 } | 4706 } |
4606 } | 4707 } |
4607 | 4708 |
4608 | 4709 |
4609 class FloatingPointHelper : public AllStatic { | |
4610 public: | |
4611 // Code pattern for loading a floating point value. Input value must | |
4612 // be either a smi or a heap number object (fp value). Requirements: | |
4613 // operand in src register. Returns operand as floating point number | |
4614 // in XMM register | |
4615 static void LoadFloatOperand(MacroAssembler* masm, | |
4616 Register src, | |
4617 XMMRegister dst); | |
4618 // Code pattern for loading floating point values. Input values must | |
4619 // be either smi or heap number objects (fp values). Requirements: | |
4620 // operand_1 on TOS+1 , operand_2 on TOS+2; Returns operands as | |
4621 // floating point numbers in XMM registers. | |
4622 static void LoadFloatOperands(MacroAssembler* masm, | |
4623 XMMRegister dst1, | |
4624 XMMRegister dst2); | |
4625 | |
4626 // Code pattern for loading floating point values onto the fp stack. | |
4627 // Input values must be either smi or heap number objects (fp values). | |
4628 // Requirements: | |
4629 // Register version: operands in registers lhs and rhs. | |
4630 // Stack version: operands on TOS+1 and TOS+2. | |
4631 // Returns operands as floating point numbers on fp stack. | |
4632 static void LoadFloatOperands(MacroAssembler* masm); | |
4633 static void LoadFloatOperands(MacroAssembler* masm, | |
4634 Register lhs, | |
4635 Register rhs); | |
4636 | |
4637 // Code pattern for loading a floating point value and converting it | |
4638 // to a 32 bit integer. Input value must be either a smi or a heap number | |
4639 // object. | |
4640 // Returns operands as 32-bit sign extended integers in a general purpose | |
4641 // registers. | |
4642 static void LoadInt32Operand(MacroAssembler* masm, | |
4643 const Operand& src, | |
4644 Register dst); | |
4645 | |
4646 // Test if operands are smi or number objects (fp). Requirements: | |
4647 // operand_1 in rax, operand_2 in rdx; falls through on float | |
4648 // operands, jumps to the non_float label otherwise. | |
4649 static void CheckFloatOperands(MacroAssembler* masm, | |
4650 Label* non_float); | |
4651 // Allocate a heap number in new space with undefined value. | |
4652 // Returns tagged pointer in result, or jumps to need_gc if new space is full. | |
4653 static void AllocateHeapNumber(MacroAssembler* masm, | |
4654 Label* need_gc, | |
4655 Register scratch, | |
4656 Register result); | |
4657 }; | |
4658 | |
4659 | |
4660 class DeferredInlineBinaryOperation: public DeferredCode { | 4710 class DeferredInlineBinaryOperation: public DeferredCode { |
4661 public: | 4711 public: |
4662 DeferredInlineBinaryOperation(Token::Value op, | 4712 DeferredInlineBinaryOperation(Token::Value op, |
4663 Register dst, | 4713 Register dst, |
4664 Register left, | 4714 Register left, |
4665 Register right, | 4715 Register right, |
4666 OverwriteMode mode) | 4716 OverwriteMode mode) |
4667 : op_(op), dst_(dst), left_(left), right_(right), mode_(mode) { | 4717 : op_(op), dst_(dst), left_(left), right_(right), mode_(mode) { |
4668 set_comment("[ DeferredInlineBinaryOperation"); | 4718 set_comment("[ DeferredInlineBinaryOperation"); |
4669 } | 4719 } |
(...skipping 2083 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
6753 __ movq(Operand(scratch, 0), result); // store new top | 6803 __ movq(Operand(scratch, 0), result); // store new top |
6754 __ addq(result, Immediate(kHeapObjectTag - HeapNumber::kSize)); | 6804 __ addq(result, Immediate(kHeapObjectTag - HeapNumber::kSize)); |
6755 __ movq(kScratchRegister, | 6805 __ movq(kScratchRegister, |
6756 Factory::heap_number_map(), | 6806 Factory::heap_number_map(), |
6757 RelocInfo::EMBEDDED_OBJECT); | 6807 RelocInfo::EMBEDDED_OBJECT); |
6758 __ movq(FieldOperand(result, HeapObject::kMapOffset), kScratchRegister); | 6808 __ movq(FieldOperand(result, HeapObject::kMapOffset), kScratchRegister); |
6759 // Tag old top and use as result. | 6809 // Tag old top and use as result. |
6760 } | 6810 } |
6761 | 6811 |
6762 | 6812 |
6813 void FloatingPointHelper::LoadFloatOperand(MacroAssembler* masm, | |
6814 Register number) { | |
6815 Label load_smi, done; | |
6816 | |
6817 __ testl(number, Immediate(kSmiTagMask)); | |
6818 __ j(zero, &load_smi); | |
6819 __ fld_d(FieldOperand(number, HeapNumber::kValueOffset)); | |
6820 __ jmp(&done); | |
6821 | |
6822 __ bind(&load_smi); | |
6823 __ sarl(number, Immediate(kSmiTagSize)); | |
6824 __ push(number); | |
6825 __ fild_s(Operand(rsp, 0)); | |
6826 __ pop(number); | |
6827 | |
6828 __ bind(&done); | |
6829 } | |
6830 | |
6763 | 6831 |
6764 void FloatingPointHelper::LoadFloatOperand(MacroAssembler* masm, | 6832 void FloatingPointHelper::LoadFloatOperand(MacroAssembler* masm, |
6765 Register src, | 6833 Register src, |
6766 XMMRegister dst) { | 6834 XMMRegister dst) { |
6767 Label load_smi, done; | 6835 Label load_smi, done; |
6768 | 6836 |
6769 __ testl(src, Immediate(kSmiTagMask)); | 6837 __ testl(src, Immediate(kSmiTagMask)); |
6770 __ j(zero, &load_smi); | 6838 __ j(zero, &load_smi); |
6771 __ movsd(dst, FieldOperand(src, HeapNumber::kValueOffset)); | 6839 __ movsd(dst, FieldOperand(src, HeapNumber::kValueOffset)); |
6772 __ jmp(&done); | 6840 __ jmp(&done); |
(...skipping 508 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
7281 int CompareStub::MinorKey() { | 7349 int CompareStub::MinorKey() { |
7282 // Encode the two parameters in a unique 16 bit value. | 7350 // Encode the two parameters in a unique 16 bit value. |
7283 ASSERT(static_cast<unsigned>(cc_) < (1 << 15)); | 7351 ASSERT(static_cast<unsigned>(cc_) < (1 << 15)); |
7284 return (static_cast<unsigned>(cc_) << 1) | (strict_ ? 1 : 0); | 7352 return (static_cast<unsigned>(cc_) << 1) | (strict_ ? 1 : 0); |
7285 } | 7353 } |
7286 | 7354 |
7287 | 7355 |
7288 #undef __ | 7356 #undef __ |
7289 | 7357 |
7290 } } // namespace v8::internal | 7358 } } // namespace v8::internal |
OLD | NEW |