Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(107)

Side by Side Diff: src/x64/codegen-x64.cc

Issue 164056: X64: Implement inline trigonometric operations. (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: Created 11 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698