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

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

Issue 1391963005: [x64] Use vmovapd and vmovsd when AVX is enabled. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Fix Win compile. Created 5 years, 2 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
« no previous file with comments | « src/x64/disasm-x64.cc ('k') | src/x64/lithium-gap-resolver-x64.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 2013 the V8 project authors. All rights reserved. 1 // Copyright 2013 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #if V8_TARGET_ARCH_X64 5 #if V8_TARGET_ARCH_X64
6 6
7 #include "src/base/bits.h" 7 #include "src/base/bits.h"
8 #include "src/code-factory.h" 8 #include "src/code-factory.h"
9 #include "src/code-stubs.h" 9 #include "src/code-stubs.h"
10 #include "src/hydrogen-osr.h" 10 #include "src/hydrogen-osr.h"
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
81 81
82 82
83 void LCodeGen::SaveCallerDoubles() { 83 void LCodeGen::SaveCallerDoubles() {
84 DCHECK(info()->saves_caller_doubles()); 84 DCHECK(info()->saves_caller_doubles());
85 DCHECK(NeedsEagerFrame()); 85 DCHECK(NeedsEagerFrame());
86 Comment(";;; Save clobbered callee double registers"); 86 Comment(";;; Save clobbered callee double registers");
87 int count = 0; 87 int count = 0;
88 BitVector* doubles = chunk()->allocated_double_registers(); 88 BitVector* doubles = chunk()->allocated_double_registers();
89 BitVector::Iterator save_iterator(doubles); 89 BitVector::Iterator save_iterator(doubles);
90 while (!save_iterator.Done()) { 90 while (!save_iterator.Done()) {
91 __ movsd(MemOperand(rsp, count * kDoubleSize), 91 __ Movsd(MemOperand(rsp, count * kDoubleSize),
92 XMMRegister::from_code(save_iterator.Current())); 92 XMMRegister::from_code(save_iterator.Current()));
93 save_iterator.Advance(); 93 save_iterator.Advance();
94 count++; 94 count++;
95 } 95 }
96 } 96 }
97 97
98 98
99 void LCodeGen::RestoreCallerDoubles() { 99 void LCodeGen::RestoreCallerDoubles() {
100 DCHECK(info()->saves_caller_doubles()); 100 DCHECK(info()->saves_caller_doubles());
101 DCHECK(NeedsEagerFrame()); 101 DCHECK(NeedsEagerFrame());
102 Comment(";;; Restore clobbered callee double registers"); 102 Comment(";;; Restore clobbered callee double registers");
103 BitVector* doubles = chunk()->allocated_double_registers(); 103 BitVector* doubles = chunk()->allocated_double_registers();
104 BitVector::Iterator save_iterator(doubles); 104 BitVector::Iterator save_iterator(doubles);
105 int count = 0; 105 int count = 0;
106 while (!save_iterator.Done()) { 106 while (!save_iterator.Done()) {
107 __ movsd(XMMRegister::from_code(save_iterator.Current()), 107 __ Movsd(XMMRegister::from_code(save_iterator.Current()),
108 MemOperand(rsp, count * kDoubleSize)); 108 MemOperand(rsp, count * kDoubleSize));
109 save_iterator.Advance(); 109 save_iterator.Advance();
110 count++; 110 count++;
111 } 111 }
112 } 112 }
113 113
114 114
115 bool LCodeGen::GeneratePrologue() { 115 bool LCodeGen::GeneratePrologue() {
116 DCHECK(is_generating()); 116 DCHECK(is_generating());
117 117
(...skipping 1866 matching lines...) Expand 10 before | Expand all | Expand 10 after
1984 } else { 1984 } else {
1985 // Since we operate on +0 and/or -0, addsd and andsd have the same effect. 1985 // Since we operate on +0 and/or -0, addsd and andsd have the same effect.
1986 __ addsd(left_reg, right_reg); 1986 __ addsd(left_reg, right_reg);
1987 } 1987 }
1988 __ jmp(&return_left, Label::kNear); 1988 __ jmp(&return_left, Label::kNear);
1989 1989
1990 __ bind(&check_nan_left); 1990 __ bind(&check_nan_left);
1991 __ ucomisd(left_reg, left_reg); // NaN check. 1991 __ ucomisd(left_reg, left_reg); // NaN check.
1992 __ j(parity_even, &return_left, Label::kNear); 1992 __ j(parity_even, &return_left, Label::kNear);
1993 __ bind(&return_right); 1993 __ bind(&return_right);
1994 __ movaps(left_reg, right_reg); 1994 __ Movapd(left_reg, right_reg);
1995 1995
1996 __ bind(&return_left); 1996 __ bind(&return_left);
1997 } 1997 }
1998 } 1998 }
1999 1999
2000 2000
2001 void LCodeGen::DoArithmeticD(LArithmeticD* instr) { 2001 void LCodeGen::DoArithmeticD(LArithmeticD* instr) {
2002 XMMRegister left = ToDoubleRegister(instr->left()); 2002 XMMRegister left = ToDoubleRegister(instr->left());
2003 XMMRegister right = ToDoubleRegister(instr->right()); 2003 XMMRegister right = ToDoubleRegister(instr->right());
2004 XMMRegister result = ToDoubleRegister(instr->result()); 2004 XMMRegister result = ToDoubleRegister(instr->result());
(...skipping 28 matching lines...) Expand all
2033 case Token::DIV: 2033 case Token::DIV:
2034 if (CpuFeatures::IsSupported(AVX)) { 2034 if (CpuFeatures::IsSupported(AVX)) {
2035 CpuFeatureScope scope(masm(), AVX); 2035 CpuFeatureScope scope(masm(), AVX);
2036 __ vdivsd(result, left, right); 2036 __ vdivsd(result, left, right);
2037 } else { 2037 } else {
2038 DCHECK(result.is(left)); 2038 DCHECK(result.is(left));
2039 __ divsd(left, right); 2039 __ divsd(left, right);
2040 } 2040 }
2041 // Don't delete this mov. It may improve performance on some CPUs, 2041 // Don't delete this mov. It may improve performance on some CPUs,
2042 // when there is a (v)mulsd depending on the result 2042 // when there is a (v)mulsd depending on the result
2043 __ movaps(result, result); 2043 __ Movapd(result, result);
2044 break; 2044 break;
2045 case Token::MOD: { 2045 case Token::MOD: {
2046 XMMRegister xmm_scratch = double_scratch0(); 2046 XMMRegister xmm_scratch = double_scratch0();
2047 __ PrepareCallCFunction(2); 2047 __ PrepareCallCFunction(2);
2048 __ movaps(xmm_scratch, left); 2048 __ Movapd(xmm_scratch, left);
2049 DCHECK(right.is(xmm1)); 2049 DCHECK(right.is(xmm1));
2050 __ CallCFunction( 2050 __ CallCFunction(
2051 ExternalReference::mod_two_doubles_operation(isolate()), 2); 2051 ExternalReference::mod_two_doubles_operation(isolate()), 2);
2052 __ movaps(result, xmm_scratch); 2052 __ Movapd(result, xmm_scratch);
2053 break; 2053 break;
2054 } 2054 }
2055 default: 2055 default:
2056 UNREACHABLE(); 2056 UNREACHABLE();
2057 break; 2057 break;
2058 } 2058 }
2059 } 2059 }
2060 2060
2061 2061
2062 void LCodeGen::DoArithmeticT(LArithmeticT* instr) { 2062 void LCodeGen::DoArithmeticT(LArithmeticT* instr) {
(...skipping 321 matching lines...) Expand 10 before | Expand all | Expand 10 after
2384 __ Cmp(input_reg, factory()->the_hole_value()); 2384 __ Cmp(input_reg, factory()->the_hole_value());
2385 EmitBranch(instr, equal); 2385 EmitBranch(instr, equal);
2386 return; 2386 return;
2387 } 2387 }
2388 2388
2389 XMMRegister input_reg = ToDoubleRegister(instr->object()); 2389 XMMRegister input_reg = ToDoubleRegister(instr->object());
2390 __ ucomisd(input_reg, input_reg); 2390 __ ucomisd(input_reg, input_reg);
2391 EmitFalseBranch(instr, parity_odd); 2391 EmitFalseBranch(instr, parity_odd);
2392 2392
2393 __ subp(rsp, Immediate(kDoubleSize)); 2393 __ subp(rsp, Immediate(kDoubleSize));
2394 __ movsd(MemOperand(rsp, 0), input_reg); 2394 __ Movsd(MemOperand(rsp, 0), input_reg);
2395 __ addp(rsp, Immediate(kDoubleSize)); 2395 __ addp(rsp, Immediate(kDoubleSize));
2396 2396
2397 int offset = sizeof(kHoleNanUpper32); 2397 int offset = sizeof(kHoleNanUpper32);
2398 __ cmpl(MemOperand(rsp, -offset), Immediate(kHoleNanUpper32)); 2398 __ cmpl(MemOperand(rsp, -offset), Immediate(kHoleNanUpper32));
2399 EmitBranch(instr, equal); 2399 EmitBranch(instr, equal);
2400 } 2400 }
2401 2401
2402 2402
2403 void LCodeGen::DoCompareMinusZeroAndBranch(LCompareMinusZeroAndBranch* instr) { 2403 void LCodeGen::DoCompareMinusZeroAndBranch(LCompareMinusZeroAndBranch* instr) {
2404 Representation rep = instr->hydrogen()->value()->representation(); 2404 Representation rep = instr->hydrogen()->value()->representation();
(...skipping 457 matching lines...) Expand 10 before | Expand all | Expand 10 after
2862 Register object = ToRegister(instr->object()); 2862 Register object = ToRegister(instr->object());
2863 __ Load(result, MemOperand(object, offset), access.representation()); 2863 __ Load(result, MemOperand(object, offset), access.representation());
2864 } 2864 }
2865 return; 2865 return;
2866 } 2866 }
2867 2867
2868 Register object = ToRegister(instr->object()); 2868 Register object = ToRegister(instr->object());
2869 if (instr->hydrogen()->representation().IsDouble()) { 2869 if (instr->hydrogen()->representation().IsDouble()) {
2870 DCHECK(access.IsInobject()); 2870 DCHECK(access.IsInobject());
2871 XMMRegister result = ToDoubleRegister(instr->result()); 2871 XMMRegister result = ToDoubleRegister(instr->result());
2872 __ movsd(result, FieldOperand(object, offset)); 2872 __ Movsd(result, FieldOperand(object, offset));
2873 return; 2873 return;
2874 } 2874 }
2875 2875
2876 Register result = ToRegister(instr->result()); 2876 Register result = ToRegister(instr->result());
2877 if (!access.IsInobject()) { 2877 if (!access.IsInobject()) {
2878 __ movp(result, FieldOperand(object, JSObject::kPropertiesOffset)); 2878 __ movp(result, FieldOperand(object, JSObject::kPropertiesOffset));
2879 object = result; 2879 object = result;
2880 } 2880 }
2881 2881
2882 Representation representation = access.representation(); 2882 Representation representation = access.representation();
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after
2995 key, 2995 key,
2996 instr->hydrogen()->key()->representation(), 2996 instr->hydrogen()->key()->representation(),
2997 elements_kind, 2997 elements_kind,
2998 instr->base_offset())); 2998 instr->base_offset()));
2999 2999
3000 if (elements_kind == FLOAT32_ELEMENTS) { 3000 if (elements_kind == FLOAT32_ELEMENTS) {
3001 XMMRegister result(ToDoubleRegister(instr->result())); 3001 XMMRegister result(ToDoubleRegister(instr->result()));
3002 __ movss(result, operand); 3002 __ movss(result, operand);
3003 __ cvtss2sd(result, result); 3003 __ cvtss2sd(result, result);
3004 } else if (elements_kind == FLOAT64_ELEMENTS) { 3004 } else if (elements_kind == FLOAT64_ELEMENTS) {
3005 __ movsd(ToDoubleRegister(instr->result()), operand); 3005 __ Movsd(ToDoubleRegister(instr->result()), operand);
3006 } else { 3006 } else {
3007 Register result(ToRegister(instr->result())); 3007 Register result(ToRegister(instr->result()));
3008 switch (elements_kind) { 3008 switch (elements_kind) {
3009 case INT8_ELEMENTS: 3009 case INT8_ELEMENTS:
3010 __ movsxbl(result, operand); 3010 __ movsxbl(result, operand);
3011 break; 3011 break;
3012 case UINT8_ELEMENTS: 3012 case UINT8_ELEMENTS:
3013 case UINT8_CLAMPED_ELEMENTS: 3013 case UINT8_CLAMPED_ELEMENTS:
3014 __ movzxbl(result, operand); 3014 __ movzxbl(result, operand);
3015 break; 3015 break;
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
3066 __ cmpl(hole_check_operand, Immediate(kHoleNanUpper32)); 3066 __ cmpl(hole_check_operand, Immediate(kHoleNanUpper32));
3067 DeoptimizeIf(equal, instr, Deoptimizer::kHole); 3067 DeoptimizeIf(equal, instr, Deoptimizer::kHole);
3068 } 3068 }
3069 3069
3070 Operand double_load_operand = BuildFastArrayOperand( 3070 Operand double_load_operand = BuildFastArrayOperand(
3071 instr->elements(), 3071 instr->elements(),
3072 key, 3072 key,
3073 instr->hydrogen()->key()->representation(), 3073 instr->hydrogen()->key()->representation(),
3074 FAST_DOUBLE_ELEMENTS, 3074 FAST_DOUBLE_ELEMENTS,
3075 instr->base_offset()); 3075 instr->base_offset());
3076 __ movsd(result, double_load_operand); 3076 __ Movsd(result, double_load_operand);
3077 } 3077 }
3078 3078
3079 3079
3080 void LCodeGen::DoLoadKeyedFixedArray(LLoadKeyed* instr) { 3080 void LCodeGen::DoLoadKeyedFixedArray(LLoadKeyed* instr) {
3081 HLoadKeyed* hinstr = instr->hydrogen(); 3081 HLoadKeyed* hinstr = instr->hydrogen();
3082 Register result = ToRegister(instr->result()); 3082 Register result = ToRegister(instr->result());
3083 LOperand* key = instr->key(); 3083 LOperand* key = instr->key();
3084 bool requires_hole_check = hinstr->RequiresHoleCheck(); 3084 bool requires_hole_check = hinstr->RequiresHoleCheck();
3085 Representation representation = hinstr->representation(); 3085 Representation representation = hinstr->representation();
3086 int offset = instr->base_offset(); 3086 int offset = instr->base_offset();
(...skipping 731 matching lines...) Expand 10 before | Expand all | Expand 10 after
3818 __ xorps(xmm_scratch, xmm_scratch); 3818 __ xorps(xmm_scratch, xmm_scratch);
3819 __ ucomisd(input_reg, xmm_scratch); 3819 __ ucomisd(input_reg, xmm_scratch);
3820 __ j(above, &positive, Label::kNear); 3820 __ j(above, &positive, Label::kNear);
3821 __ j(not_carry, &zero, Label::kNear); 3821 __ j(not_carry, &zero, Label::kNear);
3822 __ pcmpeqd(input_reg, input_reg); 3822 __ pcmpeqd(input_reg, input_reg);
3823 __ jmp(&done, Label::kNear); 3823 __ jmp(&done, Label::kNear);
3824 __ bind(&zero); 3824 __ bind(&zero);
3825 ExternalReference ninf = 3825 ExternalReference ninf =
3826 ExternalReference::address_of_negative_infinity(); 3826 ExternalReference::address_of_negative_infinity();
3827 Operand ninf_operand = masm()->ExternalOperand(ninf); 3827 Operand ninf_operand = masm()->ExternalOperand(ninf);
3828 __ movsd(input_reg, ninf_operand); 3828 __ Movsd(input_reg, ninf_operand);
3829 __ jmp(&done, Label::kNear); 3829 __ jmp(&done, Label::kNear);
3830 __ bind(&positive); 3830 __ bind(&positive);
3831 __ fldln2(); 3831 __ fldln2();
3832 __ subp(rsp, Immediate(kDoubleSize)); 3832 __ subp(rsp, Immediate(kDoubleSize));
3833 __ movsd(Operand(rsp, 0), input_reg); 3833 __ Movsd(Operand(rsp, 0), input_reg);
3834 __ fld_d(Operand(rsp, 0)); 3834 __ fld_d(Operand(rsp, 0));
3835 __ fyl2x(); 3835 __ fyl2x();
3836 __ fstp_d(Operand(rsp, 0)); 3836 __ fstp_d(Operand(rsp, 0));
3837 __ movsd(input_reg, Operand(rsp, 0)); 3837 __ Movsd(input_reg, Operand(rsp, 0));
3838 __ addp(rsp, Immediate(kDoubleSize)); 3838 __ addp(rsp, Immediate(kDoubleSize));
3839 __ bind(&done); 3839 __ bind(&done);
3840 } 3840 }
3841 3841
3842 3842
3843 void LCodeGen::DoMathClz32(LMathClz32* instr) { 3843 void LCodeGen::DoMathClz32(LMathClz32* instr) {
3844 Register input = ToRegister(instr->value()); 3844 Register input = ToRegister(instr->value());
3845 Register result = ToRegister(instr->result()); 3845 Register result = ToRegister(instr->result());
3846 3846
3847 __ Lzcntl(result, input); 3847 __ Lzcntl(result, input);
(...skipping 170 matching lines...) Expand 10 before | Expand all | Expand 10 after
4018 __ AssertNotSmi(object); 4018 __ AssertNotSmi(object);
4019 4019
4020 DCHECK(!representation.IsSmi() || 4020 DCHECK(!representation.IsSmi() ||
4021 !instr->value()->IsConstantOperand() || 4021 !instr->value()->IsConstantOperand() ||
4022 IsInteger32Constant(LConstantOperand::cast(instr->value()))); 4022 IsInteger32Constant(LConstantOperand::cast(instr->value())));
4023 if (!FLAG_unbox_double_fields && representation.IsDouble()) { 4023 if (!FLAG_unbox_double_fields && representation.IsDouble()) {
4024 DCHECK(access.IsInobject()); 4024 DCHECK(access.IsInobject());
4025 DCHECK(!hinstr->has_transition()); 4025 DCHECK(!hinstr->has_transition());
4026 DCHECK(!hinstr->NeedsWriteBarrier()); 4026 DCHECK(!hinstr->NeedsWriteBarrier());
4027 XMMRegister value = ToDoubleRegister(instr->value()); 4027 XMMRegister value = ToDoubleRegister(instr->value());
4028 __ movsd(FieldOperand(object, offset), value); 4028 __ Movsd(FieldOperand(object, offset), value);
4029 return; 4029 return;
4030 } 4030 }
4031 4031
4032 if (hinstr->has_transition()) { 4032 if (hinstr->has_transition()) {
4033 Handle<Map> transition = hinstr->transition_map(); 4033 Handle<Map> transition = hinstr->transition_map();
4034 AddDeprecationDependency(transition); 4034 AddDeprecationDependency(transition);
4035 if (!hinstr->NeedsWriteBarrierForMap()) { 4035 if (!hinstr->NeedsWriteBarrierForMap()) {
4036 __ Move(FieldOperand(object, HeapObject::kMapOffset), transition); 4036 __ Move(FieldOperand(object, HeapObject::kMapOffset), transition);
4037 } else { 4037 } else {
4038 Register temp = ToRegister(instr->temp()); 4038 Register temp = ToRegister(instr->temp());
(...skipping 27 matching lines...) Expand all
4066 DCHECK(kSmiTagSize + kSmiShiftSize == 32); 4066 DCHECK(kSmiTagSize + kSmiShiftSize == 32);
4067 offset += kPointerSize / 2; 4067 offset += kPointerSize / 2;
4068 representation = Representation::Integer32(); 4068 representation = Representation::Integer32();
4069 } 4069 }
4070 4070
4071 Operand operand = FieldOperand(write_register, offset); 4071 Operand operand = FieldOperand(write_register, offset);
4072 4072
4073 if (FLAG_unbox_double_fields && representation.IsDouble()) { 4073 if (FLAG_unbox_double_fields && representation.IsDouble()) {
4074 DCHECK(access.IsInobject()); 4074 DCHECK(access.IsInobject());
4075 XMMRegister value = ToDoubleRegister(instr->value()); 4075 XMMRegister value = ToDoubleRegister(instr->value());
4076 __ movsd(operand, value); 4076 __ Movsd(operand, value);
4077 4077
4078 } else if (instr->value()->IsRegister()) { 4078 } else if (instr->value()->IsRegister()) {
4079 Register value = ToRegister(instr->value()); 4079 Register value = ToRegister(instr->value());
4080 __ Store(operand, value, representation); 4080 __ Store(operand, value, representation);
4081 } else { 4081 } else {
4082 LConstantOperand* operand_value = LConstantOperand::cast(instr->value()); 4082 LConstantOperand* operand_value = LConstantOperand::cast(instr->value());
4083 if (IsInteger32Constant(operand_value)) { 4083 if (IsInteger32Constant(operand_value)) {
4084 DCHECK(!hinstr->NeedsWriteBarrier()); 4084 DCHECK(!hinstr->NeedsWriteBarrier());
4085 int32_t value = ToInteger32(operand_value); 4085 int32_t value = ToInteger32(operand_value);
4086 if (representation.IsSmi()) { 4086 if (representation.IsSmi()) {
(...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after
4239 key, 4239 key,
4240 instr->hydrogen()->key()->representation(), 4240 instr->hydrogen()->key()->representation(),
4241 elements_kind, 4241 elements_kind,
4242 instr->base_offset())); 4242 instr->base_offset()));
4243 4243
4244 if (elements_kind == FLOAT32_ELEMENTS) { 4244 if (elements_kind == FLOAT32_ELEMENTS) {
4245 XMMRegister value(ToDoubleRegister(instr->value())); 4245 XMMRegister value(ToDoubleRegister(instr->value()));
4246 __ cvtsd2ss(value, value); 4246 __ cvtsd2ss(value, value);
4247 __ movss(operand, value); 4247 __ movss(operand, value);
4248 } else if (elements_kind == FLOAT64_ELEMENTS) { 4248 } else if (elements_kind == FLOAT64_ELEMENTS) {
4249 __ movsd(operand, ToDoubleRegister(instr->value())); 4249 __ Movsd(operand, ToDoubleRegister(instr->value()));
4250 } else { 4250 } else {
4251 Register value(ToRegister(instr->value())); 4251 Register value(ToRegister(instr->value()));
4252 switch (elements_kind) { 4252 switch (elements_kind) {
4253 case INT8_ELEMENTS: 4253 case INT8_ELEMENTS:
4254 case UINT8_ELEMENTS: 4254 case UINT8_ELEMENTS:
4255 case UINT8_CLAMPED_ELEMENTS: 4255 case UINT8_CLAMPED_ELEMENTS:
4256 __ movb(operand, value); 4256 __ movb(operand, value);
4257 break; 4257 break;
4258 case INT16_ELEMENTS: 4258 case INT16_ELEMENTS:
4259 case UINT16_ELEMENTS: 4259 case UINT16_ELEMENTS:
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
4297 __ subsd(value, xmm_scratch); 4297 __ subsd(value, xmm_scratch);
4298 } 4298 }
4299 4299
4300 Operand double_store_operand = BuildFastArrayOperand( 4300 Operand double_store_operand = BuildFastArrayOperand(
4301 instr->elements(), 4301 instr->elements(),
4302 key, 4302 key,
4303 instr->hydrogen()->key()->representation(), 4303 instr->hydrogen()->key()->representation(),
4304 FAST_DOUBLE_ELEMENTS, 4304 FAST_DOUBLE_ELEMENTS,
4305 instr->base_offset()); 4305 instr->base_offset());
4306 4306
4307 __ movsd(double_store_operand, value); 4307 __ Movsd(double_store_operand, value);
4308 } 4308 }
4309 4309
4310 4310
4311 void LCodeGen::DoStoreKeyedFixedArray(LStoreKeyed* instr) { 4311 void LCodeGen::DoStoreKeyedFixedArray(LStoreKeyed* instr) {
4312 HStoreKeyed* hinstr = instr->hydrogen(); 4312 HStoreKeyed* hinstr = instr->hydrogen();
4313 LOperand* key = instr->key(); 4313 LOperand* key = instr->key();
4314 int offset = instr->base_offset(); 4314 int offset = instr->base_offset();
4315 Representation representation = hinstr->value()->representation(); 4315 Representation representation = hinstr->value()->representation();
4316 4316
4317 if (kPointerSize == kInt32Size && !key->IsConstantOperand() && 4317 if (kPointerSize == kInt32Size && !key->IsConstantOperand() &&
(...skipping 486 matching lines...) Expand 10 before | Expand all | Expand 10 after
4804 __ movp(rsi, Operand(rbp, StandardFrameConstants::kContextOffset)); 4804 __ movp(rsi, Operand(rbp, StandardFrameConstants::kContextOffset));
4805 __ CallRuntimeSaveDoubles(Runtime::kAllocateHeapNumber); 4805 __ CallRuntimeSaveDoubles(Runtime::kAllocateHeapNumber);
4806 RecordSafepointWithRegisters( 4806 RecordSafepointWithRegisters(
4807 instr->pointer_map(), 0, Safepoint::kNoLazyDeopt); 4807 instr->pointer_map(), 0, Safepoint::kNoLazyDeopt);
4808 __ StoreToSafepointRegisterSlot(reg, rax); 4808 __ StoreToSafepointRegisterSlot(reg, rax);
4809 } 4809 }
4810 4810
4811 // Done. Put the value in temp_xmm into the value of the allocated heap 4811 // Done. Put the value in temp_xmm into the value of the allocated heap
4812 // number. 4812 // number.
4813 __ bind(&done); 4813 __ bind(&done);
4814 __ movsd(FieldOperand(reg, HeapNumber::kValueOffset), temp_xmm); 4814 __ Movsd(FieldOperand(reg, HeapNumber::kValueOffset), temp_xmm);
4815 } 4815 }
4816 4816
4817 4817
4818 void LCodeGen::DoNumberTagD(LNumberTagD* instr) { 4818 void LCodeGen::DoNumberTagD(LNumberTagD* instr) {
4819 class DeferredNumberTagD final : public LDeferredCode { 4819 class DeferredNumberTagD final : public LDeferredCode {
4820 public: 4820 public:
4821 DeferredNumberTagD(LCodeGen* codegen, LNumberTagD* instr) 4821 DeferredNumberTagD(LCodeGen* codegen, LNumberTagD* instr)
4822 : LDeferredCode(codegen), instr_(instr) { } 4822 : LDeferredCode(codegen), instr_(instr) { }
4823 void Generate() override { codegen()->DoDeferredNumberTagD(instr_); } 4823 void Generate() override { codegen()->DoDeferredNumberTagD(instr_); }
4824 LInstruction* instr() override { return instr_; } 4824 LInstruction* instr() override { return instr_; }
4825 4825
4826 private: 4826 private:
4827 LNumberTagD* instr_; 4827 LNumberTagD* instr_;
4828 }; 4828 };
4829 4829
4830 XMMRegister input_reg = ToDoubleRegister(instr->value()); 4830 XMMRegister input_reg = ToDoubleRegister(instr->value());
4831 Register reg = ToRegister(instr->result()); 4831 Register reg = ToRegister(instr->result());
4832 Register tmp = ToRegister(instr->temp()); 4832 Register tmp = ToRegister(instr->temp());
4833 4833
4834 DeferredNumberTagD* deferred = new(zone()) DeferredNumberTagD(this, instr); 4834 DeferredNumberTagD* deferred = new(zone()) DeferredNumberTagD(this, instr);
4835 if (FLAG_inline_new) { 4835 if (FLAG_inline_new) {
4836 __ AllocateHeapNumber(reg, tmp, deferred->entry()); 4836 __ AllocateHeapNumber(reg, tmp, deferred->entry());
4837 } else { 4837 } else {
4838 __ jmp(deferred->entry()); 4838 __ jmp(deferred->entry());
4839 } 4839 }
4840 __ bind(deferred->exit()); 4840 __ bind(deferred->exit());
4841 __ movsd(FieldOperand(reg, HeapNumber::kValueOffset), input_reg); 4841 __ Movsd(FieldOperand(reg, HeapNumber::kValueOffset), input_reg);
4842 } 4842 }
4843 4843
4844 4844
4845 void LCodeGen::DoDeferredNumberTagD(LNumberTagD* instr) { 4845 void LCodeGen::DoDeferredNumberTagD(LNumberTagD* instr) {
4846 // TODO(3095996): Get rid of this. For now, we need to make the 4846 // TODO(3095996): Get rid of this. For now, we need to make the
4847 // result register contain a valid pointer because it is already 4847 // result register contain a valid pointer because it is already
4848 // contained in the register pointer map. 4848 // contained in the register pointer map.
4849 Register reg = ToRegister(instr->result()); 4849 Register reg = ToRegister(instr->result());
4850 __ Move(reg, Smi::FromInt(0)); 4850 __ Move(reg, Smi::FromInt(0));
4851 4851
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
4907 if (mode == NUMBER_CANDIDATE_IS_ANY_TAGGED) { 4907 if (mode == NUMBER_CANDIDATE_IS_ANY_TAGGED) {
4908 // Smi check. 4908 // Smi check.
4909 __ JumpIfSmi(input_reg, &load_smi, Label::kNear); 4909 __ JumpIfSmi(input_reg, &load_smi, Label::kNear);
4910 4910
4911 // Heap number map check. 4911 // Heap number map check.
4912 __ CompareRoot(FieldOperand(input_reg, HeapObject::kMapOffset), 4912 __ CompareRoot(FieldOperand(input_reg, HeapObject::kMapOffset),
4913 Heap::kHeapNumberMapRootIndex); 4913 Heap::kHeapNumberMapRootIndex);
4914 4914
4915 // On x64 it is safe to load at heap number offset before evaluating the map 4915 // On x64 it is safe to load at heap number offset before evaluating the map
4916 // check, since all heap objects are at least two words long. 4916 // check, since all heap objects are at least two words long.
4917 __ movsd(result_reg, FieldOperand(input_reg, HeapNumber::kValueOffset)); 4917 __ Movsd(result_reg, FieldOperand(input_reg, HeapNumber::kValueOffset));
4918 4918
4919 if (can_convert_undefined_to_nan) { 4919 if (can_convert_undefined_to_nan) {
4920 __ j(not_equal, &convert, Label::kNear); 4920 __ j(not_equal, &convert, Label::kNear);
4921 } else { 4921 } else {
4922 DeoptimizeIf(not_equal, instr, Deoptimizer::kNotAHeapNumber); 4922 DeoptimizeIf(not_equal, instr, Deoptimizer::kNotAHeapNumber);
4923 } 4923 }
4924 4924
4925 if (deoptimize_on_minus_zero) { 4925 if (deoptimize_on_minus_zero) {
4926 XMMRegister xmm_scratch = double_scratch0(); 4926 XMMRegister xmm_scratch = double_scratch0();
4927 __ xorps(xmm_scratch, xmm_scratch); 4927 __ xorps(xmm_scratch, xmm_scratch);
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
4986 __ CompareRoot(input_reg, Heap::kFalseValueRootIndex); 4986 __ CompareRoot(input_reg, Heap::kFalseValueRootIndex);
4987 DeoptimizeIf(not_equal, instr, 4987 DeoptimizeIf(not_equal, instr,
4988 Deoptimizer::kNotAHeapNumberUndefinedBoolean); 4988 Deoptimizer::kNotAHeapNumberUndefinedBoolean);
4989 __ Set(input_reg, 0); 4989 __ Set(input_reg, 0);
4990 } else { 4990 } else {
4991 XMMRegister scratch = ToDoubleRegister(instr->temp()); 4991 XMMRegister scratch = ToDoubleRegister(instr->temp());
4992 DCHECK(!scratch.is(xmm0)); 4992 DCHECK(!scratch.is(xmm0));
4993 __ CompareRoot(FieldOperand(input_reg, HeapObject::kMapOffset), 4993 __ CompareRoot(FieldOperand(input_reg, HeapObject::kMapOffset),
4994 Heap::kHeapNumberMapRootIndex); 4994 Heap::kHeapNumberMapRootIndex);
4995 DeoptimizeIf(not_equal, instr, Deoptimizer::kNotAHeapNumber); 4995 DeoptimizeIf(not_equal, instr, Deoptimizer::kNotAHeapNumber);
4996 __ movsd(xmm0, FieldOperand(input_reg, HeapNumber::kValueOffset)); 4996 __ Movsd(xmm0, FieldOperand(input_reg, HeapNumber::kValueOffset));
4997 __ cvttsd2si(input_reg, xmm0); 4997 __ cvttsd2si(input_reg, xmm0);
4998 __ Cvtlsi2sd(scratch, input_reg); 4998 __ Cvtlsi2sd(scratch, input_reg);
4999 __ ucomisd(xmm0, scratch); 4999 __ ucomisd(xmm0, scratch);
5000 DeoptimizeIf(not_equal, instr, Deoptimizer::kLostPrecision); 5000 DeoptimizeIf(not_equal, instr, Deoptimizer::kLostPrecision);
5001 DeoptimizeIf(parity_even, instr, Deoptimizer::kNaN); 5001 DeoptimizeIf(parity_even, instr, Deoptimizer::kNaN);
5002 if (instr->hydrogen()->GetMinusZeroMode() == FAIL_ON_MINUS_ZERO) { 5002 if (instr->hydrogen()->GetMinusZeroMode() == FAIL_ON_MINUS_ZERO) {
5003 __ testl(input_reg, input_reg); 5003 __ testl(input_reg, input_reg);
5004 __ j(not_zero, done); 5004 __ j(not_zero, done);
5005 __ movmskpd(input_reg, xmm0); 5005 __ movmskpd(input_reg, xmm0);
5006 __ andl(input_reg, Immediate(1)); 5006 __ andl(input_reg, Immediate(1));
(...skipping 291 matching lines...) Expand 10 before | Expand all | Expand 10 after
5298 5298
5299 // Check for undefined. Undefined is converted to zero for clamping 5299 // Check for undefined. Undefined is converted to zero for clamping
5300 // conversions. 5300 // conversions.
5301 __ Cmp(input_reg, factory()->undefined_value()); 5301 __ Cmp(input_reg, factory()->undefined_value());
5302 DeoptimizeIf(not_equal, instr, Deoptimizer::kNotAHeapNumberUndefined); 5302 DeoptimizeIf(not_equal, instr, Deoptimizer::kNotAHeapNumberUndefined);
5303 __ xorl(input_reg, input_reg); 5303 __ xorl(input_reg, input_reg);
5304 __ jmp(&done, Label::kNear); 5304 __ jmp(&done, Label::kNear);
5305 5305
5306 // Heap number 5306 // Heap number
5307 __ bind(&heap_number); 5307 __ bind(&heap_number);
5308 __ movsd(xmm_scratch, FieldOperand(input_reg, HeapNumber::kValueOffset)); 5308 __ Movsd(xmm_scratch, FieldOperand(input_reg, HeapNumber::kValueOffset));
5309 __ ClampDoubleToUint8(xmm_scratch, temp_xmm_reg, input_reg); 5309 __ ClampDoubleToUint8(xmm_scratch, temp_xmm_reg, input_reg);
5310 __ jmp(&done, Label::kNear); 5310 __ jmp(&done, Label::kNear);
5311 5311
5312 // smi 5312 // smi
5313 __ bind(&is_smi); 5313 __ bind(&is_smi);
5314 __ SmiToInteger32(input_reg, input_reg); 5314 __ SmiToInteger32(input_reg, input_reg);
5315 __ ClampUint8(input_reg); 5315 __ ClampUint8(input_reg);
5316 5316
5317 __ bind(&done); 5317 __ bind(&done);
5318 } 5318 }
(...skipping 586 matching lines...) Expand 10 before | Expand all | Expand 10 after
5905 RecordSafepoint(Safepoint::kNoLazyDeopt); 5905 RecordSafepoint(Safepoint::kNoLazyDeopt);
5906 } 5906 }
5907 5907
5908 5908
5909 #undef __ 5909 #undef __
5910 5910
5911 } // namespace internal 5911 } // namespace internal
5912 } // namespace v8 5912 } // namespace v8
5913 5913
5914 #endif // V8_TARGET_ARCH_X64 5914 #endif // V8_TARGET_ARCH_X64
OLDNEW
« no previous file with comments | « src/x64/disasm-x64.cc ('k') | src/x64/lithium-gap-resolver-x64.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698