Chromium Code Reviews| 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 |