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

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

Issue 24277002: Make the use of xmm0 as double scratch register explicit in ia32 and x64. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 7 years, 3 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/lithium-codegen-ia32.h ('k') | src/x64/lithium-codegen-x64.h » ('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 1978 matching lines...) Expand 10 before | Expand all | Expand 10 after
1989 } else { 1989 } else {
1990 __ xorps(res, res); 1990 __ xorps(res, res);
1991 __ Set(temp, Immediate(upper)); 1991 __ Set(temp, Immediate(upper));
1992 __ pinsrd(res, Operand(temp), 1); 1992 __ pinsrd(res, Operand(temp), 1);
1993 } 1993 }
1994 } else { 1994 } else {
1995 __ Set(temp, Immediate(upper)); 1995 __ Set(temp, Immediate(upper));
1996 __ movd(res, Operand(temp)); 1996 __ movd(res, Operand(temp));
1997 __ psllq(res, 32); 1997 __ psllq(res, 32);
1998 if (lower != 0) { 1998 if (lower != 0) {
1999 XMMRegister xmm_scratch = double_scratch0();
1999 __ Set(temp, Immediate(lower)); 2000 __ Set(temp, Immediate(lower));
2000 __ movd(xmm0, Operand(temp)); 2001 __ movd(xmm_scratch, Operand(temp));
2001 __ por(res, xmm0); 2002 __ por(res, xmm_scratch);
2002 } 2003 }
2003 } 2004 }
2004 } 2005 }
2005 } 2006 }
2006 } 2007 }
2007 2008
2008 2009
2009 void LCodeGen::DoConstantE(LConstantE* instr) { 2010 void LCodeGen::DoConstantE(LConstantE* instr) {
2010 __ lea(ToRegister(instr->result()), Operand::StaticVariable(instr->value())); 2011 __ lea(ToRegister(instr->result()), Operand::StaticVariable(instr->value()));
2011 } 2012 }
(...skipping 188 matching lines...) Expand 10 before | Expand all | Expand 10 after
2200 Condition condition = (operation == HMathMinMax::kMathMin) ? below : above; 2201 Condition condition = (operation == HMathMinMax::kMathMin) ? below : above;
2201 XMMRegister left_reg = ToDoubleRegister(left); 2202 XMMRegister left_reg = ToDoubleRegister(left);
2202 XMMRegister right_reg = ToDoubleRegister(right); 2203 XMMRegister right_reg = ToDoubleRegister(right);
2203 __ ucomisd(left_reg, right_reg); 2204 __ ucomisd(left_reg, right_reg);
2204 __ j(parity_even, &check_nan_left, Label::kNear); // At least one NaN. 2205 __ j(parity_even, &check_nan_left, Label::kNear); // At least one NaN.
2205 __ j(equal, &check_zero, Label::kNear); // left == right. 2206 __ j(equal, &check_zero, Label::kNear); // left == right.
2206 __ j(condition, &return_left, Label::kNear); 2207 __ j(condition, &return_left, Label::kNear);
2207 __ jmp(&return_right, Label::kNear); 2208 __ jmp(&return_right, Label::kNear);
2208 2209
2209 __ bind(&check_zero); 2210 __ bind(&check_zero);
2210 XMMRegister xmm_scratch = xmm0; 2211 XMMRegister xmm_scratch = double_scratch0();
2211 __ xorps(xmm_scratch, xmm_scratch); 2212 __ xorps(xmm_scratch, xmm_scratch);
2212 __ ucomisd(left_reg, xmm_scratch); 2213 __ ucomisd(left_reg, xmm_scratch);
2213 __ j(not_equal, &return_left, Label::kNear); // left == right != 0. 2214 __ j(not_equal, &return_left, Label::kNear); // left == right != 0.
2214 // At this point, both left and right are either 0 or -0. 2215 // At this point, both left and right are either 0 or -0.
2215 if (operation == HMathMinMax::kMathMin) { 2216 if (operation == HMathMinMax::kMathMin) {
2216 __ orpd(left_reg, right_reg); 2217 __ orpd(left_reg, right_reg);
2217 } else { 2218 } else {
2218 // Since we operate on +0 and/or -0, addsd and andsd have the same effect. 2219 // Since we operate on +0 and/or -0, addsd and andsd have the same effect.
2219 __ addsd(left_reg, right_reg); 2220 __ addsd(left_reg, right_reg);
2220 } 2221 }
(...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after
2370 void LCodeGen::DoBranch(LBranch* instr) { 2371 void LCodeGen::DoBranch(LBranch* instr) {
2371 Representation r = instr->hydrogen()->value()->representation(); 2372 Representation r = instr->hydrogen()->value()->representation();
2372 if (r.IsSmiOrInteger32()) { 2373 if (r.IsSmiOrInteger32()) {
2373 Register reg = ToRegister(instr->value()); 2374 Register reg = ToRegister(instr->value());
2374 __ test(reg, Operand(reg)); 2375 __ test(reg, Operand(reg));
2375 EmitBranch(instr, not_zero); 2376 EmitBranch(instr, not_zero);
2376 } else if (r.IsDouble()) { 2377 } else if (r.IsDouble()) {
2377 ASSERT(!info()->IsStub()); 2378 ASSERT(!info()->IsStub());
2378 CpuFeatureScope scope(masm(), SSE2); 2379 CpuFeatureScope scope(masm(), SSE2);
2379 XMMRegister reg = ToDoubleRegister(instr->value()); 2380 XMMRegister reg = ToDoubleRegister(instr->value());
2380 __ xorps(xmm0, xmm0); 2381 XMMRegister xmm_scratch = double_scratch0();
2381 __ ucomisd(reg, xmm0); 2382 __ xorps(xmm_scratch, xmm_scratch);
2383 __ ucomisd(reg, xmm_scratch);
2382 EmitBranch(instr, not_equal); 2384 EmitBranch(instr, not_equal);
2383 } else { 2385 } else {
2384 ASSERT(r.IsTagged()); 2386 ASSERT(r.IsTagged());
2385 Register reg = ToRegister(instr->value()); 2387 Register reg = ToRegister(instr->value());
2386 HType type = instr->hydrogen()->value()->type(); 2388 HType type = instr->hydrogen()->value()->type();
2387 if (type.IsBoolean()) { 2389 if (type.IsBoolean()) {
2388 ASSERT(!info()->IsStub()); 2390 ASSERT(!info()->IsStub());
2389 __ cmp(reg, factory()->true_value()); 2391 __ cmp(reg, factory()->true_value());
2390 EmitBranch(instr, equal); 2392 EmitBranch(instr, equal);
2391 } else if (type.IsSmi()) { 2393 } else if (type.IsSmi()) {
2392 ASSERT(!info()->IsStub()); 2394 ASSERT(!info()->IsStub());
2393 __ test(reg, Operand(reg)); 2395 __ test(reg, Operand(reg));
2394 EmitBranch(instr, not_equal); 2396 EmitBranch(instr, not_equal);
2395 } else if (type.IsJSArray()) { 2397 } else if (type.IsJSArray()) {
2396 ASSERT(!info()->IsStub()); 2398 ASSERT(!info()->IsStub());
2397 EmitBranch(instr, no_condition); 2399 EmitBranch(instr, no_condition);
2398 } else if (type.IsHeapNumber()) { 2400 } else if (type.IsHeapNumber()) {
2399 ASSERT(!info()->IsStub()); 2401 ASSERT(!info()->IsStub());
2400 CpuFeatureScope scope(masm(), SSE2); 2402 CpuFeatureScope scope(masm(), SSE2);
2401 __ xorps(xmm0, xmm0); 2403 XMMRegister xmm_scratch = double_scratch0();
2402 __ ucomisd(xmm0, FieldOperand(reg, HeapNumber::kValueOffset)); 2404 __ xorps(xmm_scratch, xmm_scratch);
2405 __ ucomisd(xmm_scratch, FieldOperand(reg, HeapNumber::kValueOffset));
2403 EmitBranch(instr, not_equal); 2406 EmitBranch(instr, not_equal);
2404 } else if (type.IsString()) { 2407 } else if (type.IsString()) {
2405 ASSERT(!info()->IsStub()); 2408 ASSERT(!info()->IsStub());
2406 __ cmp(FieldOperand(reg, String::kLengthOffset), Immediate(0)); 2409 __ cmp(FieldOperand(reg, String::kLengthOffset), Immediate(0));
2407 EmitBranch(instr, not_equal); 2410 EmitBranch(instr, not_equal);
2408 } else { 2411 } else {
2409 ToBooleanStub::Types expected = instr->hydrogen()->expected_input_types(); 2412 ToBooleanStub::Types expected = instr->hydrogen()->expected_input_types();
2410 if (expected.IsEmpty()) expected = ToBooleanStub::Types::Generic(); 2413 if (expected.IsEmpty()) expected = ToBooleanStub::Types::Generic();
2411 2414
2412 if (expected.Contains(ToBooleanStub::UNDEFINED)) { 2415 if (expected.Contains(ToBooleanStub::UNDEFINED)) {
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
2477 } 2480 }
2478 2481
2479 if (expected.Contains(ToBooleanStub::HEAP_NUMBER)) { 2482 if (expected.Contains(ToBooleanStub::HEAP_NUMBER)) {
2480 // heap number -> false iff +0, -0, or NaN. 2483 // heap number -> false iff +0, -0, or NaN.
2481 Label not_heap_number; 2484 Label not_heap_number;
2482 __ cmp(FieldOperand(reg, HeapObject::kMapOffset), 2485 __ cmp(FieldOperand(reg, HeapObject::kMapOffset),
2483 factory()->heap_number_map()); 2486 factory()->heap_number_map());
2484 __ j(not_equal, &not_heap_number, Label::kNear); 2487 __ j(not_equal, &not_heap_number, Label::kNear);
2485 if (CpuFeatures::IsSafeForSnapshot(SSE2)) { 2488 if (CpuFeatures::IsSafeForSnapshot(SSE2)) {
2486 CpuFeatureScope scope(masm(), SSE2); 2489 CpuFeatureScope scope(masm(), SSE2);
2487 __ xorps(xmm0, xmm0); 2490 XMMRegister xmm_scratch = double_scratch0();
2488 __ ucomisd(xmm0, FieldOperand(reg, HeapNumber::kValueOffset)); 2491 __ xorps(xmm_scratch, xmm_scratch);
2492 __ ucomisd(xmm_scratch, FieldOperand(reg, HeapNumber::kValueOffset));
2489 } else { 2493 } else {
2490 __ fldz(); 2494 __ fldz();
2491 __ fld_d(FieldOperand(reg, HeapNumber::kValueOffset)); 2495 __ fld_d(FieldOperand(reg, HeapNumber::kValueOffset));
2492 __ FCmp(); 2496 __ FCmp();
2493 } 2497 }
2494 __ j(zero, instr->FalseLabel(chunk_)); 2498 __ j(zero, instr->FalseLabel(chunk_));
2495 __ jmp(instr->TrueLabel(chunk_)); 2499 __ jmp(instr->TrueLabel(chunk_));
2496 __ bind(&not_heap_number); 2500 __ bind(&not_heap_number);
2497 } 2501 }
2498 2502
(...skipping 1419 matching lines...) Expand 10 before | Expand all | Expand 10 after
3918 virtual LInstruction* instr() V8_OVERRIDE { return instr_; } 3922 virtual LInstruction* instr() V8_OVERRIDE { return instr_; }
3919 private: 3923 private:
3920 LMathAbs* instr_; 3924 LMathAbs* instr_;
3921 }; 3925 };
3922 3926
3923 ASSERT(instr->value()->Equals(instr->result())); 3927 ASSERT(instr->value()->Equals(instr->result()));
3924 Representation r = instr->hydrogen()->value()->representation(); 3928 Representation r = instr->hydrogen()->value()->representation();
3925 3929
3926 CpuFeatureScope scope(masm(), SSE2); 3930 CpuFeatureScope scope(masm(), SSE2);
3927 if (r.IsDouble()) { 3931 if (r.IsDouble()) {
3928 XMMRegister scratch = xmm0; 3932 XMMRegister scratch = double_scratch0();
3929 XMMRegister input_reg = ToDoubleRegister(instr->value()); 3933 XMMRegister input_reg = ToDoubleRegister(instr->value());
3930 __ xorps(scratch, scratch); 3934 __ xorps(scratch, scratch);
3931 __ subsd(scratch, input_reg); 3935 __ subsd(scratch, input_reg);
3932 __ pand(input_reg, scratch); 3936 __ pand(input_reg, scratch);
3933 } else if (r.IsSmiOrInteger32()) { 3937 } else if (r.IsSmiOrInteger32()) {
3934 EmitIntegerMathAbs(instr); 3938 EmitIntegerMathAbs(instr);
3935 } else { // Tagged case. 3939 } else { // Tagged case.
3936 DeferredMathAbsTaggedHeapNumber* deferred = 3940 DeferredMathAbsTaggedHeapNumber* deferred =
3937 new(zone()) DeferredMathAbsTaggedHeapNumber(this, instr, x87_stack_); 3941 new(zone()) DeferredMathAbsTaggedHeapNumber(this, instr, x87_stack_);
3938 Register input_reg = ToRegister(instr->value()); 3942 Register input_reg = ToRegister(instr->value());
3939 // Smi check. 3943 // Smi check.
3940 __ JumpIfNotSmi(input_reg, deferred->entry()); 3944 __ JumpIfNotSmi(input_reg, deferred->entry());
3941 EmitIntegerMathAbs(instr); 3945 EmitIntegerMathAbs(instr);
3942 __ bind(deferred->exit()); 3946 __ bind(deferred->exit());
3943 } 3947 }
3944 } 3948 }
3945 3949
3946 3950
3947 void LCodeGen::DoMathFloor(LMathFloor* instr) { 3951 void LCodeGen::DoMathFloor(LMathFloor* instr) {
3948 CpuFeatureScope scope(masm(), SSE2); 3952 CpuFeatureScope scope(masm(), SSE2);
3949 XMMRegister xmm_scratch = xmm0; 3953 XMMRegister xmm_scratch = double_scratch0();
3950 Register output_reg = ToRegister(instr->result()); 3954 Register output_reg = ToRegister(instr->result());
3951 XMMRegister input_reg = ToDoubleRegister(instr->value()); 3955 XMMRegister input_reg = ToDoubleRegister(instr->value());
3952 3956
3953 if (CpuFeatures::IsSupported(SSE4_1)) { 3957 if (CpuFeatures::IsSupported(SSE4_1)) {
3954 CpuFeatureScope scope(masm(), SSE4_1); 3958 CpuFeatureScope scope(masm(), SSE4_1);
3955 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { 3959 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
3956 // Deoptimize on negative zero. 3960 // Deoptimize on negative zero.
3957 Label non_zero; 3961 Label non_zero;
3958 __ xorps(xmm_scratch, xmm_scratch); // Zero the register. 3962 __ xorps(xmm_scratch, xmm_scratch); // Zero the register.
3959 __ ucomisd(input_reg, xmm_scratch); 3963 __ ucomisd(input_reg, xmm_scratch);
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
4007 4011
4008 __ bind(&done); 4012 __ bind(&done);
4009 } 4013 }
4010 } 4014 }
4011 4015
4012 4016
4013 void LCodeGen::DoMathRound(LMathRound* instr) { 4017 void LCodeGen::DoMathRound(LMathRound* instr) {
4014 CpuFeatureScope scope(masm(), SSE2); 4018 CpuFeatureScope scope(masm(), SSE2);
4015 Register output_reg = ToRegister(instr->result()); 4019 Register output_reg = ToRegister(instr->result());
4016 XMMRegister input_reg = ToDoubleRegister(instr->value()); 4020 XMMRegister input_reg = ToDoubleRegister(instr->value());
4017 XMMRegister xmm_scratch = xmm0; 4021 XMMRegister xmm_scratch = double_scratch0();
4018 XMMRegister input_temp = ToDoubleRegister(instr->temp()); 4022 XMMRegister input_temp = ToDoubleRegister(instr->temp());
4019 ExternalReference one_half = ExternalReference::address_of_one_half(); 4023 ExternalReference one_half = ExternalReference::address_of_one_half();
4020 ExternalReference minus_one_half = 4024 ExternalReference minus_one_half =
4021 ExternalReference::address_of_minus_one_half(); 4025 ExternalReference::address_of_minus_one_half();
4022 4026
4023 Label done, round_to_zero, below_one_half, do_not_compensate; 4027 Label done, round_to_zero, below_one_half, do_not_compensate;
4024 __ movdbl(xmm_scratch, Operand::StaticVariable(one_half)); 4028 __ movdbl(xmm_scratch, Operand::StaticVariable(one_half));
4025 __ ucomisd(xmm_scratch, input_reg); 4029 __ ucomisd(xmm_scratch, input_reg);
4026 __ j(above, &below_one_half); 4030 __ j(above, &below_one_half);
4027 4031
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
4074 void LCodeGen::DoMathSqrt(LMathSqrt* instr) { 4078 void LCodeGen::DoMathSqrt(LMathSqrt* instr) {
4075 CpuFeatureScope scope(masm(), SSE2); 4079 CpuFeatureScope scope(masm(), SSE2);
4076 XMMRegister input_reg = ToDoubleRegister(instr->value()); 4080 XMMRegister input_reg = ToDoubleRegister(instr->value());
4077 ASSERT(ToDoubleRegister(instr->result()).is(input_reg)); 4081 ASSERT(ToDoubleRegister(instr->result()).is(input_reg));
4078 __ sqrtsd(input_reg, input_reg); 4082 __ sqrtsd(input_reg, input_reg);
4079 } 4083 }
4080 4084
4081 4085
4082 void LCodeGen::DoMathPowHalf(LMathPowHalf* instr) { 4086 void LCodeGen::DoMathPowHalf(LMathPowHalf* instr) {
4083 CpuFeatureScope scope(masm(), SSE2); 4087 CpuFeatureScope scope(masm(), SSE2);
4084 XMMRegister xmm_scratch = xmm0; 4088 XMMRegister xmm_scratch = double_scratch0();
4085 XMMRegister input_reg = ToDoubleRegister(instr->value()); 4089 XMMRegister input_reg = ToDoubleRegister(instr->value());
4086 Register scratch = ToRegister(instr->temp()); 4090 Register scratch = ToRegister(instr->temp());
4087 ASSERT(ToDoubleRegister(instr->result()).is(input_reg)); 4091 ASSERT(ToDoubleRegister(instr->result()).is(input_reg));
4088 4092
4089 // Note that according to ECMA-262 15.8.2.13: 4093 // Note that according to ECMA-262 15.8.2.13:
4090 // Math.pow(-Infinity, 0.5) == Infinity 4094 // Math.pow(-Infinity, 0.5) == Infinity
4091 // Math.sqrt(-Infinity) == NaN 4095 // Math.sqrt(-Infinity) == NaN
4092 Label done, sqrt; 4096 Label done, sqrt;
4093 // Check base for -Infinity. According to IEEE-754, single-precision 4097 // Check base for -Infinity. According to IEEE-754, single-precision
4094 // -Infinity has the highest 9 bits set and the lowest 23 bits cleared. 4098 // -Infinity has the highest 9 bits set and the lowest 23 bits cleared.
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after
4193 // Random bit pattern = (state[0] << 14) + (state[1] & 0x3FFFF) 4197 // Random bit pattern = (state[0] << 14) + (state[1] & 0x3FFFF)
4194 Register random = state0; 4198 Register random = state0;
4195 __ shl(random, 14); 4199 __ shl(random, 14);
4196 __ and_(state1, Immediate(0x3FFFF)); 4200 __ and_(state1, Immediate(0x3FFFF));
4197 __ add(random, state1); 4201 __ add(random, state1);
4198 4202
4199 // Convert 32 random bits in random to 0.(32 random bits) in a double 4203 // Convert 32 random bits in random to 0.(32 random bits) in a double
4200 // by computing: 4204 // by computing:
4201 // ( 1.(20 0s)(32 random bits) x 2^20 ) - (1.0 x 2^20)). 4205 // ( 1.(20 0s)(32 random bits) x 2^20 ) - (1.0 x 2^20)).
4202 XMMRegister result = ToDoubleRegister(instr->result()); 4206 XMMRegister result = ToDoubleRegister(instr->result());
4203 // We use xmm0 as fixed scratch register here. 4207 XMMRegister scratch4 = double_scratch0();
4204 XMMRegister scratch4 = xmm0;
4205 __ mov(scratch3, Immediate(0x49800000)); // 1.0 x 2^20 as single. 4208 __ mov(scratch3, Immediate(0x49800000)); // 1.0 x 2^20 as single.
4206 __ movd(scratch4, scratch3); 4209 __ movd(scratch4, scratch3);
4207 __ movd(result, random); 4210 __ movd(result, random);
4208 __ cvtss2sd(scratch4, scratch4); 4211 __ cvtss2sd(scratch4, scratch4);
4209 __ xorps(result, scratch4); 4212 __ xorps(result, scratch4);
4210 __ subsd(result, scratch4); 4213 __ subsd(result, scratch4);
4211 } 4214 }
4212 4215
4213 4216
4214 void LCodeGen::DoMathLog(LMathLog* instr) { 4217 void LCodeGen::DoMathLog(LMathLog* instr) {
4215 CpuFeatureScope scope(masm(), SSE2); 4218 CpuFeatureScope scope(masm(), SSE2);
4216 ASSERT(instr->value()->Equals(instr->result())); 4219 ASSERT(instr->value()->Equals(instr->result()));
4217 XMMRegister input_reg = ToDoubleRegister(instr->value()); 4220 XMMRegister input_reg = ToDoubleRegister(instr->value());
4221 XMMRegister xmm_scratch = double_scratch0();
4218 Label positive, done, zero; 4222 Label positive, done, zero;
4219 __ xorps(xmm0, xmm0); 4223 __ xorps(xmm_scratch, xmm_scratch);
4220 __ ucomisd(input_reg, xmm0); 4224 __ ucomisd(input_reg, xmm_scratch);
4221 __ j(above, &positive, Label::kNear); 4225 __ j(above, &positive, Label::kNear);
4222 __ j(equal, &zero, Label::kNear); 4226 __ j(equal, &zero, Label::kNear);
4223 ExternalReference nan = 4227 ExternalReference nan =
4224 ExternalReference::address_of_canonical_non_hole_nan(); 4228 ExternalReference::address_of_canonical_non_hole_nan();
4225 __ movdbl(input_reg, Operand::StaticVariable(nan)); 4229 __ movdbl(input_reg, Operand::StaticVariable(nan));
4226 __ jmp(&done, Label::kNear); 4230 __ jmp(&done, Label::kNear);
4227 __ bind(&zero); 4231 __ bind(&zero);
4228 __ push(Immediate(0xFFF00000)); 4232 __ push(Immediate(0xFFF00000));
4229 __ push(Immediate(0)); 4233 __ push(Immediate(0));
4230 __ movdbl(input_reg, Operand(esp, 0)); 4234 __ movdbl(input_reg, Operand(esp, 0));
4231 __ add(Operand(esp), Immediate(kDoubleSize)); 4235 __ add(Operand(esp), Immediate(kDoubleSize));
4232 __ jmp(&done, Label::kNear); 4236 __ jmp(&done, Label::kNear);
4233 __ bind(&positive); 4237 __ bind(&positive);
4234 __ fldln2(); 4238 __ fldln2();
4235 __ sub(Operand(esp), Immediate(kDoubleSize)); 4239 __ sub(Operand(esp), Immediate(kDoubleSize));
4236 __ movdbl(Operand(esp, 0), input_reg); 4240 __ movdbl(Operand(esp, 0), input_reg);
4237 __ fld_d(Operand(esp, 0)); 4241 __ fld_d(Operand(esp, 0));
4238 __ fyl2x(); 4242 __ fyl2x();
4239 __ fstp_d(Operand(esp, 0)); 4243 __ fstp_d(Operand(esp, 0));
4240 __ movdbl(input_reg, Operand(esp, 0)); 4244 __ movdbl(input_reg, Operand(esp, 0));
4241 __ add(Operand(esp), Immediate(kDoubleSize)); 4245 __ add(Operand(esp), Immediate(kDoubleSize));
4242 __ bind(&done); 4246 __ bind(&done);
4243 } 4247 }
4244 4248
4245 4249
4246 void LCodeGen::DoMathExp(LMathExp* instr) { 4250 void LCodeGen::DoMathExp(LMathExp* instr) {
4247 CpuFeatureScope scope(masm(), SSE2); 4251 CpuFeatureScope scope(masm(), SSE2);
4248 XMMRegister input = ToDoubleRegister(instr->value()); 4252 XMMRegister input = ToDoubleRegister(instr->value());
4249 XMMRegister result = ToDoubleRegister(instr->result()); 4253 XMMRegister result = ToDoubleRegister(instr->result());
4254 XMMRegister temp0 = double_scratch0();
4250 Register temp1 = ToRegister(instr->temp1()); 4255 Register temp1 = ToRegister(instr->temp1());
4251 Register temp2 = ToRegister(instr->temp2()); 4256 Register temp2 = ToRegister(instr->temp2());
4252 4257
4253 MathExpGenerator::EmitMathExp(masm(), input, result, xmm0, temp1, temp2); 4258 MathExpGenerator::EmitMathExp(masm(), input, result, temp0, temp1, temp2);
4254 } 4259 }
4255 4260
4256 4261
4257 void LCodeGen::DoMathTan(LMathTan* instr) { 4262 void LCodeGen::DoMathTan(LMathTan* instr) {
4258 ASSERT(ToDoubleRegister(instr->result()).is(xmm1)); 4263 ASSERT(ToDoubleRegister(instr->result()).is(xmm1));
4259 // Set the context register to a GC-safe fake value. Clobbering it is 4264 // Set the context register to a GC-safe fake value. Clobbering it is
4260 // OK because this instruction is marked as a call. 4265 // OK because this instruction is marked as a call.
4261 __ Set(esi, Immediate(0)); 4266 __ Set(esi, Immediate(0));
4262 TranscendentalCacheStub stub(TranscendentalCache::TAN, 4267 TranscendentalCacheStub stub(TranscendentalCache::TAN,
4263 TranscendentalCacheStub::UNTAGGED); 4268 TranscendentalCacheStub::UNTAGGED);
(...skipping 360 matching lines...) Expand 10 before | Expand all | Expand 10 after
4624 Operand operand(BuildFastArrayOperand( 4629 Operand operand(BuildFastArrayOperand(
4625 instr->elements(), 4630 instr->elements(),
4626 key, 4631 key,
4627 instr->hydrogen()->key()->representation(), 4632 instr->hydrogen()->key()->representation(),
4628 elements_kind, 4633 elements_kind,
4629 0, 4634 0,
4630 instr->additional_index())); 4635 instr->additional_index()));
4631 if (elements_kind == EXTERNAL_FLOAT_ELEMENTS) { 4636 if (elements_kind == EXTERNAL_FLOAT_ELEMENTS) {
4632 if (CpuFeatures::IsSafeForSnapshot(SSE2)) { 4637 if (CpuFeatures::IsSafeForSnapshot(SSE2)) {
4633 CpuFeatureScope scope(masm(), SSE2); 4638 CpuFeatureScope scope(masm(), SSE2);
4634 __ cvtsd2ss(xmm0, ToDoubleRegister(instr->value())); 4639 XMMRegister xmm_scratch = double_scratch0();
4635 __ movss(operand, xmm0); 4640 __ cvtsd2ss(xmm_scratch, ToDoubleRegister(instr->value()));
4641 __ movss(operand, xmm_scratch);
4636 } else { 4642 } else {
4637 __ fld(0); 4643 __ fld(0);
4638 __ fstp_s(operand); 4644 __ fstp_s(operand);
4639 } 4645 }
4640 } else if (elements_kind == EXTERNAL_DOUBLE_ELEMENTS) { 4646 } else if (elements_kind == EXTERNAL_DOUBLE_ELEMENTS) {
4641 if (CpuFeatures::IsSafeForSnapshot(SSE2)) { 4647 if (CpuFeatures::IsSafeForSnapshot(SSE2)) {
4642 CpuFeatureScope scope(masm(), SSE2); 4648 CpuFeatureScope scope(masm(), SSE2);
4643 __ movdbl(operand, ToDoubleRegister(instr->value())); 4649 __ movdbl(operand, ToDoubleRegister(instr->value()));
4644 } else { 4650 } else {
4645 X87Mov(operand, ToX87Register(instr->value())); 4651 X87Mov(operand, ToX87Register(instr->value()));
(...skipping 442 matching lines...) Expand 10 before | Expand all | Expand 10 after
5088 __ bind(deferred->exit()); 5094 __ bind(deferred->exit());
5089 } 5095 }
5090 5096
5091 5097
5092 void LCodeGen::DoDeferredNumberTagI(LInstruction* instr, 5098 void LCodeGen::DoDeferredNumberTagI(LInstruction* instr,
5093 LOperand* value, 5099 LOperand* value,
5094 IntegerSignedness signedness) { 5100 IntegerSignedness signedness) {
5095 Label slow; 5101 Label slow;
5096 Register reg = ToRegister(value); 5102 Register reg = ToRegister(value);
5097 Register tmp = reg.is(eax) ? ecx : eax; 5103 Register tmp = reg.is(eax) ? ecx : eax;
5104 XMMRegister xmm_scratch = double_scratch0();
5098 5105
5099 // Preserve the value of all registers. 5106 // Preserve the value of all registers.
5100 PushSafepointRegistersScope scope(this); 5107 PushSafepointRegistersScope scope(this);
5101 5108
5102 Label done; 5109 Label done;
5103 5110
5104 if (signedness == SIGNED_INT32) { 5111 if (signedness == SIGNED_INT32) {
5105 // There was overflow, so bits 30 and 31 of the original integer 5112 // There was overflow, so bits 30 and 31 of the original integer
5106 // disagree. Try to allocate a heap number in new space and store 5113 // disagree. Try to allocate a heap number in new space and store
5107 // the value in there. If that fails, call the runtime system. 5114 // the value in there. If that fails, call the runtime system.
5108 __ SmiUntag(reg); 5115 __ SmiUntag(reg);
5109 __ xor_(reg, 0x80000000); 5116 __ xor_(reg, 0x80000000);
5110 if (CpuFeatures::IsSupported(SSE2)) { 5117 if (CpuFeatures::IsSupported(SSE2)) {
5111 CpuFeatureScope feature_scope(masm(), SSE2); 5118 CpuFeatureScope feature_scope(masm(), SSE2);
5112 __ Cvtsi2sd(xmm0, Operand(reg)); 5119 __ Cvtsi2sd(xmm_scratch, Operand(reg));
5113 } else { 5120 } else {
5114 __ push(reg); 5121 __ push(reg);
5115 __ fild_s(Operand(esp, 0)); 5122 __ fild_s(Operand(esp, 0));
5116 __ pop(reg); 5123 __ pop(reg);
5117 } 5124 }
5118 } else { 5125 } else {
5119 if (CpuFeatures::IsSupported(SSE2)) { 5126 if (CpuFeatures::IsSupported(SSE2)) {
5120 CpuFeatureScope feature_scope(masm(), SSE2); 5127 CpuFeatureScope feature_scope(masm(), SSE2);
5121 __ LoadUint32(xmm0, reg, 5128 __ LoadUint32(xmm_scratch, reg,
5122 ToDoubleRegister(LNumberTagU::cast(instr)->temp())); 5129 ToDoubleRegister(LNumberTagU::cast(instr)->temp()));
5123 } else { 5130 } else {
5124 // There's no fild variant for unsigned values, so zero-extend to a 64-bit 5131 // There's no fild variant for unsigned values, so zero-extend to a 64-bit
5125 // int manually. 5132 // int manually.
5126 __ push(Immediate(0)); 5133 __ push(Immediate(0));
5127 __ push(reg); 5134 __ push(reg);
5128 __ fild_d(Operand(esp, 0)); 5135 __ fild_d(Operand(esp, 0));
5129 __ pop(reg); 5136 __ pop(reg);
5130 __ pop(reg); 5137 __ pop(reg);
5131 } 5138 }
(...skipping 15 matching lines...) Expand all
5147 // the environment's HContext or HInlinedContext value. 5154 // the environment's HContext or HInlinedContext value.
5148 // They only call Runtime::kAllocateHeapNumber. 5155 // They only call Runtime::kAllocateHeapNumber.
5149 // The corresponding HChange instructions are added in a phase that does 5156 // The corresponding HChange instructions are added in a phase that does
5150 // not have easy access to the local context. 5157 // not have easy access to the local context.
5151 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); 5158 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset));
5152 __ CallRuntimeSaveDoubles(Runtime::kAllocateHeapNumber); 5159 __ CallRuntimeSaveDoubles(Runtime::kAllocateHeapNumber);
5153 RecordSafepointWithRegisters( 5160 RecordSafepointWithRegisters(
5154 instr->pointer_map(), 0, Safepoint::kNoLazyDeopt); 5161 instr->pointer_map(), 0, Safepoint::kNoLazyDeopt);
5155 if (!reg.is(eax)) __ mov(reg, eax); 5162 if (!reg.is(eax)) __ mov(reg, eax);
5156 5163
5157 // Done. Put the value in xmm0 into the value of the allocated heap 5164 // Done. Put the value in xmm_scratch into the value of the allocated heap
5158 // number. 5165 // number.
5159 __ bind(&done); 5166 __ bind(&done);
5160 if (CpuFeatures::IsSupported(SSE2)) { 5167 if (CpuFeatures::IsSupported(SSE2)) {
5161 CpuFeatureScope feature_scope(masm(), SSE2); 5168 CpuFeatureScope feature_scope(masm(), SSE2);
5162 __ movdbl(FieldOperand(reg, HeapNumber::kValueOffset), xmm0); 5169 __ movdbl(FieldOperand(reg, HeapNumber::kValueOffset), xmm_scratch);
5163 } else { 5170 } else {
5164 __ fstp_d(FieldOperand(reg, HeapNumber::kValueOffset)); 5171 __ fstp_d(FieldOperand(reg, HeapNumber::kValueOffset));
5165 } 5172 }
5166 __ StoreToSafepointRegisterSlot(reg, reg); 5173 __ StoreToSafepointRegisterSlot(reg, reg);
5167 } 5174 }
5168 5175
5169 5176
5170 void LCodeGen::DoNumberTagD(LNumberTagD* instr) { 5177 void LCodeGen::DoNumberTagD(LNumberTagD* instr) {
5171 class DeferredNumberTagD V8_FINAL : public LDeferredCode { 5178 class DeferredNumberTagD V8_FINAL : public LDeferredCode {
5172 public: 5179 public:
(...skipping 169 matching lines...) Expand 10 before | Expand all | Expand 10 after
5342 if (can_convert_undefined_to_nan) { 5349 if (can_convert_undefined_to_nan) {
5343 __ j(not_equal, &convert, Label::kNear); 5350 __ j(not_equal, &convert, Label::kNear);
5344 } else { 5351 } else {
5345 DeoptimizeIf(not_equal, env); 5352 DeoptimizeIf(not_equal, env);
5346 } 5353 }
5347 5354
5348 // Heap number to XMM conversion. 5355 // Heap number to XMM conversion.
5349 __ movdbl(result_reg, FieldOperand(input_reg, HeapNumber::kValueOffset)); 5356 __ movdbl(result_reg, FieldOperand(input_reg, HeapNumber::kValueOffset));
5350 5357
5351 if (deoptimize_on_minus_zero) { 5358 if (deoptimize_on_minus_zero) {
5352 XMMRegister xmm_scratch = xmm0; 5359 XMMRegister xmm_scratch = double_scratch0();
5353 __ xorps(xmm_scratch, xmm_scratch); 5360 __ xorps(xmm_scratch, xmm_scratch);
5354 __ ucomisd(result_reg, xmm_scratch); 5361 __ ucomisd(result_reg, xmm_scratch);
5355 __ j(not_zero, &done, Label::kNear); 5362 __ j(not_zero, &done, Label::kNear);
5356 __ movmskpd(temp_reg, result_reg); 5363 __ movmskpd(temp_reg, result_reg);
5357 __ test_b(temp_reg, 1); 5364 __ test_b(temp_reg, 1);
5358 DeoptimizeIf(not_zero, env); 5365 DeoptimizeIf(not_zero, env);
5359 } 5366 }
5360 __ jmp(&done, Label::kNear); 5367 __ jmp(&done, Label::kNear);
5361 5368
5362 if (can_convert_undefined_to_nan) { 5369 if (can_convert_undefined_to_nan) {
(...skipping 145 matching lines...) Expand 10 before | Expand all | Expand 10 after
5508 } else { 5515 } else {
5509 X87Register input_reg = ToX87Register(input); 5516 X87Register input_reg = ToX87Register(input);
5510 X87Fxch(input_reg); 5517 X87Fxch(input_reg);
5511 __ TruncateX87TOSToI(result_reg); 5518 __ TruncateX87TOSToI(result_reg);
5512 } 5519 }
5513 } else { 5520 } else {
5514 Label bailout, done; 5521 Label bailout, done;
5515 if (CpuFeatures::IsSafeForSnapshot(SSE2)) { 5522 if (CpuFeatures::IsSafeForSnapshot(SSE2)) {
5516 CpuFeatureScope scope(masm(), SSE2); 5523 CpuFeatureScope scope(masm(), SSE2);
5517 XMMRegister input_reg = ToDoubleRegister(input); 5524 XMMRegister input_reg = ToDoubleRegister(input);
5518 __ DoubleToI(result_reg, input_reg, xmm0, 5525 XMMRegister xmm_scratch = double_scratch0();
5526 __ DoubleToI(result_reg, input_reg, xmm_scratch,
5519 instr->hydrogen()->GetMinusZeroMode(), &bailout, Label::kNear); 5527 instr->hydrogen()->GetMinusZeroMode(), &bailout, Label::kNear);
5520 } else { 5528 } else {
5521 X87Register input_reg = ToX87Register(input); 5529 X87Register input_reg = ToX87Register(input);
5522 X87Fxch(input_reg); 5530 X87Fxch(input_reg);
5523 __ X87TOSToI(result_reg, instr->hydrogen()->GetMinusZeroMode(), 5531 __ X87TOSToI(result_reg, instr->hydrogen()->GetMinusZeroMode(),
5524 &bailout, Label::kNear); 5532 &bailout, Label::kNear);
5525 } 5533 }
5526 __ jmp(&done, Label::kNear); 5534 __ jmp(&done, Label::kNear);
5527 __ bind(&bailout); 5535 __ bind(&bailout);
5528 DeoptimizeIf(no_condition, instr->environment()); 5536 DeoptimizeIf(no_condition, instr->environment());
5529 __ bind(&done); 5537 __ bind(&done);
5530 } 5538 }
5531 } 5539 }
5532 5540
5533 5541
5534 void LCodeGen::DoDoubleToSmi(LDoubleToSmi* instr) { 5542 void LCodeGen::DoDoubleToSmi(LDoubleToSmi* instr) {
5535 LOperand* input = instr->value(); 5543 LOperand* input = instr->value();
5536 ASSERT(input->IsDoubleRegister()); 5544 ASSERT(input->IsDoubleRegister());
5537 LOperand* result = instr->result(); 5545 LOperand* result = instr->result();
5538 ASSERT(result->IsRegister()); 5546 ASSERT(result->IsRegister());
5539 Register result_reg = ToRegister(result); 5547 Register result_reg = ToRegister(result);
5540 5548
5541 Label bailout, done; 5549 Label bailout, done;
5542 if (CpuFeatures::IsSafeForSnapshot(SSE2)) { 5550 if (CpuFeatures::IsSafeForSnapshot(SSE2)) {
5543 CpuFeatureScope scope(masm(), SSE2); 5551 CpuFeatureScope scope(masm(), SSE2);
5544 XMMRegister input_reg = ToDoubleRegister(input); 5552 XMMRegister input_reg = ToDoubleRegister(input);
5545 __ DoubleToI(result_reg, input_reg, xmm0, 5553 XMMRegister xmm_scratch = double_scratch0();
5554 __ DoubleToI(result_reg, input_reg, xmm_scratch,
5546 instr->hydrogen()->GetMinusZeroMode(), &bailout, Label::kNear); 5555 instr->hydrogen()->GetMinusZeroMode(), &bailout, Label::kNear);
5547 } else { 5556 } else {
5548 X87Register input_reg = ToX87Register(input); 5557 X87Register input_reg = ToX87Register(input);
5549 X87Fxch(input_reg); 5558 X87Fxch(input_reg);
5550 __ X87TOSToI(result_reg, instr->hydrogen()->GetMinusZeroMode(), 5559 __ X87TOSToI(result_reg, instr->hydrogen()->GetMinusZeroMode(),
5551 &bailout, Label::kNear); 5560 &bailout, Label::kNear);
5552 } 5561 }
5553 __ jmp(&done, Label::kNear); 5562 __ jmp(&done, Label::kNear);
5554 __ bind(&bailout); 5563 __ bind(&bailout);
5555 DeoptimizeIf(no_condition, instr->environment()); 5564 DeoptimizeIf(no_condition, instr->environment());
(...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after
5699 DeoptimizeIf(not_equal, instr->environment()); 5708 DeoptimizeIf(not_equal, instr->environment());
5700 } 5709 }
5701 5710
5702 __ bind(&success); 5711 __ bind(&success);
5703 } 5712 }
5704 5713
5705 5714
5706 void LCodeGen::DoClampDToUint8(LClampDToUint8* instr) { 5715 void LCodeGen::DoClampDToUint8(LClampDToUint8* instr) {
5707 CpuFeatureScope scope(masm(), SSE2); 5716 CpuFeatureScope scope(masm(), SSE2);
5708 XMMRegister value_reg = ToDoubleRegister(instr->unclamped()); 5717 XMMRegister value_reg = ToDoubleRegister(instr->unclamped());
5718 XMMRegister xmm_scratch = double_scratch0();
5709 Register result_reg = ToRegister(instr->result()); 5719 Register result_reg = ToRegister(instr->result());
5710 __ ClampDoubleToUint8(value_reg, xmm0, result_reg); 5720 __ ClampDoubleToUint8(value_reg, xmm_scratch, result_reg);
5711 } 5721 }
5712 5722
5713 5723
5714 void LCodeGen::DoClampIToUint8(LClampIToUint8* instr) { 5724 void LCodeGen::DoClampIToUint8(LClampIToUint8* instr) {
5715 ASSERT(instr->unclamped()->Equals(instr->result())); 5725 ASSERT(instr->unclamped()->Equals(instr->result()));
5716 Register value_reg = ToRegister(instr->result()); 5726 Register value_reg = ToRegister(instr->result());
5717 __ ClampUint8(value_reg); 5727 __ ClampUint8(value_reg);
5718 } 5728 }
5719 5729
5720 5730
5721 void LCodeGen::DoClampTToUint8(LClampTToUint8* instr) { 5731 void LCodeGen::DoClampTToUint8(LClampTToUint8* instr) {
5722 CpuFeatureScope scope(masm(), SSE2); 5732 CpuFeatureScope scope(masm(), SSE2);
5723 5733
5724 ASSERT(instr->unclamped()->Equals(instr->result())); 5734 ASSERT(instr->unclamped()->Equals(instr->result()));
5725 Register input_reg = ToRegister(instr->unclamped()); 5735 Register input_reg = ToRegister(instr->unclamped());
5736 XMMRegister xmm_scratch = double_scratch0();
5726 Label is_smi, done, heap_number; 5737 Label is_smi, done, heap_number;
5727 5738
5728 __ JumpIfSmi(input_reg, &is_smi); 5739 __ JumpIfSmi(input_reg, &is_smi);
5729 5740
5730 // Check for heap number 5741 // Check for heap number
5731 __ cmp(FieldOperand(input_reg, HeapObject::kMapOffset), 5742 __ cmp(FieldOperand(input_reg, HeapObject::kMapOffset),
5732 factory()->heap_number_map()); 5743 factory()->heap_number_map());
5733 __ j(equal, &heap_number, Label::kNear); 5744 __ j(equal, &heap_number, Label::kNear);
5734 5745
5735 // Check for undefined. Undefined is converted to zero for clamping 5746 // Check for undefined. Undefined is converted to zero for clamping
5736 // conversions. 5747 // conversions.
5737 __ cmp(input_reg, factory()->undefined_value()); 5748 __ cmp(input_reg, factory()->undefined_value());
5738 DeoptimizeIf(not_equal, instr->environment()); 5749 DeoptimizeIf(not_equal, instr->environment());
5739 __ mov(input_reg, 0); 5750 __ mov(input_reg, 0);
5740 __ jmp(&done, Label::kNear); 5751 __ jmp(&done, Label::kNear);
5741 5752
5742 // Heap number 5753 // Heap number
5743 __ bind(&heap_number); 5754 __ bind(&heap_number);
5744 __ movdbl(xmm0, FieldOperand(input_reg, HeapNumber::kValueOffset)); 5755 __ movdbl(xmm_scratch, FieldOperand(input_reg, HeapNumber::kValueOffset));
5745 __ ClampDoubleToUint8(xmm0, xmm1, input_reg); 5756 __ ClampDoubleToUint8(xmm_scratch, xmm1, input_reg);
5746 __ jmp(&done, Label::kNear); 5757 __ jmp(&done, Label::kNear);
5747 5758
5748 // smi 5759 // smi
5749 __ bind(&is_smi); 5760 __ bind(&is_smi);
5750 __ SmiUntag(input_reg); 5761 __ SmiUntag(input_reg);
5751 __ ClampUint8(input_reg); 5762 __ ClampUint8(input_reg);
5752 __ bind(&done); 5763 __ bind(&done);
5753 } 5764 }
5754 5765
5755 5766
(...skipping 628 matching lines...) Expand 10 before | Expand all | Expand 10 after
6384 FixedArray::kHeaderSize - kPointerSize)); 6395 FixedArray::kHeaderSize - kPointerSize));
6385 __ bind(&done); 6396 __ bind(&done);
6386 } 6397 }
6387 6398
6388 6399
6389 #undef __ 6400 #undef __
6390 6401
6391 } } // namespace v8::internal 6402 } } // namespace v8::internal
6392 6403
6393 #endif // V8_TARGET_ARCH_IA32 6404 #endif // V8_TARGET_ARCH_IA32
OLDNEW
« no previous file with comments | « src/ia32/lithium-codegen-ia32.h ('k') | src/x64/lithium-codegen-x64.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698