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

Side by Side Diff: src/ia32/lithium-codegen-ia32.cc

Issue 12391055: Cleaned up CpuFeature scope handling. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Fixed nits Created 7 years, 9 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 | « src/ia32/full-codegen-ia32.cc ('k') | src/ia32/lithium-gap-resolver-ia32.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 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 242 matching lines...) Expand 10 before | Expand all | Expand 10 after
253 if (dynamic_frame_alignment_) { 253 if (dynamic_frame_alignment_) {
254 __ mov(Operand(ebp, offset), edx); 254 __ mov(Operand(ebp, offset), edx);
255 } else { 255 } else {
256 __ mov(Operand(ebp, offset), Immediate(kNoAlignmentPadding)); 256 __ mov(Operand(ebp, offset), Immediate(kNoAlignmentPadding));
257 } 257 }
258 } 258 }
259 } 259 }
260 260
261 if (info()->saves_caller_doubles() && CpuFeatures::IsSupported(SSE2)) { 261 if (info()->saves_caller_doubles() && CpuFeatures::IsSupported(SSE2)) {
262 Comment(";;; Save clobbered callee double registers"); 262 Comment(";;; Save clobbered callee double registers");
263 CpuFeatures::Scope scope(SSE2); 263 CpuFeatureScope scope(masm(), SSE2);
264 int count = 0; 264 int count = 0;
265 BitVector* doubles = chunk()->allocated_double_registers(); 265 BitVector* doubles = chunk()->allocated_double_registers();
266 BitVector::Iterator save_iterator(doubles); 266 BitVector::Iterator save_iterator(doubles);
267 while (!save_iterator.Done()) { 267 while (!save_iterator.Done()) {
268 __ movdbl(MemOperand(esp, count * kDoubleSize), 268 __ movdbl(MemOperand(esp, count * kDoubleSize),
269 XMMRegister::FromAllocationIndex(save_iterator.Current())); 269 XMMRegister::FromAllocationIndex(save_iterator.Current()));
270 save_iterator.Advance(); 270 save_iterator.Advance();
271 count++; 271 count++;
272 } 272 }
273 } 273 }
(...skipping 1414 matching lines...) Expand 10 before | Expand all | Expand 10 after
1688 // Use xor to produce +0.0 in a fast and compact way, but avoid to 1688 // Use xor to produce +0.0 in a fast and compact way, but avoid to
1689 // do so if the constant is -0.0. 1689 // do so if the constant is -0.0.
1690 if (BitCast<uint64_t, double>(v) == 0) { 1690 if (BitCast<uint64_t, double>(v) == 0) {
1691 __ xorps(res, res); 1691 __ xorps(res, res);
1692 } else { 1692 } else {
1693 Register temp = ToRegister(instr->temp()); 1693 Register temp = ToRegister(instr->temp());
1694 uint64_t int_val = BitCast<uint64_t, double>(v); 1694 uint64_t int_val = BitCast<uint64_t, double>(v);
1695 int32_t lower = static_cast<int32_t>(int_val); 1695 int32_t lower = static_cast<int32_t>(int_val);
1696 int32_t upper = static_cast<int32_t>(int_val >> (kBitsPerInt)); 1696 int32_t upper = static_cast<int32_t>(int_val >> (kBitsPerInt));
1697 if (CpuFeatures::IsSupported(SSE4_1)) { 1697 if (CpuFeatures::IsSupported(SSE4_1)) {
1698 CpuFeatures::Scope scope1(SSE2); 1698 CpuFeatureScope scope1(masm(), SSE2);
1699 CpuFeatures::Scope scope2(SSE4_1); 1699 CpuFeatureScope scope2(masm(), SSE4_1);
1700 if (lower != 0) { 1700 if (lower != 0) {
1701 __ Set(temp, Immediate(lower)); 1701 __ Set(temp, Immediate(lower));
1702 __ movd(res, Operand(temp)); 1702 __ movd(res, Operand(temp));
1703 __ Set(temp, Immediate(upper)); 1703 __ Set(temp, Immediate(upper));
1704 __ pinsrd(res, Operand(temp), 1); 1704 __ pinsrd(res, Operand(temp), 1);
1705 } else { 1705 } else {
1706 __ xorps(res, res); 1706 __ xorps(res, res);
1707 __ Set(temp, Immediate(upper)); 1707 __ Set(temp, Immediate(upper));
1708 __ pinsrd(res, Operand(temp), 1); 1708 __ pinsrd(res, Operand(temp), 1);
1709 } 1709 }
1710 } else { 1710 } else {
1711 CpuFeatures::Scope scope(SSE2); 1711 CpuFeatureScope scope(masm(), SSE2);
1712 __ Set(temp, Immediate(upper)); 1712 __ Set(temp, Immediate(upper));
1713 __ movd(res, Operand(temp)); 1713 __ movd(res, Operand(temp));
1714 __ psllq(res, 32); 1714 __ psllq(res, 32);
1715 if (lower != 0) { 1715 if (lower != 0) {
1716 __ Set(temp, Immediate(lower)); 1716 __ Set(temp, Immediate(lower));
1717 __ movd(xmm0, Operand(temp)); 1717 __ movd(xmm0, Operand(temp));
1718 __ por(res, xmm0); 1718 __ por(res, xmm0);
1719 } 1719 }
1720 } 1720 }
1721 } 1721 }
(...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after
1864 __ add(ToRegister(left), ToOperand(right)); 1864 __ add(ToRegister(left), ToOperand(right));
1865 } 1865 }
1866 1866
1867 if (instr->hydrogen()->CheckFlag(HValue::kCanOverflow)) { 1867 if (instr->hydrogen()->CheckFlag(HValue::kCanOverflow)) {
1868 DeoptimizeIf(overflow, instr->environment()); 1868 DeoptimizeIf(overflow, instr->environment());
1869 } 1869 }
1870 } 1870 }
1871 1871
1872 1872
1873 void LCodeGen::DoMathMinMax(LMathMinMax* instr) { 1873 void LCodeGen::DoMathMinMax(LMathMinMax* instr) {
1874 CpuFeatures::Scope scope(SSE2); 1874 CpuFeatureScope scope(masm(), SSE2);
1875 LOperand* left = instr->left(); 1875 LOperand* left = instr->left();
1876 LOperand* right = instr->right(); 1876 LOperand* right = instr->right();
1877 ASSERT(left->Equals(instr->result())); 1877 ASSERT(left->Equals(instr->result()));
1878 HMathMinMax::Operation operation = instr->hydrogen()->operation(); 1878 HMathMinMax::Operation operation = instr->hydrogen()->operation();
1879 if (instr->hydrogen()->representation().IsInteger32()) { 1879 if (instr->hydrogen()->representation().IsInteger32()) {
1880 Label return_left; 1880 Label return_left;
1881 Condition condition = (operation == HMathMinMax::kMathMin) 1881 Condition condition = (operation == HMathMinMax::kMathMin)
1882 ? less_equal 1882 ? less_equal
1883 : greater_equal; 1883 : greater_equal;
1884 if (right->IsConstantOperand()) { 1884 if (right->IsConstantOperand()) {
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
1926 __ j(parity_even, &return_left, Label::kNear); // left == NaN. 1926 __ j(parity_even, &return_left, Label::kNear); // left == NaN.
1927 __ bind(&return_right); 1927 __ bind(&return_right);
1928 __ movsd(left_reg, right_reg); 1928 __ movsd(left_reg, right_reg);
1929 1929
1930 __ bind(&return_left); 1930 __ bind(&return_left);
1931 } 1931 }
1932 } 1932 }
1933 1933
1934 1934
1935 void LCodeGen::DoArithmeticD(LArithmeticD* instr) { 1935 void LCodeGen::DoArithmeticD(LArithmeticD* instr) {
1936 CpuFeatures::Scope scope(SSE2); 1936 CpuFeatureScope scope(masm(), SSE2);
1937 XMMRegister left = ToDoubleRegister(instr->left()); 1937 XMMRegister left = ToDoubleRegister(instr->left());
1938 XMMRegister right = ToDoubleRegister(instr->right()); 1938 XMMRegister right = ToDoubleRegister(instr->right());
1939 XMMRegister result = ToDoubleRegister(instr->result()); 1939 XMMRegister result = ToDoubleRegister(instr->result());
1940 // Modulo uses a fixed result register. 1940 // Modulo uses a fixed result register.
1941 ASSERT(instr->op() == Token::MOD || left.is(result)); 1941 ASSERT(instr->op() == Token::MOD || left.is(result));
1942 switch (instr->op()) { 1942 switch (instr->op()) {
1943 case Token::ADD: 1943 case Token::ADD:
1944 __ addsd(left, right); 1944 __ addsd(left, right);
1945 break; 1945 break;
1946 case Token::SUB: 1946 case Token::SUB:
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
2011 } else { 2011 } else {
2012 __ j(cc, chunk_->GetAssemblyLabel(left_block)); 2012 __ j(cc, chunk_->GetAssemblyLabel(left_block));
2013 __ jmp(chunk_->GetAssemblyLabel(right_block)); 2013 __ jmp(chunk_->GetAssemblyLabel(right_block));
2014 } 2014 }
2015 } 2015 }
2016 2016
2017 2017
2018 void LCodeGen::DoBranch(LBranch* instr) { 2018 void LCodeGen::DoBranch(LBranch* instr) {
2019 int true_block = chunk_->LookupDestination(instr->true_block_id()); 2019 int true_block = chunk_->LookupDestination(instr->true_block_id());
2020 int false_block = chunk_->LookupDestination(instr->false_block_id()); 2020 int false_block = chunk_->LookupDestination(instr->false_block_id());
2021 CpuFeatures::Scope scope(SSE2); 2021 CpuFeatureScope scope(masm(), SSE2);
2022 2022
2023 Representation r = instr->hydrogen()->value()->representation(); 2023 Representation r = instr->hydrogen()->value()->representation();
2024 if (r.IsInteger32()) { 2024 if (r.IsInteger32()) {
2025 Register reg = ToRegister(instr->value()); 2025 Register reg = ToRegister(instr->value());
2026 __ test(reg, Operand(reg)); 2026 __ test(reg, Operand(reg));
2027 EmitBranch(true_block, false_block, not_zero); 2027 EmitBranch(true_block, false_block, not_zero);
2028 } else if (r.IsDouble()) { 2028 } else if (r.IsDouble()) {
2029 XMMRegister reg = ToDoubleRegister(instr->value()); 2029 XMMRegister reg = ToDoubleRegister(instr->value());
2030 __ xorps(xmm0, xmm0); 2030 __ xorps(xmm0, xmm0);
2031 __ ucomisd(reg, xmm0); 2031 __ ucomisd(reg, xmm0);
(...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after
2181 if (left->IsConstantOperand() && right->IsConstantOperand()) { 2181 if (left->IsConstantOperand() && right->IsConstantOperand()) {
2182 // We can statically evaluate the comparison. 2182 // We can statically evaluate the comparison.
2183 double left_val = ToDouble(LConstantOperand::cast(left)); 2183 double left_val = ToDouble(LConstantOperand::cast(left));
2184 double right_val = ToDouble(LConstantOperand::cast(right)); 2184 double right_val = ToDouble(LConstantOperand::cast(right));
2185 int next_block = 2185 int next_block =
2186 EvalComparison(instr->op(), left_val, right_val) ? true_block 2186 EvalComparison(instr->op(), left_val, right_val) ? true_block
2187 : false_block; 2187 : false_block;
2188 EmitGoto(next_block); 2188 EmitGoto(next_block);
2189 } else { 2189 } else {
2190 if (instr->is_double()) { 2190 if (instr->is_double()) {
2191 CpuFeatures::Scope scope(SSE2); 2191 CpuFeatureScope scope(masm(), SSE2);
2192 // Don't base result on EFLAGS when a NaN is involved. Instead 2192 // Don't base result on EFLAGS when a NaN is involved. Instead
2193 // jump to the false block. 2193 // jump to the false block.
2194 __ ucomisd(ToDoubleRegister(left), ToDoubleRegister(right)); 2194 __ ucomisd(ToDoubleRegister(left), ToDoubleRegister(right));
2195 __ j(parity_even, chunk_->GetAssemblyLabel(false_block)); 2195 __ j(parity_even, chunk_->GetAssemblyLabel(false_block));
2196 } else { 2196 } else {
2197 if (right->IsConstantOperand()) { 2197 if (right->IsConstantOperand()) {
2198 __ cmp(ToRegister(left), ToInteger32Immediate(right)); 2198 __ cmp(ToRegister(left), ToInteger32Immediate(right));
2199 } else if (left->IsConstantOperand()) { 2199 } else if (left->IsConstantOperand()) {
2200 __ cmp(ToOperand(right), ToInteger32Immediate(left)); 2200 __ cmp(ToOperand(right), ToInteger32Immediate(left));
2201 // We transposed the operands. Reverse the condition. 2201 // We transposed the operands. Reverse the condition.
(...skipping 497 matching lines...) Expand 10 before | Expand all | Expand 10 after
2699 // Preserve the return value on the stack and rely on the runtime call 2699 // Preserve the return value on the stack and rely on the runtime call
2700 // to return the value in the same register. We're leaving the code 2700 // to return the value in the same register. We're leaving the code
2701 // managed by the register allocator and tearing down the frame, it's 2701 // managed by the register allocator and tearing down the frame, it's
2702 // safe to write to the context register. 2702 // safe to write to the context register.
2703 __ push(eax); 2703 __ push(eax);
2704 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); 2704 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset));
2705 __ CallRuntime(Runtime::kTraceExit, 1); 2705 __ CallRuntime(Runtime::kTraceExit, 1);
2706 } 2706 }
2707 if (info()->saves_caller_doubles() && CpuFeatures::IsSupported(SSE2)) { 2707 if (info()->saves_caller_doubles() && CpuFeatures::IsSupported(SSE2)) {
2708 ASSERT(NeedsEagerFrame()); 2708 ASSERT(NeedsEagerFrame());
2709 CpuFeatures::Scope scope(SSE2); 2709 CpuFeatureScope scope(masm(), SSE2);
2710 BitVector* doubles = chunk()->allocated_double_registers(); 2710 BitVector* doubles = chunk()->allocated_double_registers();
2711 BitVector::Iterator save_iterator(doubles); 2711 BitVector::Iterator save_iterator(doubles);
2712 int count = 0; 2712 int count = 0;
2713 while (!save_iterator.Done()) { 2713 while (!save_iterator.Done()) {
2714 __ movdbl(XMMRegister::FromAllocationIndex(save_iterator.Current()), 2714 __ movdbl(XMMRegister::FromAllocationIndex(save_iterator.Current()),
2715 MemOperand(esp, count * kDoubleSize)); 2715 MemOperand(esp, count * kDoubleSize));
2716 save_iterator.Advance(); 2716 save_iterator.Advance();
2717 count++; 2717 count++;
2718 } 2718 }
2719 } 2719 }
(...skipping 392 matching lines...) Expand 10 before | Expand all | Expand 10 after
3112 } 3112 }
3113 Operand operand(BuildFastArrayOperand( 3113 Operand operand(BuildFastArrayOperand(
3114 instr->elements(), 3114 instr->elements(),
3115 key, 3115 key,
3116 instr->hydrogen()->key()->representation(), 3116 instr->hydrogen()->key()->representation(),
3117 elements_kind, 3117 elements_kind,
3118 0, 3118 0,
3119 instr->additional_index())); 3119 instr->additional_index()));
3120 if (elements_kind == EXTERNAL_FLOAT_ELEMENTS) { 3120 if (elements_kind == EXTERNAL_FLOAT_ELEMENTS) {
3121 if (CpuFeatures::IsSupported(SSE2)) { 3121 if (CpuFeatures::IsSupported(SSE2)) {
3122 CpuFeatures::Scope scope(SSE2); 3122 CpuFeatureScope scope(masm(), SSE2);
3123 XMMRegister result(ToDoubleRegister(instr->result())); 3123 XMMRegister result(ToDoubleRegister(instr->result()));
3124 __ movss(result, operand); 3124 __ movss(result, operand);
3125 __ cvtss2sd(result, result); 3125 __ cvtss2sd(result, result);
3126 } else { 3126 } else {
3127 __ fld_s(operand); 3127 __ fld_s(operand);
3128 HandleX87FPReturnValue(instr); 3128 HandleX87FPReturnValue(instr);
3129 } 3129 }
3130 } else if (elements_kind == EXTERNAL_DOUBLE_ELEMENTS) { 3130 } else if (elements_kind == EXTERNAL_DOUBLE_ELEMENTS) {
3131 if (CpuFeatures::IsSupported(SSE2)) { 3131 if (CpuFeatures::IsSupported(SSE2)) {
3132 CpuFeatures::Scope scope(SSE2); 3132 CpuFeatureScope scope(masm(), SSE2);
3133 __ movdbl(ToDoubleRegister(instr->result()), operand); 3133 __ movdbl(ToDoubleRegister(instr->result()), operand);
3134 } else { 3134 } else {
3135 __ fld_d(operand); 3135 __ fld_d(operand);
3136 HandleX87FPReturnValue(instr); 3136 HandleX87FPReturnValue(instr);
3137 } 3137 }
3138 } else { 3138 } else {
3139 Register result(ToRegister(instr->result())); 3139 Register result(ToRegister(instr->result()));
3140 switch (elements_kind) { 3140 switch (elements_kind) {
3141 case EXTERNAL_BYTE_ELEMENTS: 3141 case EXTERNAL_BYTE_ELEMENTS:
3142 __ movsx_b(result, operand); 3142 __ movsx_b(result, operand);
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
3216 } 3216 }
3217 3217
3218 Operand double_load_operand = BuildFastArrayOperand( 3218 Operand double_load_operand = BuildFastArrayOperand(
3219 instr->elements(), 3219 instr->elements(),
3220 instr->key(), 3220 instr->key(),
3221 instr->hydrogen()->key()->representation(), 3221 instr->hydrogen()->key()->representation(),
3222 FAST_DOUBLE_ELEMENTS, 3222 FAST_DOUBLE_ELEMENTS,
3223 FixedDoubleArray::kHeaderSize - kHeapObjectTag, 3223 FixedDoubleArray::kHeaderSize - kHeapObjectTag,
3224 instr->additional_index()); 3224 instr->additional_index());
3225 if (CpuFeatures::IsSupported(SSE2)) { 3225 if (CpuFeatures::IsSupported(SSE2)) {
3226 CpuFeatures::Scope scope(SSE2); 3226 CpuFeatureScope scope(masm(), SSE2);
3227 XMMRegister result = ToDoubleRegister(instr->result()); 3227 XMMRegister result = ToDoubleRegister(instr->result());
3228 __ movdbl(result, double_load_operand); 3228 __ movdbl(result, double_load_operand);
3229 } else { 3229 } else {
3230 __ fld_d(double_load_operand); 3230 __ fld_d(double_load_operand);
3231 HandleX87FPReturnValue(instr); 3231 HandleX87FPReturnValue(instr);
3232 } 3232 }
3233 } 3233 }
3234 3234
3235 3235
3236 void LCodeGen::DoLoadKeyedFixedArray(LLoadKeyed* instr) { 3236 void LCodeGen::DoLoadKeyedFixedArray(LLoadKeyed* instr) {
(...skipping 403 matching lines...) Expand 10 before | Expand all | Expand 10 after
3640 codegen()->DoDeferredMathAbsTaggedHeapNumber(instr_); 3640 codegen()->DoDeferredMathAbsTaggedHeapNumber(instr_);
3641 } 3641 }
3642 virtual LInstruction* instr() { return instr_; } 3642 virtual LInstruction* instr() { return instr_; }
3643 private: 3643 private:
3644 LUnaryMathOperation* instr_; 3644 LUnaryMathOperation* instr_;
3645 }; 3645 };
3646 3646
3647 ASSERT(instr->value()->Equals(instr->result())); 3647 ASSERT(instr->value()->Equals(instr->result()));
3648 Representation r = instr->hydrogen()->value()->representation(); 3648 Representation r = instr->hydrogen()->value()->representation();
3649 3649
3650 CpuFeatures::Scope scope(SSE2); 3650 CpuFeatureScope scope(masm(), SSE2);
3651 if (r.IsDouble()) { 3651 if (r.IsDouble()) {
3652 XMMRegister scratch = xmm0; 3652 XMMRegister scratch = xmm0;
3653 XMMRegister input_reg = ToDoubleRegister(instr->value()); 3653 XMMRegister input_reg = ToDoubleRegister(instr->value());
3654 __ xorps(scratch, scratch); 3654 __ xorps(scratch, scratch);
3655 __ subsd(scratch, input_reg); 3655 __ subsd(scratch, input_reg);
3656 __ pand(input_reg, scratch); 3656 __ pand(input_reg, scratch);
3657 } else if (r.IsInteger32()) { 3657 } else if (r.IsInteger32()) {
3658 EmitIntegerMathAbs(instr); 3658 EmitIntegerMathAbs(instr);
3659 } else { // Tagged case. 3659 } else { // Tagged case.
3660 DeferredMathAbsTaggedHeapNumber* deferred = 3660 DeferredMathAbsTaggedHeapNumber* deferred =
3661 new(zone()) DeferredMathAbsTaggedHeapNumber(this, instr); 3661 new(zone()) DeferredMathAbsTaggedHeapNumber(this, instr);
3662 Register input_reg = ToRegister(instr->value()); 3662 Register input_reg = ToRegister(instr->value());
3663 // Smi check. 3663 // Smi check.
3664 __ JumpIfNotSmi(input_reg, deferred->entry()); 3664 __ JumpIfNotSmi(input_reg, deferred->entry());
3665 EmitIntegerMathAbs(instr); 3665 EmitIntegerMathAbs(instr);
3666 __ bind(deferred->exit()); 3666 __ bind(deferred->exit());
3667 } 3667 }
3668 } 3668 }
3669 3669
3670 3670
3671 void LCodeGen::DoMathFloor(LUnaryMathOperation* instr) { 3671 void LCodeGen::DoMathFloor(LUnaryMathOperation* instr) {
3672 CpuFeatures::Scope scope(SSE2); 3672 CpuFeatureScope scope(masm(), SSE2);
3673 XMMRegister xmm_scratch = xmm0; 3673 XMMRegister xmm_scratch = xmm0;
3674 Register output_reg = ToRegister(instr->result()); 3674 Register output_reg = ToRegister(instr->result());
3675 XMMRegister input_reg = ToDoubleRegister(instr->value()); 3675 XMMRegister input_reg = ToDoubleRegister(instr->value());
3676 3676
3677 if (CpuFeatures::IsSupported(SSE4_1)) { 3677 if (CpuFeatures::IsSupported(SSE4_1)) {
3678 CpuFeatures::Scope scope(SSE4_1); 3678 CpuFeatureScope scope(masm(), SSE4_1);
3679 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { 3679 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
3680 // Deoptimize on negative zero. 3680 // Deoptimize on negative zero.
3681 Label non_zero; 3681 Label non_zero;
3682 __ xorps(xmm_scratch, xmm_scratch); // Zero the register. 3682 __ xorps(xmm_scratch, xmm_scratch); // Zero the register.
3683 __ ucomisd(input_reg, xmm_scratch); 3683 __ ucomisd(input_reg, xmm_scratch);
3684 __ j(not_equal, &non_zero, Label::kNear); 3684 __ j(not_equal, &non_zero, Label::kNear);
3685 __ movmskpd(output_reg, input_reg); 3685 __ movmskpd(output_reg, input_reg);
3686 __ test(output_reg, Immediate(1)); 3686 __ test(output_reg, Immediate(1));
3687 DeoptimizeIf(not_zero, instr->environment()); 3687 DeoptimizeIf(not_zero, instr->environment());
3688 __ bind(&non_zero); 3688 __ bind(&non_zero);
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
3727 __ ucomisd(input_reg, xmm_scratch); 3727 __ ucomisd(input_reg, xmm_scratch);
3728 __ j(equal, &done, Label::kNear); 3728 __ j(equal, &done, Label::kNear);
3729 __ sub(output_reg, Immediate(1)); 3729 __ sub(output_reg, Immediate(1));
3730 DeoptimizeIf(overflow, instr->environment()); 3730 DeoptimizeIf(overflow, instr->environment());
3731 3731
3732 __ bind(&done); 3732 __ bind(&done);
3733 } 3733 }
3734 } 3734 }
3735 3735
3736 void LCodeGen::DoMathRound(LMathRound* instr) { 3736 void LCodeGen::DoMathRound(LMathRound* instr) {
3737 CpuFeatures::Scope scope(SSE2); 3737 CpuFeatureScope scope(masm(), SSE2);
3738 Register output_reg = ToRegister(instr->result()); 3738 Register output_reg = ToRegister(instr->result());
3739 XMMRegister input_reg = ToDoubleRegister(instr->value()); 3739 XMMRegister input_reg = ToDoubleRegister(instr->value());
3740 XMMRegister xmm_scratch = xmm0; 3740 XMMRegister xmm_scratch = xmm0;
3741 XMMRegister input_temp = ToDoubleRegister(instr->temp()); 3741 XMMRegister input_temp = ToDoubleRegister(instr->temp());
3742 ExternalReference one_half = ExternalReference::address_of_one_half(); 3742 ExternalReference one_half = ExternalReference::address_of_one_half();
3743 ExternalReference minus_one_half = 3743 ExternalReference minus_one_half =
3744 ExternalReference::address_of_minus_one_half(); 3744 ExternalReference::address_of_minus_one_half();
3745 3745
3746 Label done, round_to_zero, below_one_half, do_not_compensate; 3746 Label done, round_to_zero, below_one_half, do_not_compensate;
3747 __ movdbl(xmm_scratch, Operand::StaticVariable(one_half)); 3747 __ movdbl(xmm_scratch, Operand::StaticVariable(one_half));
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
3788 __ test(output_reg, Immediate(1)); 3788 __ test(output_reg, Immediate(1));
3789 __ RecordComment("Minus zero"); 3789 __ RecordComment("Minus zero");
3790 DeoptimizeIf(not_zero, instr->environment()); 3790 DeoptimizeIf(not_zero, instr->environment());
3791 } 3791 }
3792 __ Set(output_reg, Immediate(0)); 3792 __ Set(output_reg, Immediate(0));
3793 __ bind(&done); 3793 __ bind(&done);
3794 } 3794 }
3795 3795
3796 3796
3797 void LCodeGen::DoMathSqrt(LUnaryMathOperation* instr) { 3797 void LCodeGen::DoMathSqrt(LUnaryMathOperation* instr) {
3798 CpuFeatures::Scope scope(SSE2); 3798 CpuFeatureScope scope(masm(), SSE2);
3799 XMMRegister input_reg = ToDoubleRegister(instr->value()); 3799 XMMRegister input_reg = ToDoubleRegister(instr->value());
3800 ASSERT(ToDoubleRegister(instr->result()).is(input_reg)); 3800 ASSERT(ToDoubleRegister(instr->result()).is(input_reg));
3801 __ sqrtsd(input_reg, input_reg); 3801 __ sqrtsd(input_reg, input_reg);
3802 } 3802 }
3803 3803
3804 3804
3805 void LCodeGen::DoMathPowHalf(LMathPowHalf* instr) { 3805 void LCodeGen::DoMathPowHalf(LMathPowHalf* instr) {
3806 CpuFeatures::Scope scope(SSE2); 3806 CpuFeatureScope scope(masm(), SSE2);
3807 XMMRegister xmm_scratch = xmm0; 3807 XMMRegister xmm_scratch = xmm0;
3808 XMMRegister input_reg = ToDoubleRegister(instr->value()); 3808 XMMRegister input_reg = ToDoubleRegister(instr->value());
3809 Register scratch = ToRegister(instr->temp()); 3809 Register scratch = ToRegister(instr->temp());
3810 ASSERT(ToDoubleRegister(instr->result()).is(input_reg)); 3810 ASSERT(ToDoubleRegister(instr->result()).is(input_reg));
3811 3811
3812 // Note that according to ECMA-262 15.8.2.13: 3812 // Note that according to ECMA-262 15.8.2.13:
3813 // Math.pow(-Infinity, 0.5) == Infinity 3813 // Math.pow(-Infinity, 0.5) == Infinity
3814 // Math.sqrt(-Infinity) == NaN 3814 // Math.sqrt(-Infinity) == NaN
3815 Label done, sqrt; 3815 Label done, sqrt;
3816 // Check base for -Infinity. According to IEEE-754, single-precision 3816 // Check base for -Infinity. According to IEEE-754, single-precision
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
3873 DeferredDoRandom(LCodeGen* codegen, LRandom* instr) 3873 DeferredDoRandom(LCodeGen* codegen, LRandom* instr)
3874 : LDeferredCode(codegen), instr_(instr) { } 3874 : LDeferredCode(codegen), instr_(instr) { }
3875 virtual void Generate() { codegen()->DoDeferredRandom(instr_); } 3875 virtual void Generate() { codegen()->DoDeferredRandom(instr_); }
3876 virtual LInstruction* instr() { return instr_; } 3876 virtual LInstruction* instr() { return instr_; }
3877 private: 3877 private:
3878 LRandom* instr_; 3878 LRandom* instr_;
3879 }; 3879 };
3880 3880
3881 DeferredDoRandom* deferred = new(zone()) DeferredDoRandom(this, instr); 3881 DeferredDoRandom* deferred = new(zone()) DeferredDoRandom(this, instr);
3882 3882
3883 CpuFeatures::Scope scope(SSE2); 3883 CpuFeatureScope scope(masm(), SSE2);
3884 // Having marked this instruction as a call we can use any 3884 // Having marked this instruction as a call we can use any
3885 // registers. 3885 // registers.
3886 ASSERT(ToDoubleRegister(instr->result()).is(xmm1)); 3886 ASSERT(ToDoubleRegister(instr->result()).is(xmm1));
3887 ASSERT(ToRegister(instr->global_object()).is(eax)); 3887 ASSERT(ToRegister(instr->global_object()).is(eax));
3888 // Assert that the register size is indeed the size of each seed. 3888 // Assert that the register size is indeed the size of each seed.
3889 static const int kSeedSize = sizeof(uint32_t); 3889 static const int kSeedSize = sizeof(uint32_t);
3890 STATIC_ASSERT(kPointerSize == kSeedSize); 3890 STATIC_ASSERT(kPointerSize == kSeedSize);
3891 3891
3892 __ mov(eax, FieldOperand(eax, GlobalObject::kNativeContextOffset)); 3892 __ mov(eax, FieldOperand(eax, GlobalObject::kNativeContextOffset));
3893 static const int kRandomSeedOffset = 3893 static const int kRandomSeedOffset =
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
3941 3941
3942 void LCodeGen::DoDeferredRandom(LRandom* instr) { 3942 void LCodeGen::DoDeferredRandom(LRandom* instr) {
3943 __ PrepareCallCFunction(1, ebx); 3943 __ PrepareCallCFunction(1, ebx);
3944 __ mov(Operand(esp, 0), eax); 3944 __ mov(Operand(esp, 0), eax);
3945 __ CallCFunction(ExternalReference::random_uint32_function(isolate()), 1); 3945 __ CallCFunction(ExternalReference::random_uint32_function(isolate()), 1);
3946 // Return value is in eax. 3946 // Return value is in eax.
3947 } 3947 }
3948 3948
3949 3949
3950 void LCodeGen::DoMathLog(LUnaryMathOperation* instr) { 3950 void LCodeGen::DoMathLog(LUnaryMathOperation* instr) {
3951 CpuFeatures::Scope scope(SSE2); 3951 CpuFeatureScope scope(masm(), SSE2);
3952 ASSERT(instr->value()->Equals(instr->result())); 3952 ASSERT(instr->value()->Equals(instr->result()));
3953 XMMRegister input_reg = ToDoubleRegister(instr->value()); 3953 XMMRegister input_reg = ToDoubleRegister(instr->value());
3954 Label positive, done, zero; 3954 Label positive, done, zero;
3955 __ xorps(xmm0, xmm0); 3955 __ xorps(xmm0, xmm0);
3956 __ ucomisd(input_reg, xmm0); 3956 __ ucomisd(input_reg, xmm0);
3957 __ j(above, &positive, Label::kNear); 3957 __ j(above, &positive, Label::kNear);
3958 __ j(equal, &zero, Label::kNear); 3958 __ j(equal, &zero, Label::kNear);
3959 ExternalReference nan = 3959 ExternalReference nan =
3960 ExternalReference::address_of_canonical_non_hole_nan(); 3960 ExternalReference::address_of_canonical_non_hole_nan();
3961 __ movdbl(input_reg, Operand::StaticVariable(nan)); 3961 __ movdbl(input_reg, Operand::StaticVariable(nan));
(...skipping 11 matching lines...) Expand all
3973 __ fld_d(Operand(esp, 0)); 3973 __ fld_d(Operand(esp, 0));
3974 __ fyl2x(); 3974 __ fyl2x();
3975 __ fstp_d(Operand(esp, 0)); 3975 __ fstp_d(Operand(esp, 0));
3976 __ movdbl(input_reg, Operand(esp, 0)); 3976 __ movdbl(input_reg, Operand(esp, 0));
3977 __ add(Operand(esp), Immediate(kDoubleSize)); 3977 __ add(Operand(esp), Immediate(kDoubleSize));
3978 __ bind(&done); 3978 __ bind(&done);
3979 } 3979 }
3980 3980
3981 3981
3982 void LCodeGen::DoMathExp(LMathExp* instr) { 3982 void LCodeGen::DoMathExp(LMathExp* instr) {
3983 CpuFeatures::Scope scope(SSE2); 3983 CpuFeatureScope scope(masm(), SSE2);
3984 XMMRegister input = ToDoubleRegister(instr->value()); 3984 XMMRegister input = ToDoubleRegister(instr->value());
3985 XMMRegister result = ToDoubleRegister(instr->result()); 3985 XMMRegister result = ToDoubleRegister(instr->result());
3986 Register temp1 = ToRegister(instr->temp1()); 3986 Register temp1 = ToRegister(instr->temp1());
3987 Register temp2 = ToRegister(instr->temp2()); 3987 Register temp2 = ToRegister(instr->temp2());
3988 3988
3989 MathExpGenerator::EmitMathExp(masm(), input, result, xmm0, temp1, temp2); 3989 MathExpGenerator::EmitMathExp(masm(), input, result, xmm0, temp1, temp2);
3990 } 3990 }
3991 3991
3992 3992
3993 void LCodeGen::DoMathTan(LUnaryMathOperation* instr) { 3993 void LCodeGen::DoMathTan(LUnaryMathOperation* instr) {
(...skipping 269 matching lines...) Expand 10 before | Expand all | Expand 10 after
4263 __ SmiUntag(ToRegister(key)); 4263 __ SmiUntag(ToRegister(key));
4264 } 4264 }
4265 Operand operand(BuildFastArrayOperand( 4265 Operand operand(BuildFastArrayOperand(
4266 instr->elements(), 4266 instr->elements(),
4267 key, 4267 key,
4268 instr->hydrogen()->key()->representation(), 4268 instr->hydrogen()->key()->representation(),
4269 elements_kind, 4269 elements_kind,
4270 0, 4270 0,
4271 instr->additional_index())); 4271 instr->additional_index()));
4272 if (elements_kind == EXTERNAL_FLOAT_ELEMENTS) { 4272 if (elements_kind == EXTERNAL_FLOAT_ELEMENTS) {
4273 CpuFeatures::Scope scope(SSE2); 4273 CpuFeatureScope scope(masm(), SSE2);
4274 __ cvtsd2ss(xmm0, ToDoubleRegister(instr->value())); 4274 __ cvtsd2ss(xmm0, ToDoubleRegister(instr->value()));
4275 __ movss(operand, xmm0); 4275 __ movss(operand, xmm0);
4276 } else if (elements_kind == EXTERNAL_DOUBLE_ELEMENTS) { 4276 } else if (elements_kind == EXTERNAL_DOUBLE_ELEMENTS) {
4277 CpuFeatures::Scope scope(SSE2); 4277 CpuFeatureScope scope(masm(), SSE2);
4278 __ movdbl(operand, ToDoubleRegister(instr->value())); 4278 __ movdbl(operand, ToDoubleRegister(instr->value()));
4279 } else { 4279 } else {
4280 Register value = ToRegister(instr->value()); 4280 Register value = ToRegister(instr->value());
4281 switch (elements_kind) { 4281 switch (elements_kind) {
4282 case EXTERNAL_PIXEL_ELEMENTS: 4282 case EXTERNAL_PIXEL_ELEMENTS:
4283 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS: 4283 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS:
4284 case EXTERNAL_BYTE_ELEMENTS: 4284 case EXTERNAL_BYTE_ELEMENTS:
4285 __ mov_b(operand, value); 4285 __ mov_b(operand, value);
4286 break; 4286 break;
4287 case EXTERNAL_SHORT_ELEMENTS: 4287 case EXTERNAL_SHORT_ELEMENTS:
(...skipping 15 matching lines...) Expand all
4303 case DICTIONARY_ELEMENTS: 4303 case DICTIONARY_ELEMENTS:
4304 case NON_STRICT_ARGUMENTS_ELEMENTS: 4304 case NON_STRICT_ARGUMENTS_ELEMENTS:
4305 UNREACHABLE(); 4305 UNREACHABLE();
4306 break; 4306 break;
4307 } 4307 }
4308 } 4308 }
4309 } 4309 }
4310 4310
4311 4311
4312 void LCodeGen::DoStoreKeyedFixedDoubleArray(LStoreKeyed* instr) { 4312 void LCodeGen::DoStoreKeyedFixedDoubleArray(LStoreKeyed* instr) {
4313 CpuFeatures::Scope scope(SSE2); 4313 CpuFeatureScope scope(masm(), SSE2);
4314 XMMRegister value = ToDoubleRegister(instr->value()); 4314 XMMRegister value = ToDoubleRegister(instr->value());
4315 4315
4316 if (instr->NeedsCanonicalization()) { 4316 if (instr->NeedsCanonicalization()) {
4317 Label have_value; 4317 Label have_value;
4318 4318
4319 __ ucomisd(value, value); 4319 __ ucomisd(value, value);
4320 __ j(parity_odd, &have_value); // NaN. 4320 __ j(parity_odd, &have_value); // NaN.
4321 4321
4322 ExternalReference canonical_nan_reference = 4322 ExternalReference canonical_nan_reference =
4323 ExternalReference::address_of_canonical_non_hole_nan(); 4323 ExternalReference::address_of_canonical_non_hole_nan();
(...skipping 254 matching lines...) Expand 10 before | Expand all | Expand 10 after
4578 void LCodeGen::DoStringAdd(LStringAdd* instr) { 4578 void LCodeGen::DoStringAdd(LStringAdd* instr) {
4579 EmitPushTaggedOperand(instr->left()); 4579 EmitPushTaggedOperand(instr->left());
4580 EmitPushTaggedOperand(instr->right()); 4580 EmitPushTaggedOperand(instr->right());
4581 StringAddStub stub(NO_STRING_CHECK_IN_STUB); 4581 StringAddStub stub(NO_STRING_CHECK_IN_STUB);
4582 CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr); 4582 CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr);
4583 } 4583 }
4584 4584
4585 4585
4586 void LCodeGen::DoInteger32ToDouble(LInteger32ToDouble* instr) { 4586 void LCodeGen::DoInteger32ToDouble(LInteger32ToDouble* instr) {
4587 if (CpuFeatures::IsSupported(SSE2)) { 4587 if (CpuFeatures::IsSupported(SSE2)) {
4588 CpuFeatures::Scope scope(SSE2); 4588 CpuFeatureScope scope(masm(), SSE2);
4589 LOperand* input = instr->value(); 4589 LOperand* input = instr->value();
4590 ASSERT(input->IsRegister() || input->IsStackSlot()); 4590 ASSERT(input->IsRegister() || input->IsStackSlot());
4591 LOperand* output = instr->result(); 4591 LOperand* output = instr->result();
4592 ASSERT(output->IsDoubleRegister()); 4592 ASSERT(output->IsDoubleRegister());
4593 __ cvtsi2sd(ToDoubleRegister(output), ToOperand(input)); 4593 __ cvtsi2sd(ToDoubleRegister(output), ToOperand(input));
4594 } else { 4594 } else {
4595 UNREACHABLE(); 4595 UNREACHABLE();
4596 } 4596 }
4597 } 4597 }
4598 4598
4599 4599
4600 void LCodeGen::DoUint32ToDouble(LUint32ToDouble* instr) { 4600 void LCodeGen::DoUint32ToDouble(LUint32ToDouble* instr) {
4601 CpuFeatures::Scope scope(SSE2); 4601 CpuFeatureScope scope(masm(), SSE2);
4602 LOperand* input = instr->value(); 4602 LOperand* input = instr->value();
4603 LOperand* output = instr->result(); 4603 LOperand* output = instr->result();
4604 LOperand* temp = instr->temp(); 4604 LOperand* temp = instr->temp();
4605 4605
4606 __ LoadUint32(ToDoubleRegister(output), 4606 __ LoadUint32(ToDoubleRegister(output),
4607 ToRegister(input), 4607 ToRegister(input),
4608 ToDoubleRegister(temp)); 4608 ToDoubleRegister(temp));
4609 } 4609 }
4610 4610
4611 4611
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
4670 4670
4671 Label done; 4671 Label done;
4672 4672
4673 if (signedness == SIGNED_INT32) { 4673 if (signedness == SIGNED_INT32) {
4674 // There was overflow, so bits 30 and 31 of the original integer 4674 // There was overflow, so bits 30 and 31 of the original integer
4675 // disagree. Try to allocate a heap number in new space and store 4675 // disagree. Try to allocate a heap number in new space and store
4676 // the value in there. If that fails, call the runtime system. 4676 // the value in there. If that fails, call the runtime system.
4677 __ SmiUntag(reg); 4677 __ SmiUntag(reg);
4678 __ xor_(reg, 0x80000000); 4678 __ xor_(reg, 0x80000000);
4679 if (CpuFeatures::IsSupported(SSE2)) { 4679 if (CpuFeatures::IsSupported(SSE2)) {
4680 CpuFeatures::Scope feature_scope(SSE2); 4680 CpuFeatureScope feature_scope(masm(), SSE2);
4681 __ cvtsi2sd(xmm0, Operand(reg)); 4681 __ cvtsi2sd(xmm0, Operand(reg));
4682 } else { 4682 } else {
4683 __ push(reg); 4683 __ push(reg);
4684 __ fild_s(Operand(esp, 0)); 4684 __ fild_s(Operand(esp, 0));
4685 __ pop(reg); 4685 __ pop(reg);
4686 } 4686 }
4687 } else { 4687 } else {
4688 if (CpuFeatures::IsSupported(SSE2)) { 4688 if (CpuFeatures::IsSupported(SSE2)) {
4689 CpuFeatures::Scope feature_scope(SSE2); 4689 CpuFeatureScope feature_scope(masm(), SSE2);
4690 __ LoadUint32(xmm0, reg, xmm1); 4690 __ LoadUint32(xmm0, reg, xmm1);
4691 } else { 4691 } else {
4692 // There's no fild variant for unsigned values, so zero-extend to a 64-bit 4692 // There's no fild variant for unsigned values, so zero-extend to a 64-bit
4693 // int manually. 4693 // int manually.
4694 __ push(Immediate(0)); 4694 __ push(Immediate(0));
4695 __ push(reg); 4695 __ push(reg);
4696 __ fild_d(Operand(esp, 0)); 4696 __ fild_d(Operand(esp, 0));
4697 __ pop(reg); 4697 __ pop(reg);
4698 __ pop(reg); 4698 __ pop(reg);
4699 } 4699 }
(...skipping 19 matching lines...) Expand all
4719 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); 4719 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset));
4720 __ CallRuntimeSaveDoubles(Runtime::kAllocateHeapNumber); 4720 __ CallRuntimeSaveDoubles(Runtime::kAllocateHeapNumber);
4721 RecordSafepointWithRegisters( 4721 RecordSafepointWithRegisters(
4722 instr->pointer_map(), 0, Safepoint::kNoLazyDeopt); 4722 instr->pointer_map(), 0, Safepoint::kNoLazyDeopt);
4723 if (!reg.is(eax)) __ mov(reg, eax); 4723 if (!reg.is(eax)) __ mov(reg, eax);
4724 4724
4725 // Done. Put the value in xmm0 into the value of the allocated heap 4725 // Done. Put the value in xmm0 into the value of the allocated heap
4726 // number. 4726 // number.
4727 __ bind(&done); 4727 __ bind(&done);
4728 if (CpuFeatures::IsSupported(SSE2)) { 4728 if (CpuFeatures::IsSupported(SSE2)) {
4729 CpuFeatures::Scope feature_scope(SSE2); 4729 CpuFeatureScope feature_scope(masm(), SSE2);
4730 __ movdbl(FieldOperand(reg, HeapNumber::kValueOffset), xmm0); 4730 __ movdbl(FieldOperand(reg, HeapNumber::kValueOffset), xmm0);
4731 } else { 4731 } else {
4732 __ fstp_d(FieldOperand(reg, HeapNumber::kValueOffset)); 4732 __ fstp_d(FieldOperand(reg, HeapNumber::kValueOffset));
4733 } 4733 }
4734 __ StoreToSafepointRegisterSlot(reg, reg); 4734 __ StoreToSafepointRegisterSlot(reg, reg);
4735 } 4735 }
4736 4736
4737 4737
4738 void LCodeGen::DoNumberTagD(LNumberTagD* instr) { 4738 void LCodeGen::DoNumberTagD(LNumberTagD* instr) {
4739 class DeferredNumberTagD: public LDeferredCode { 4739 class DeferredNumberTagD: public LDeferredCode {
(...skipping 13 matching lines...) Expand all
4753 if (change_input->IsLoadKeyed()) { 4753 if (change_input->IsLoadKeyed()) {
4754 HLoadKeyed* load = HLoadKeyed::cast(change_input); 4754 HLoadKeyed* load = HLoadKeyed::cast(change_input);
4755 convert_hole = load->UsesMustHandleHole(); 4755 convert_hole = load->UsesMustHandleHole();
4756 } 4756 }
4757 4757
4758 Label no_special_nan_handling; 4758 Label no_special_nan_handling;
4759 Label done; 4759 Label done;
4760 if (convert_hole) { 4760 if (convert_hole) {
4761 bool use_sse2 = CpuFeatures::IsSupported(SSE2); 4761 bool use_sse2 = CpuFeatures::IsSupported(SSE2);
4762 if (use_sse2) { 4762 if (use_sse2) {
4763 CpuFeatures::Scope scope(SSE2); 4763 CpuFeatureScope scope(masm(), SSE2);
4764 XMMRegister input_reg = ToDoubleRegister(instr->value()); 4764 XMMRegister input_reg = ToDoubleRegister(instr->value());
4765 __ ucomisd(input_reg, input_reg); 4765 __ ucomisd(input_reg, input_reg);
4766 } else { 4766 } else {
4767 if (!IsX87TopOfStack(instr->value())) { 4767 if (!IsX87TopOfStack(instr->value())) {
4768 __ fld_d(ToOperand(instr->value())); 4768 __ fld_d(ToOperand(instr->value()));
4769 } 4769 }
4770 __ fld(0); 4770 __ fld(0);
4771 __ fld(0); 4771 __ fld(0);
4772 __ FCmp(); 4772 __ FCmp();
4773 } 4773 }
4774 4774
4775 __ j(parity_odd, &no_special_nan_handling); 4775 __ j(parity_odd, &no_special_nan_handling);
4776 __ sub(esp, Immediate(kDoubleSize)); 4776 __ sub(esp, Immediate(kDoubleSize));
4777 if (use_sse2) { 4777 if (use_sse2) {
4778 CpuFeatures::Scope scope(SSE2); 4778 CpuFeatureScope scope(masm(), SSE2);
4779 XMMRegister input_reg = ToDoubleRegister(instr->value()); 4779 XMMRegister input_reg = ToDoubleRegister(instr->value());
4780 __ movdbl(MemOperand(esp, 0), input_reg); 4780 __ movdbl(MemOperand(esp, 0), input_reg);
4781 } else { 4781 } else {
4782 __ fld(0); 4782 __ fld(0);
4783 __ fstp_d(MemOperand(esp, 0)); 4783 __ fstp_d(MemOperand(esp, 0));
4784 } 4784 }
4785 __ cmp(MemOperand(esp, sizeof(kHoleNanLower32)), 4785 __ cmp(MemOperand(esp, sizeof(kHoleNanLower32)),
4786 Immediate(kHoleNanUpper32)); 4786 Immediate(kHoleNanUpper32));
4787 Label canonicalize; 4787 Label canonicalize;
4788 __ j(not_equal, &canonicalize); 4788 __ j(not_equal, &canonicalize);
4789 __ add(esp, Immediate(kDoubleSize)); 4789 __ add(esp, Immediate(kDoubleSize));
4790 __ mov(reg, factory()->the_hole_value()); 4790 __ mov(reg, factory()->the_hole_value());
4791 __ jmp(&done); 4791 __ jmp(&done);
4792 __ bind(&canonicalize); 4792 __ bind(&canonicalize);
4793 __ add(esp, Immediate(kDoubleSize)); 4793 __ add(esp, Immediate(kDoubleSize));
4794 ExternalReference nan = 4794 ExternalReference nan =
4795 ExternalReference::address_of_canonical_non_hole_nan(); 4795 ExternalReference::address_of_canonical_non_hole_nan();
4796 if (use_sse2) { 4796 if (use_sse2) {
4797 CpuFeatures::Scope scope(SSE2); 4797 CpuFeatureScope scope(masm(), SSE2);
4798 XMMRegister input_reg = ToDoubleRegister(instr->value()); 4798 XMMRegister input_reg = ToDoubleRegister(instr->value());
4799 __ movdbl(input_reg, Operand::StaticVariable(nan)); 4799 __ movdbl(input_reg, Operand::StaticVariable(nan));
4800 } else { 4800 } else {
4801 __ fstp(0); 4801 __ fstp(0);
4802 __ fld_d(Operand::StaticVariable(nan)); 4802 __ fld_d(Operand::StaticVariable(nan));
4803 } 4803 }
4804 } 4804 }
4805 4805
4806 __ bind(&no_special_nan_handling); 4806 __ bind(&no_special_nan_handling);
4807 DeferredNumberTagD* deferred = new(zone()) DeferredNumberTagD(this, instr); 4807 DeferredNumberTagD* deferred = new(zone()) DeferredNumberTagD(this, instr);
4808 if (FLAG_inline_new) { 4808 if (FLAG_inline_new) {
4809 Register tmp = ToRegister(instr->temp()); 4809 Register tmp = ToRegister(instr->temp());
4810 __ AllocateHeapNumber(reg, tmp, no_reg, deferred->entry()); 4810 __ AllocateHeapNumber(reg, tmp, no_reg, deferred->entry());
4811 } else { 4811 } else {
4812 __ jmp(deferred->entry()); 4812 __ jmp(deferred->entry());
4813 } 4813 }
4814 __ bind(deferred->exit()); 4814 __ bind(deferred->exit());
4815 if (CpuFeatures::IsSupported(SSE2)) { 4815 if (CpuFeatures::IsSupported(SSE2)) {
4816 CpuFeatures::Scope scope(SSE2); 4816 CpuFeatureScope scope(masm(), SSE2);
4817 XMMRegister input_reg = ToDoubleRegister(instr->value()); 4817 XMMRegister input_reg = ToDoubleRegister(instr->value());
4818 __ movdbl(FieldOperand(reg, HeapNumber::kValueOffset), input_reg); 4818 __ movdbl(FieldOperand(reg, HeapNumber::kValueOffset), input_reg);
4819 } else { 4819 } else {
4820 if (!IsX87TopOfStack(instr->value())) { 4820 if (!IsX87TopOfStack(instr->value())) {
4821 __ fld_d(ToOperand(instr->value())); 4821 __ fld_d(ToOperand(instr->value()));
4822 } 4822 }
4823 __ fstp_d(FieldOperand(reg, HeapNumber::kValueOffset)); 4823 __ fstp_d(FieldOperand(reg, HeapNumber::kValueOffset));
4824 } 4824 }
4825 __ bind(&done); 4825 __ bind(&done);
4826 } 4826 }
(...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after
4949 // Check for undefined. Undefined is converted to zero for truncating 4949 // Check for undefined. Undefined is converted to zero for truncating
4950 // conversions. 4950 // conversions.
4951 __ cmp(input_reg, factory()->undefined_value()); 4951 __ cmp(input_reg, factory()->undefined_value());
4952 __ RecordComment("Deferred TaggedToI: cannot truncate"); 4952 __ RecordComment("Deferred TaggedToI: cannot truncate");
4953 DeoptimizeIf(not_equal, instr->environment()); 4953 DeoptimizeIf(not_equal, instr->environment());
4954 __ mov(input_reg, 0); 4954 __ mov(input_reg, 0);
4955 __ jmp(&done, Label::kNear); 4955 __ jmp(&done, Label::kNear);
4956 4956
4957 __ bind(&heap_number); 4957 __ bind(&heap_number);
4958 if (CpuFeatures::IsSupported(SSE3)) { 4958 if (CpuFeatures::IsSupported(SSE3)) {
4959 CpuFeatures::Scope scope(SSE3); 4959 CpuFeatureScope scope(masm(), SSE3);
4960 Label convert; 4960 Label convert;
4961 // Use more powerful conversion when sse3 is available. 4961 // Use more powerful conversion when sse3 is available.
4962 // Load x87 register with heap number. 4962 // Load x87 register with heap number.
4963 __ fld_d(FieldOperand(input_reg, HeapNumber::kValueOffset)); 4963 __ fld_d(FieldOperand(input_reg, HeapNumber::kValueOffset));
4964 // Get exponent alone and check for too-big exponent. 4964 // Get exponent alone and check for too-big exponent.
4965 __ mov(input_reg, FieldOperand(input_reg, HeapNumber::kExponentOffset)); 4965 __ mov(input_reg, FieldOperand(input_reg, HeapNumber::kExponentOffset));
4966 __ and_(input_reg, HeapNumber::kExponentMask); 4966 __ and_(input_reg, HeapNumber::kExponentMask);
4967 const uint32_t kTooBigExponent = 4967 const uint32_t kTooBigExponent =
4968 (HeapNumber::kExponentBias + 63) << HeapNumber::kExponentShift; 4968 (HeapNumber::kExponentBias + 63) << HeapNumber::kExponentShift;
4969 __ cmp(Operand(input_reg), Immediate(kTooBigExponent)); 4969 __ cmp(Operand(input_reg), Immediate(kTooBigExponent));
4970 __ j(less, &convert, Label::kNear); 4970 __ j(less, &convert, Label::kNear);
4971 // Pop FPU stack before deoptimizing. 4971 // Pop FPU stack before deoptimizing.
4972 __ fstp(0); 4972 __ fstp(0);
4973 __ RecordComment("Deferred TaggedToI: exponent too big"); 4973 __ RecordComment("Deferred TaggedToI: exponent too big");
4974 DeoptimizeIf(no_condition, instr->environment()); 4974 DeoptimizeIf(no_condition, instr->environment());
4975 4975
4976 // Reserve space for 64 bit answer. 4976 // Reserve space for 64 bit answer.
4977 __ bind(&convert); 4977 __ bind(&convert);
4978 __ sub(Operand(esp), Immediate(kDoubleSize)); 4978 __ sub(Operand(esp), Immediate(kDoubleSize));
4979 // Do conversion, which cannot fail because we checked the exponent. 4979 // Do conversion, which cannot fail because we checked the exponent.
4980 __ fisttp_d(Operand(esp, 0)); 4980 __ fisttp_d(Operand(esp, 0));
4981 __ mov(input_reg, Operand(esp, 0)); // Low word of answer is the result. 4981 __ mov(input_reg, Operand(esp, 0)); // Low word of answer is the result.
4982 __ add(Operand(esp), Immediate(kDoubleSize)); 4982 __ add(Operand(esp), Immediate(kDoubleSize));
4983 } else { 4983 } else {
4984 CpuFeatures::Scope scope(SSE2); 4984 CpuFeatureScope scope(masm(), SSE2);
4985 XMMRegister xmm_temp = ToDoubleRegister(instr->temp()); 4985 XMMRegister xmm_temp = ToDoubleRegister(instr->temp());
4986 __ movdbl(xmm0, FieldOperand(input_reg, HeapNumber::kValueOffset)); 4986 __ movdbl(xmm0, FieldOperand(input_reg, HeapNumber::kValueOffset));
4987 __ cvttsd2si(input_reg, Operand(xmm0)); 4987 __ cvttsd2si(input_reg, Operand(xmm0));
4988 __ cmp(input_reg, 0x80000000u); 4988 __ cmp(input_reg, 0x80000000u);
4989 __ j(not_equal, &done); 4989 __ j(not_equal, &done);
4990 // Check if the input was 0x8000000 (kMinInt). 4990 // Check if the input was 0x8000000 (kMinInt).
4991 // If no, then we got an overflow and we deoptimize. 4991 // If no, then we got an overflow and we deoptimize.
4992 ExternalReference min_int = ExternalReference::address_of_min_int(); 4992 ExternalReference min_int = ExternalReference::address_of_min_int();
4993 __ movdbl(xmm_temp, Operand::StaticVariable(min_int)); 4993 __ movdbl(xmm_temp, Operand::StaticVariable(min_int));
4994 __ ucomisd(xmm_temp, xmm0); 4994 __ ucomisd(xmm_temp, xmm0);
4995 DeoptimizeIf(not_equal, instr->environment()); 4995 DeoptimizeIf(not_equal, instr->environment());
4996 DeoptimizeIf(parity_even, instr->environment()); // NaN. 4996 DeoptimizeIf(parity_even, instr->environment()); // NaN.
4997 } 4997 }
4998 } else if (CpuFeatures::IsSupported(SSE2)) { 4998 } else if (CpuFeatures::IsSupported(SSE2)) {
4999 CpuFeatures::Scope scope(SSE2); 4999 CpuFeatureScope scope(masm(), SSE2);
5000 // Deoptimize if we don't have a heap number. 5000 // Deoptimize if we don't have a heap number.
5001 __ RecordComment("Deferred TaggedToI: not a heap number"); 5001 __ RecordComment("Deferred TaggedToI: not a heap number");
5002 DeoptimizeIf(not_equal, instr->environment()); 5002 DeoptimizeIf(not_equal, instr->environment());
5003 5003
5004 XMMRegister xmm_temp = ToDoubleRegister(instr->temp()); 5004 XMMRegister xmm_temp = ToDoubleRegister(instr->temp());
5005 __ movdbl(xmm0, FieldOperand(input_reg, HeapNumber::kValueOffset)); 5005 __ movdbl(xmm0, FieldOperand(input_reg, HeapNumber::kValueOffset));
5006 __ cvttsd2si(input_reg, Operand(xmm0)); 5006 __ cvttsd2si(input_reg, Operand(xmm0));
5007 __ cvtsi2sd(xmm_temp, Operand(input_reg)); 5007 __ cvtsi2sd(xmm_temp, Operand(input_reg));
5008 __ ucomisd(xmm0, xmm_temp); 5008 __ ucomisd(xmm0, xmm_temp);
5009 __ RecordComment("Deferred TaggedToI: lost precision"); 5009 __ RecordComment("Deferred TaggedToI: lost precision");
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
5056 5056
5057 void LCodeGen::DoNumberUntagD(LNumberUntagD* instr) { 5057 void LCodeGen::DoNumberUntagD(LNumberUntagD* instr) {
5058 LOperand* input = instr->value(); 5058 LOperand* input = instr->value();
5059 ASSERT(input->IsRegister()); 5059 ASSERT(input->IsRegister());
5060 LOperand* temp = instr->temp(); 5060 LOperand* temp = instr->temp();
5061 ASSERT(temp == NULL || temp->IsRegister()); 5061 ASSERT(temp == NULL || temp->IsRegister());
5062 LOperand* result = instr->result(); 5062 LOperand* result = instr->result();
5063 ASSERT(result->IsDoubleRegister()); 5063 ASSERT(result->IsDoubleRegister());
5064 5064
5065 if (CpuFeatures::IsSupported(SSE2)) { 5065 if (CpuFeatures::IsSupported(SSE2)) {
5066 CpuFeatures::Scope scope(SSE2); 5066 CpuFeatureScope scope(masm(), SSE2);
5067 Register input_reg = ToRegister(input); 5067 Register input_reg = ToRegister(input);
5068 XMMRegister result_reg = ToDoubleRegister(result); 5068 XMMRegister result_reg = ToDoubleRegister(result);
5069 5069
5070 bool deoptimize_on_minus_zero = 5070 bool deoptimize_on_minus_zero =
5071 instr->hydrogen()->deoptimize_on_minus_zero(); 5071 instr->hydrogen()->deoptimize_on_minus_zero();
5072 Register temp_reg = deoptimize_on_minus_zero ? ToRegister(temp) : no_reg; 5072 Register temp_reg = deoptimize_on_minus_zero ? ToRegister(temp) : no_reg;
5073 5073
5074 NumberUntagDMode mode = NUMBER_CANDIDATE_IS_ANY_TAGGED; 5074 NumberUntagDMode mode = NUMBER_CANDIDATE_IS_ANY_TAGGED;
5075 HValue* value = instr->hydrogen()->value(); 5075 HValue* value = instr->hydrogen()->value();
5076 if (value->type().IsSmi()) { 5076 if (value->type().IsSmi()) {
(...skipping 22 matching lines...) Expand all
5099 UNIMPLEMENTED(); 5099 UNIMPLEMENTED();
5100 } 5100 }
5101 } 5101 }
5102 5102
5103 5103
5104 void LCodeGen::DoDoubleToI(LDoubleToI* instr) { 5104 void LCodeGen::DoDoubleToI(LDoubleToI* instr) {
5105 LOperand* input = instr->value(); 5105 LOperand* input = instr->value();
5106 ASSERT(input->IsDoubleRegister()); 5106 ASSERT(input->IsDoubleRegister());
5107 LOperand* result = instr->result(); 5107 LOperand* result = instr->result();
5108 ASSERT(result->IsRegister()); 5108 ASSERT(result->IsRegister());
5109 CpuFeatures::Scope scope(SSE2); 5109 CpuFeatureScope scope(masm(), SSE2);
5110 5110
5111 XMMRegister input_reg = ToDoubleRegister(input); 5111 XMMRegister input_reg = ToDoubleRegister(input);
5112 Register result_reg = ToRegister(result); 5112 Register result_reg = ToRegister(result);
5113 5113
5114 if (instr->truncating()) { 5114 if (instr->truncating()) {
5115 // Performs a truncating conversion of a floating point number as used by 5115 // Performs a truncating conversion of a floating point number as used by
5116 // the JS bitwise operations. 5116 // the JS bitwise operations.
5117 __ cvttsd2si(result_reg, Operand(input_reg)); 5117 __ cvttsd2si(result_reg, Operand(input_reg));
5118 __ cmp(result_reg, 0x80000000u); 5118 __ cmp(result_reg, 0x80000000u);
5119 if (CpuFeatures::IsSupported(SSE3)) { 5119 if (CpuFeatures::IsSupported(SSE3)) {
5120 // This will deoptimize if the exponent of the input in out of range. 5120 // This will deoptimize if the exponent of the input in out of range.
5121 CpuFeatures::Scope scope(SSE3); 5121 CpuFeatureScope scope(masm(), SSE3);
5122 Label convert, done; 5122 Label convert, done;
5123 __ j(not_equal, &done, Label::kNear); 5123 __ j(not_equal, &done, Label::kNear);
5124 __ sub(Operand(esp), Immediate(kDoubleSize)); 5124 __ sub(Operand(esp), Immediate(kDoubleSize));
5125 __ movdbl(Operand(esp, 0), input_reg); 5125 __ movdbl(Operand(esp, 0), input_reg);
5126 // Get exponent alone and check for too-big exponent. 5126 // Get exponent alone and check for too-big exponent.
5127 __ mov(result_reg, Operand(esp, sizeof(int32_t))); 5127 __ mov(result_reg, Operand(esp, sizeof(int32_t)));
5128 __ and_(result_reg, HeapNumber::kExponentMask); 5128 __ and_(result_reg, HeapNumber::kExponentMask);
5129 const uint32_t kTooBigExponent = 5129 const uint32_t kTooBigExponent =
5130 (HeapNumber::kExponentBias + 63) << HeapNumber::kExponentShift; 5130 (HeapNumber::kExponentBias + 63) << HeapNumber::kExponentShift;
5131 __ cmp(Operand(result_reg), Immediate(kTooBigExponent)); 5131 __ cmp(Operand(result_reg), Immediate(kTooBigExponent));
(...skipping 184 matching lines...) Expand 10 before | Expand all | Expand 10 after
5316 __ CompareMap(reg, map, &success, REQUIRE_EXACT_MAP); 5316 __ CompareMap(reg, map, &success, REQUIRE_EXACT_MAP);
5317 __ j(equal, &success); 5317 __ j(equal, &success);
5318 } 5318 }
5319 Handle<Map> map = map_set->last(); 5319 Handle<Map> map = map_set->last();
5320 DoCheckMapCommon(reg, map, REQUIRE_EXACT_MAP, instr); 5320 DoCheckMapCommon(reg, map, REQUIRE_EXACT_MAP, instr);
5321 __ bind(&success); 5321 __ bind(&success);
5322 } 5322 }
5323 5323
5324 5324
5325 void LCodeGen::DoClampDToUint8(LClampDToUint8* instr) { 5325 void LCodeGen::DoClampDToUint8(LClampDToUint8* instr) {
5326 CpuFeatures::Scope scope(SSE2); 5326 CpuFeatureScope scope(masm(), SSE2);
5327 XMMRegister value_reg = ToDoubleRegister(instr->unclamped()); 5327 XMMRegister value_reg = ToDoubleRegister(instr->unclamped());
5328 Register result_reg = ToRegister(instr->result()); 5328 Register result_reg = ToRegister(instr->result());
5329 __ ClampDoubleToUint8(value_reg, xmm0, result_reg); 5329 __ ClampDoubleToUint8(value_reg, xmm0, result_reg);
5330 } 5330 }
5331 5331
5332 5332
5333 void LCodeGen::DoClampIToUint8(LClampIToUint8* instr) { 5333 void LCodeGen::DoClampIToUint8(LClampIToUint8* instr) {
5334 ASSERT(instr->unclamped()->Equals(instr->result())); 5334 ASSERT(instr->unclamped()->Equals(instr->result()));
5335 Register value_reg = ToRegister(instr->result()); 5335 Register value_reg = ToRegister(instr->result());
5336 __ ClampUint8(value_reg); 5336 __ ClampUint8(value_reg);
5337 } 5337 }
5338 5338
5339 5339
5340 void LCodeGen::DoClampTToUint8(LClampTToUint8* instr) { 5340 void LCodeGen::DoClampTToUint8(LClampTToUint8* instr) {
5341 CpuFeatures::Scope scope(SSE2); 5341 CpuFeatureScope scope(masm(), SSE2);
5342 5342
5343 ASSERT(instr->unclamped()->Equals(instr->result())); 5343 ASSERT(instr->unclamped()->Equals(instr->result()));
5344 Register input_reg = ToRegister(instr->unclamped()); 5344 Register input_reg = ToRegister(instr->unclamped());
5345 Label is_smi, done, heap_number; 5345 Label is_smi, done, heap_number;
5346 5346
5347 __ JumpIfSmi(input_reg, &is_smi); 5347 __ JumpIfSmi(input_reg, &is_smi);
5348 5348
5349 // Check for heap number 5349 // Check for heap number
5350 __ cmp(FieldOperand(input_reg, HeapObject::kMapOffset), 5350 __ cmp(FieldOperand(input_reg, HeapObject::kMapOffset),
5351 factory()->heap_number_map()); 5351 factory()->heap_number_map());
(...skipping 901 matching lines...) Expand 10 before | Expand all | Expand 10 after
6253 FixedArray::kHeaderSize - kPointerSize)); 6253 FixedArray::kHeaderSize - kPointerSize));
6254 __ bind(&done); 6254 __ bind(&done);
6255 } 6255 }
6256 6256
6257 6257
6258 #undef __ 6258 #undef __
6259 6259
6260 } } // namespace v8::internal 6260 } } // namespace v8::internal
6261 6261
6262 #endif // V8_TARGET_ARCH_IA32 6262 #endif // V8_TARGET_ARCH_IA32
OLDNEW
« no previous file with comments | « src/ia32/full-codegen-ia32.cc ('k') | src/ia32/lithium-gap-resolver-ia32.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698