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

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

Issue 146213004: A64: Synchronize with r16849. (Closed) Base URL: https://v8.googlecode.com/svn/branches/experimental/a64
Patch Set: Created 6 years, 10 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/ia32/lithium-ia32.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 322 matching lines...) Expand 10 before | Expand all | Expand 10 after
333 } 333 }
334 334
335 335
336 void LCodeGen::GenerateOsrPrologue() { 336 void LCodeGen::GenerateOsrPrologue() {
337 // Generate the OSR entry prologue at the first unknown OSR value, or if there 337 // Generate the OSR entry prologue at the first unknown OSR value, or if there
338 // are none, at the OSR entrypoint instruction. 338 // are none, at the OSR entrypoint instruction.
339 if (osr_pc_offset_ >= 0) return; 339 if (osr_pc_offset_ >= 0) return;
340 340
341 osr_pc_offset_ = masm()->pc_offset(); 341 osr_pc_offset_ = masm()->pc_offset();
342 342
343 // Move state of dynamic frame alignment into edx.
344 __ mov(edx, Immediate(kNoAlignmentPadding));
345
346 if (support_aligned_spilled_doubles_ && dynamic_frame_alignment_) {
347 Label do_not_pad, align_loop;
348 // Align ebp + 4 to a multiple of 2 * kPointerSize.
349 __ test(ebp, Immediate(kPointerSize));
350 __ j(zero, &do_not_pad, Label::kNear);
351 __ push(Immediate(0));
352 __ mov(ebx, esp);
353 __ mov(edx, Immediate(kAlignmentPaddingPushed));
354
355 // Move all parts of the frame over one word. The frame consists of:
356 // unoptimized frame slots, alignment state, context, frame pointer, return
357 // address, receiver, and the arguments.
358 __ mov(ecx, Immediate(scope()->num_parameters() +
359 5 + graph()->osr()->UnoptimizedFrameSlots()));
360
361 __ bind(&align_loop);
362 __ mov(eax, Operand(ebx, 1 * kPointerSize));
363 __ mov(Operand(ebx, 0), eax);
364 __ add(Operand(ebx), Immediate(kPointerSize));
365 __ dec(ecx);
366 __ j(not_zero, &align_loop, Label::kNear);
367 __ mov(Operand(ebx, 0), Immediate(kAlignmentZapValue));
368 __ sub(Operand(ebp), Immediate(kPointerSize));
369 __ bind(&do_not_pad);
370 }
371
343 // Save the first local, which is overwritten by the alignment state. 372 // Save the first local, which is overwritten by the alignment state.
344 Operand alignment_loc = MemOperand(ebp, -3 * kPointerSize); 373 Operand alignment_loc = MemOperand(ebp, -3 * kPointerSize);
345 __ push(alignment_loc); 374 __ push(alignment_loc);
346 375
347 // Set the dynamic frame alignment state to "not aligned". 376 // Set the dynamic frame alignment state.
348 __ mov(alignment_loc, Immediate(kNoAlignmentPadding)); 377 __ mov(alignment_loc, edx);
349 378
350 // Adjust the frame size, subsuming the unoptimized frame into the 379 // Adjust the frame size, subsuming the unoptimized frame into the
351 // optimized frame. 380 // optimized frame.
352 int slots = GetStackSlotCount() - graph()->osr()->UnoptimizedFrameSlots(); 381 int slots = GetStackSlotCount() - graph()->osr()->UnoptimizedFrameSlots();
353 ASSERT(slots >= 1); 382 ASSERT(slots >= 1);
354 __ sub(esp, Immediate((slots - 1) * kPointerSize)); 383 __ sub(esp, Immediate((slots - 1) * kPointerSize));
355 } 384 }
356 385
357 386
358 bool LCodeGen::GenerateBody() { 387 bool LCodeGen::GenerateBody() {
(...skipping 1601 matching lines...) Expand 10 before | Expand all | Expand 10 after
1960 } else { 1989 } else {
1961 __ xorps(res, res); 1990 __ xorps(res, res);
1962 __ Set(temp, Immediate(upper)); 1991 __ Set(temp, Immediate(upper));
1963 __ pinsrd(res, Operand(temp), 1); 1992 __ pinsrd(res, Operand(temp), 1);
1964 } 1993 }
1965 } else { 1994 } else {
1966 __ Set(temp, Immediate(upper)); 1995 __ Set(temp, Immediate(upper));
1967 __ movd(res, Operand(temp)); 1996 __ movd(res, Operand(temp));
1968 __ psllq(res, 32); 1997 __ psllq(res, 32);
1969 if (lower != 0) { 1998 if (lower != 0) {
1999 XMMRegister xmm_scratch = double_scratch0();
1970 __ Set(temp, Immediate(lower)); 2000 __ Set(temp, Immediate(lower));
1971 __ movd(xmm0, Operand(temp)); 2001 __ movd(xmm_scratch, Operand(temp));
1972 __ por(res, xmm0); 2002 __ por(res, xmm_scratch);
1973 } 2003 }
1974 } 2004 }
1975 } 2005 }
1976 } 2006 }
1977 } 2007 }
1978 2008
1979 2009
1980 void LCodeGen::DoConstantE(LConstantE* instr) { 2010 void LCodeGen::DoConstantE(LConstantE* instr) {
1981 __ lea(ToRegister(instr->result()), Operand::StaticVariable(instr->value())); 2011 __ lea(ToRegister(instr->result()), Operand::StaticVariable(instr->value()));
1982 } 2012 }
(...skipping 188 matching lines...) Expand 10 before | Expand all | Expand 10 after
2171 Condition condition = (operation == HMathMinMax::kMathMin) ? below : above; 2201 Condition condition = (operation == HMathMinMax::kMathMin) ? below : above;
2172 XMMRegister left_reg = ToDoubleRegister(left); 2202 XMMRegister left_reg = ToDoubleRegister(left);
2173 XMMRegister right_reg = ToDoubleRegister(right); 2203 XMMRegister right_reg = ToDoubleRegister(right);
2174 __ ucomisd(left_reg, right_reg); 2204 __ ucomisd(left_reg, right_reg);
2175 __ 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.
2176 __ j(equal, &check_zero, Label::kNear); // left == right. 2206 __ j(equal, &check_zero, Label::kNear); // left == right.
2177 __ j(condition, &return_left, Label::kNear); 2207 __ j(condition, &return_left, Label::kNear);
2178 __ jmp(&return_right, Label::kNear); 2208 __ jmp(&return_right, Label::kNear);
2179 2209
2180 __ bind(&check_zero); 2210 __ bind(&check_zero);
2181 XMMRegister xmm_scratch = xmm0; 2211 XMMRegister xmm_scratch = double_scratch0();
2182 __ xorps(xmm_scratch, xmm_scratch); 2212 __ xorps(xmm_scratch, xmm_scratch);
2183 __ ucomisd(left_reg, xmm_scratch); 2213 __ ucomisd(left_reg, xmm_scratch);
2184 __ j(not_equal, &return_left, Label::kNear); // left == right != 0. 2214 __ j(not_equal, &return_left, Label::kNear); // left == right != 0.
2185 // 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.
2186 if (operation == HMathMinMax::kMathMin) { 2216 if (operation == HMathMinMax::kMathMin) {
2187 __ orpd(left_reg, right_reg); 2217 __ orpd(left_reg, right_reg);
2188 } else { 2218 } else {
2189 // 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.
2190 __ addsd(left_reg, right_reg); 2220 __ addsd(left_reg, right_reg);
2191 } 2221 }
(...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after
2331 void LCodeGen::EmitFalseBranch(InstrType instr, Condition cc) { 2361 void LCodeGen::EmitFalseBranch(InstrType instr, Condition cc) {
2332 int false_block = instr->FalseDestination(chunk_); 2362 int false_block = instr->FalseDestination(chunk_);
2333 if (cc == no_condition) { 2363 if (cc == no_condition) {
2334 __ jmp(chunk_->GetAssemblyLabel(false_block)); 2364 __ jmp(chunk_->GetAssemblyLabel(false_block));
2335 } else { 2365 } else {
2336 __ j(cc, chunk_->GetAssemblyLabel(false_block)); 2366 __ j(cc, chunk_->GetAssemblyLabel(false_block));
2337 } 2367 }
2338 } 2368 }
2339 2369
2340 2370
2341 void LCodeGen::DoIsNumberAndBranch(LIsNumberAndBranch* instr) {
2342 Representation r = instr->hydrogen()->value()->representation();
2343 if (r.IsSmiOrInteger32() || r.IsDouble()) {
2344 EmitBranch(instr, no_condition);
2345 } else {
2346 ASSERT(r.IsTagged());
2347 Register reg = ToRegister(instr->value());
2348 HType type = instr->hydrogen()->value()->type();
2349 if (type.IsTaggedNumber()) {
2350 EmitBranch(instr, no_condition);
2351 }
2352 __ JumpIfSmi(reg, instr->TrueLabel(chunk_));
2353 __ cmp(FieldOperand(reg, HeapObject::kMapOffset),
2354 factory()->heap_number_map());
2355 EmitBranch(instr, equal);
2356 }
2357 }
2358
2359
2360 void LCodeGen::DoBranch(LBranch* instr) { 2371 void LCodeGen::DoBranch(LBranch* instr) {
2361 Representation r = instr->hydrogen()->value()->representation(); 2372 Representation r = instr->hydrogen()->value()->representation();
2362 if (r.IsSmiOrInteger32()) { 2373 if (r.IsSmiOrInteger32()) {
2363 Register reg = ToRegister(instr->value()); 2374 Register reg = ToRegister(instr->value());
2364 __ test(reg, Operand(reg)); 2375 __ test(reg, Operand(reg));
2365 EmitBranch(instr, not_zero); 2376 EmitBranch(instr, not_zero);
2366 } else if (r.IsDouble()) { 2377 } else if (r.IsDouble()) {
2367 ASSERT(!info()->IsStub()); 2378 ASSERT(!info()->IsStub());
2368 CpuFeatureScope scope(masm(), SSE2); 2379 CpuFeatureScope scope(masm(), SSE2);
2369 XMMRegister reg = ToDoubleRegister(instr->value()); 2380 XMMRegister reg = ToDoubleRegister(instr->value());
2370 __ xorps(xmm0, xmm0); 2381 XMMRegister xmm_scratch = double_scratch0();
2371 __ ucomisd(reg, xmm0); 2382 __ xorps(xmm_scratch, xmm_scratch);
2383 __ ucomisd(reg, xmm_scratch);
2372 EmitBranch(instr, not_equal); 2384 EmitBranch(instr, not_equal);
2373 } else { 2385 } else {
2374 ASSERT(r.IsTagged()); 2386 ASSERT(r.IsTagged());
2375 Register reg = ToRegister(instr->value()); 2387 Register reg = ToRegister(instr->value());
2376 HType type = instr->hydrogen()->value()->type(); 2388 HType type = instr->hydrogen()->value()->type();
2377 if (type.IsBoolean()) { 2389 if (type.IsBoolean()) {
2378 ASSERT(!info()->IsStub()); 2390 ASSERT(!info()->IsStub());
2379 __ cmp(reg, factory()->true_value()); 2391 __ cmp(reg, factory()->true_value());
2380 EmitBranch(instr, equal); 2392 EmitBranch(instr, equal);
2381 } else if (type.IsSmi()) { 2393 } else if (type.IsSmi()) {
2382 ASSERT(!info()->IsStub()); 2394 ASSERT(!info()->IsStub());
2383 __ test(reg, Operand(reg)); 2395 __ test(reg, Operand(reg));
2384 EmitBranch(instr, not_equal); 2396 EmitBranch(instr, not_equal);
2385 } else if (type.IsJSArray()) { 2397 } else if (type.IsJSArray()) {
2386 ASSERT(!info()->IsStub()); 2398 ASSERT(!info()->IsStub());
2387 EmitBranch(instr, no_condition); 2399 EmitBranch(instr, no_condition);
2388 } else if (type.IsHeapNumber()) { 2400 } else if (type.IsHeapNumber()) {
2389 ASSERT(!info()->IsStub()); 2401 ASSERT(!info()->IsStub());
2390 CpuFeatureScope scope(masm(), SSE2); 2402 CpuFeatureScope scope(masm(), SSE2);
2391 __ xorps(xmm0, xmm0); 2403 XMMRegister xmm_scratch = double_scratch0();
2392 __ ucomisd(xmm0, FieldOperand(reg, HeapNumber::kValueOffset)); 2404 __ xorps(xmm_scratch, xmm_scratch);
2405 __ ucomisd(xmm_scratch, FieldOperand(reg, HeapNumber::kValueOffset));
2393 EmitBranch(instr, not_equal); 2406 EmitBranch(instr, not_equal);
2394 } else if (type.IsString()) { 2407 } else if (type.IsString()) {
2395 ASSERT(!info()->IsStub()); 2408 ASSERT(!info()->IsStub());
2396 __ cmp(FieldOperand(reg, String::kLengthOffset), Immediate(0)); 2409 __ cmp(FieldOperand(reg, String::kLengthOffset), Immediate(0));
2397 EmitBranch(instr, not_equal); 2410 EmitBranch(instr, not_equal);
2398 } else { 2411 } else {
2399 ToBooleanStub::Types expected = instr->hydrogen()->expected_input_types(); 2412 ToBooleanStub::Types expected = instr->hydrogen()->expected_input_types();
2400 if (expected.IsEmpty()) expected = ToBooleanStub::Types::Generic(); 2413 if (expected.IsEmpty()) expected = ToBooleanStub::Types::Generic();
2401 2414
2402 if (expected.Contains(ToBooleanStub::UNDEFINED)) { 2415 if (expected.Contains(ToBooleanStub::UNDEFINED)) {
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
2467 } 2480 }
2468 2481
2469 if (expected.Contains(ToBooleanStub::HEAP_NUMBER)) { 2482 if (expected.Contains(ToBooleanStub::HEAP_NUMBER)) {
2470 // heap number -> false iff +0, -0, or NaN. 2483 // heap number -> false iff +0, -0, or NaN.
2471 Label not_heap_number; 2484 Label not_heap_number;
2472 __ cmp(FieldOperand(reg, HeapObject::kMapOffset), 2485 __ cmp(FieldOperand(reg, HeapObject::kMapOffset),
2473 factory()->heap_number_map()); 2486 factory()->heap_number_map());
2474 __ j(not_equal, &not_heap_number, Label::kNear); 2487 __ j(not_equal, &not_heap_number, Label::kNear);
2475 if (CpuFeatures::IsSafeForSnapshot(SSE2)) { 2488 if (CpuFeatures::IsSafeForSnapshot(SSE2)) {
2476 CpuFeatureScope scope(masm(), SSE2); 2489 CpuFeatureScope scope(masm(), SSE2);
2477 __ xorps(xmm0, xmm0); 2490 XMMRegister xmm_scratch = double_scratch0();
2478 __ ucomisd(xmm0, FieldOperand(reg, HeapNumber::kValueOffset)); 2491 __ xorps(xmm_scratch, xmm_scratch);
2492 __ ucomisd(xmm_scratch, FieldOperand(reg, HeapNumber::kValueOffset));
2479 } else { 2493 } else {
2480 __ fldz(); 2494 __ fldz();
2481 __ fld_d(FieldOperand(reg, HeapNumber::kValueOffset)); 2495 __ fld_d(FieldOperand(reg, HeapNumber::kValueOffset));
2482 __ FCmp(); 2496 __ FCmp();
2483 } 2497 }
2484 __ j(zero, instr->FalseLabel(chunk_)); 2498 __ j(zero, instr->FalseLabel(chunk_));
2485 __ jmp(instr->TrueLabel(chunk_)); 2499 __ jmp(instr->TrueLabel(chunk_));
2486 __ bind(&not_heap_number); 2500 __ bind(&not_heap_number);
2487 } 2501 }
2488 2502
(...skipping 859 matching lines...) Expand 10 before | Expand all | Expand 10 after
3348 // Non-instance prototype: Fetch prototype from constructor field 3362 // Non-instance prototype: Fetch prototype from constructor field
3349 // in the function's map. 3363 // in the function's map.
3350 __ bind(&non_instance); 3364 __ bind(&non_instance);
3351 __ mov(result, FieldOperand(result, Map::kConstructorOffset)); 3365 __ mov(result, FieldOperand(result, Map::kConstructorOffset));
3352 3366
3353 // All done. 3367 // All done.
3354 __ bind(&done); 3368 __ bind(&done);
3355 } 3369 }
3356 3370
3357 3371
3372 void LCodeGen::DoLoadRoot(LLoadRoot* instr) {
3373 Register result = ToRegister(instr->result());
3374 __ LoadRoot(result, instr->index());
3375 }
3376
3377
3358 void LCodeGen::DoLoadExternalArrayPointer( 3378 void LCodeGen::DoLoadExternalArrayPointer(
3359 LLoadExternalArrayPointer* instr) { 3379 LLoadExternalArrayPointer* instr) {
3360 Register result = ToRegister(instr->result()); 3380 Register result = ToRegister(instr->result());
3361 Register input = ToRegister(instr->object()); 3381 Register input = ToRegister(instr->object());
3362 __ mov(result, FieldOperand(input, 3382 __ mov(result, FieldOperand(input,
3363 ExternalArray::kExternalPointerOffset)); 3383 ExternalArray::kExternalPointerOffset));
3364 } 3384 }
3365 3385
3366 3386
3367 void LCodeGen::DoAccessArgumentsAt(LAccessArgumentsAt* instr) { 3387 void LCodeGen::DoAccessArgumentsAt(LAccessArgumentsAt* instr) {
(...skipping 534 matching lines...) Expand 10 before | Expand all | Expand 10 after
3902 virtual LInstruction* instr() V8_OVERRIDE { return instr_; } 3922 virtual LInstruction* instr() V8_OVERRIDE { return instr_; }
3903 private: 3923 private:
3904 LMathAbs* instr_; 3924 LMathAbs* instr_;
3905 }; 3925 };
3906 3926
3907 ASSERT(instr->value()->Equals(instr->result())); 3927 ASSERT(instr->value()->Equals(instr->result()));
3908 Representation r = instr->hydrogen()->value()->representation(); 3928 Representation r = instr->hydrogen()->value()->representation();
3909 3929
3910 CpuFeatureScope scope(masm(), SSE2); 3930 CpuFeatureScope scope(masm(), SSE2);
3911 if (r.IsDouble()) { 3931 if (r.IsDouble()) {
3912 XMMRegister scratch = xmm0; 3932 XMMRegister scratch = double_scratch0();
3913 XMMRegister input_reg = ToDoubleRegister(instr->value()); 3933 XMMRegister input_reg = ToDoubleRegister(instr->value());
3914 __ xorps(scratch, scratch); 3934 __ xorps(scratch, scratch);
3915 __ subsd(scratch, input_reg); 3935 __ subsd(scratch, input_reg);
3916 __ pand(input_reg, scratch); 3936 __ pand(input_reg, scratch);
3917 } else if (r.IsSmiOrInteger32()) { 3937 } else if (r.IsSmiOrInteger32()) {
3918 EmitIntegerMathAbs(instr); 3938 EmitIntegerMathAbs(instr);
3919 } else { // Tagged case. 3939 } else { // Tagged case.
3920 DeferredMathAbsTaggedHeapNumber* deferred = 3940 DeferredMathAbsTaggedHeapNumber* deferred =
3921 new(zone()) DeferredMathAbsTaggedHeapNumber(this, instr, x87_stack_); 3941 new(zone()) DeferredMathAbsTaggedHeapNumber(this, instr, x87_stack_);
3922 Register input_reg = ToRegister(instr->value()); 3942 Register input_reg = ToRegister(instr->value());
3923 // Smi check. 3943 // Smi check.
3924 __ JumpIfNotSmi(input_reg, deferred->entry()); 3944 __ JumpIfNotSmi(input_reg, deferred->entry());
3925 EmitIntegerMathAbs(instr); 3945 EmitIntegerMathAbs(instr);
3926 __ bind(deferred->exit()); 3946 __ bind(deferred->exit());
3927 } 3947 }
3928 } 3948 }
3929 3949
3930 3950
3931 void LCodeGen::DoMathFloor(LMathFloor* instr) { 3951 void LCodeGen::DoMathFloor(LMathFloor* instr) {
3932 CpuFeatureScope scope(masm(), SSE2); 3952 CpuFeatureScope scope(masm(), SSE2);
3933 XMMRegister xmm_scratch = xmm0; 3953 XMMRegister xmm_scratch = double_scratch0();
3934 Register output_reg = ToRegister(instr->result()); 3954 Register output_reg = ToRegister(instr->result());
3935 XMMRegister input_reg = ToDoubleRegister(instr->value()); 3955 XMMRegister input_reg = ToDoubleRegister(instr->value());
3936 3956
3937 if (CpuFeatures::IsSupported(SSE4_1)) { 3957 if (CpuFeatures::IsSupported(SSE4_1)) {
3938 CpuFeatureScope scope(masm(), SSE4_1); 3958 CpuFeatureScope scope(masm(), SSE4_1);
3939 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { 3959 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
3940 // Deoptimize on negative zero. 3960 // Deoptimize on negative zero.
3941 Label non_zero; 3961 Label non_zero;
3942 __ xorps(xmm_scratch, xmm_scratch); // Zero the register. 3962 __ xorps(xmm_scratch, xmm_scratch); // Zero the register.
3943 __ ucomisd(input_reg, xmm_scratch); 3963 __ ucomisd(input_reg, xmm_scratch);
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
3991 4011
3992 __ bind(&done); 4012 __ bind(&done);
3993 } 4013 }
3994 } 4014 }
3995 4015
3996 4016
3997 void LCodeGen::DoMathRound(LMathRound* instr) { 4017 void LCodeGen::DoMathRound(LMathRound* instr) {
3998 CpuFeatureScope scope(masm(), SSE2); 4018 CpuFeatureScope scope(masm(), SSE2);
3999 Register output_reg = ToRegister(instr->result()); 4019 Register output_reg = ToRegister(instr->result());
4000 XMMRegister input_reg = ToDoubleRegister(instr->value()); 4020 XMMRegister input_reg = ToDoubleRegister(instr->value());
4001 XMMRegister xmm_scratch = xmm0; 4021 XMMRegister xmm_scratch = double_scratch0();
4002 XMMRegister input_temp = ToDoubleRegister(instr->temp()); 4022 XMMRegister input_temp = ToDoubleRegister(instr->temp());
4003 ExternalReference one_half = ExternalReference::address_of_one_half(); 4023 ExternalReference one_half = ExternalReference::address_of_one_half();
4004 ExternalReference minus_one_half = 4024 ExternalReference minus_one_half =
4005 ExternalReference::address_of_minus_one_half(); 4025 ExternalReference::address_of_minus_one_half();
4006 4026
4007 Label done, round_to_zero, below_one_half, do_not_compensate; 4027 Label done, round_to_zero, below_one_half, do_not_compensate;
4008 __ movdbl(xmm_scratch, Operand::StaticVariable(one_half)); 4028 __ movdbl(xmm_scratch, Operand::StaticVariable(one_half));
4009 __ ucomisd(xmm_scratch, input_reg); 4029 __ ucomisd(xmm_scratch, input_reg);
4010 __ j(above, &below_one_half); 4030 __ j(above, &below_one_half);
4011 4031
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
4058 void LCodeGen::DoMathSqrt(LMathSqrt* instr) { 4078 void LCodeGen::DoMathSqrt(LMathSqrt* instr) {
4059 CpuFeatureScope scope(masm(), SSE2); 4079 CpuFeatureScope scope(masm(), SSE2);
4060 XMMRegister input_reg = ToDoubleRegister(instr->value()); 4080 XMMRegister input_reg = ToDoubleRegister(instr->value());
4061 ASSERT(ToDoubleRegister(instr->result()).is(input_reg)); 4081 ASSERT(ToDoubleRegister(instr->result()).is(input_reg));
4062 __ sqrtsd(input_reg, input_reg); 4082 __ sqrtsd(input_reg, input_reg);
4063 } 4083 }
4064 4084
4065 4085
4066 void LCodeGen::DoMathPowHalf(LMathPowHalf* instr) { 4086 void LCodeGen::DoMathPowHalf(LMathPowHalf* instr) {
4067 CpuFeatureScope scope(masm(), SSE2); 4087 CpuFeatureScope scope(masm(), SSE2);
4068 XMMRegister xmm_scratch = xmm0; 4088 XMMRegister xmm_scratch = double_scratch0();
4069 XMMRegister input_reg = ToDoubleRegister(instr->value()); 4089 XMMRegister input_reg = ToDoubleRegister(instr->value());
4070 Register scratch = ToRegister(instr->temp()); 4090 Register scratch = ToRegister(instr->temp());
4071 ASSERT(ToDoubleRegister(instr->result()).is(input_reg)); 4091 ASSERT(ToDoubleRegister(instr->result()).is(input_reg));
4072 4092
4073 // Note that according to ECMA-262 15.8.2.13: 4093 // Note that according to ECMA-262 15.8.2.13:
4074 // Math.pow(-Infinity, 0.5) == Infinity 4094 // Math.pow(-Infinity, 0.5) == Infinity
4075 // Math.sqrt(-Infinity) == NaN 4095 // Math.sqrt(-Infinity) == NaN
4076 Label done, sqrt; 4096 Label done, sqrt;
4077 // Check base for -Infinity. According to IEEE-754, single-precision 4097 // Check base for -Infinity. According to IEEE-754, single-precision
4078 // -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
4177 // Random bit pattern = (state[0] << 14) + (state[1] & 0x3FFFF) 4197 // Random bit pattern = (state[0] << 14) + (state[1] & 0x3FFFF)
4178 Register random = state0; 4198 Register random = state0;
4179 __ shl(random, 14); 4199 __ shl(random, 14);
4180 __ and_(state1, Immediate(0x3FFFF)); 4200 __ and_(state1, Immediate(0x3FFFF));
4181 __ add(random, state1); 4201 __ add(random, state1);
4182 4202
4183 // 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
4184 // by computing: 4204 // by computing:
4185 // ( 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)).
4186 XMMRegister result = ToDoubleRegister(instr->result()); 4206 XMMRegister result = ToDoubleRegister(instr->result());
4187 // We use xmm0 as fixed scratch register here. 4207 XMMRegister scratch4 = double_scratch0();
4188 XMMRegister scratch4 = xmm0;
4189 __ mov(scratch3, Immediate(0x49800000)); // 1.0 x 2^20 as single. 4208 __ mov(scratch3, Immediate(0x49800000)); // 1.0 x 2^20 as single.
4190 __ movd(scratch4, scratch3); 4209 __ movd(scratch4, scratch3);
4191 __ movd(result, random); 4210 __ movd(result, random);
4192 __ cvtss2sd(scratch4, scratch4); 4211 __ cvtss2sd(scratch4, scratch4);
4193 __ xorps(result, scratch4); 4212 __ xorps(result, scratch4);
4194 __ subsd(result, scratch4); 4213 __ subsd(result, scratch4);
4195 } 4214 }
4196 4215
4197 4216
4198 void LCodeGen::DoMathLog(LMathLog* instr) { 4217 void LCodeGen::DoMathLog(LMathLog* instr) {
4199 CpuFeatureScope scope(masm(), SSE2); 4218 CpuFeatureScope scope(masm(), SSE2);
4200 ASSERT(instr->value()->Equals(instr->result())); 4219 ASSERT(instr->value()->Equals(instr->result()));
4201 XMMRegister input_reg = ToDoubleRegister(instr->value()); 4220 XMMRegister input_reg = ToDoubleRegister(instr->value());
4221 XMMRegister xmm_scratch = double_scratch0();
4202 Label positive, done, zero; 4222 Label positive, done, zero;
4203 __ xorps(xmm0, xmm0); 4223 __ xorps(xmm_scratch, xmm_scratch);
4204 __ ucomisd(input_reg, xmm0); 4224 __ ucomisd(input_reg, xmm_scratch);
4205 __ j(above, &positive, Label::kNear); 4225 __ j(above, &positive, Label::kNear);
4206 __ j(equal, &zero, Label::kNear); 4226 __ j(equal, &zero, Label::kNear);
4207 ExternalReference nan = 4227 ExternalReference nan =
4208 ExternalReference::address_of_canonical_non_hole_nan(); 4228 ExternalReference::address_of_canonical_non_hole_nan();
4209 __ movdbl(input_reg, Operand::StaticVariable(nan)); 4229 __ movdbl(input_reg, Operand::StaticVariable(nan));
4210 __ jmp(&done, Label::kNear); 4230 __ jmp(&done, Label::kNear);
4211 __ bind(&zero); 4231 __ bind(&zero);
4212 __ push(Immediate(0xFFF00000)); 4232 __ push(Immediate(0xFFF00000));
4213 __ push(Immediate(0)); 4233 __ push(Immediate(0));
4214 __ movdbl(input_reg, Operand(esp, 0)); 4234 __ movdbl(input_reg, Operand(esp, 0));
4215 __ add(Operand(esp), Immediate(kDoubleSize)); 4235 __ add(Operand(esp), Immediate(kDoubleSize));
4216 __ jmp(&done, Label::kNear); 4236 __ jmp(&done, Label::kNear);
4217 __ bind(&positive); 4237 __ bind(&positive);
4218 __ fldln2(); 4238 __ fldln2();
4219 __ sub(Operand(esp), Immediate(kDoubleSize)); 4239 __ sub(Operand(esp), Immediate(kDoubleSize));
4220 __ movdbl(Operand(esp, 0), input_reg); 4240 __ movdbl(Operand(esp, 0), input_reg);
4221 __ fld_d(Operand(esp, 0)); 4241 __ fld_d(Operand(esp, 0));
4222 __ fyl2x(); 4242 __ fyl2x();
4223 __ fstp_d(Operand(esp, 0)); 4243 __ fstp_d(Operand(esp, 0));
4224 __ movdbl(input_reg, Operand(esp, 0)); 4244 __ movdbl(input_reg, Operand(esp, 0));
4225 __ add(Operand(esp), Immediate(kDoubleSize)); 4245 __ add(Operand(esp), Immediate(kDoubleSize));
4226 __ bind(&done); 4246 __ bind(&done);
4227 } 4247 }
4228 4248
4229 4249
4230 void LCodeGen::DoMathExp(LMathExp* instr) { 4250 void LCodeGen::DoMathExp(LMathExp* instr) {
4231 CpuFeatureScope scope(masm(), SSE2); 4251 CpuFeatureScope scope(masm(), SSE2);
4232 XMMRegister input = ToDoubleRegister(instr->value()); 4252 XMMRegister input = ToDoubleRegister(instr->value());
4233 XMMRegister result = ToDoubleRegister(instr->result()); 4253 XMMRegister result = ToDoubleRegister(instr->result());
4254 XMMRegister temp0 = double_scratch0();
4234 Register temp1 = ToRegister(instr->temp1()); 4255 Register temp1 = ToRegister(instr->temp1());
4235 Register temp2 = ToRegister(instr->temp2()); 4256 Register temp2 = ToRegister(instr->temp2());
4236 4257
4237 MathExpGenerator::EmitMathExp(masm(), input, result, xmm0, temp1, temp2); 4258 MathExpGenerator::EmitMathExp(masm(), input, result, temp0, temp1, temp2);
4238 } 4259 }
4239 4260
4240 4261
4241 void LCodeGen::DoMathTan(LMathTan* instr) { 4262 void LCodeGen::DoMathTan(LMathTan* instr) {
4242 ASSERT(ToDoubleRegister(instr->result()).is(xmm1)); 4263 ASSERT(ToDoubleRegister(instr->result()).is(xmm1));
4243 // 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
4244 // OK because this instruction is marked as a call. 4265 // OK because this instruction is marked as a call.
4245 __ Set(esi, Immediate(0)); 4266 __ Set(esi, Immediate(0));
4246 TranscendentalCacheStub stub(TranscendentalCache::TAN, 4267 TranscendentalCacheStub stub(TranscendentalCache::TAN,
4247 TranscendentalCacheStub::UNTAGGED); 4268 TranscendentalCacheStub::UNTAGGED);
(...skipping 360 matching lines...) Expand 10 before | Expand all | Expand 10 after
4608 Operand operand(BuildFastArrayOperand( 4629 Operand operand(BuildFastArrayOperand(
4609 instr->elements(), 4630 instr->elements(),
4610 key, 4631 key,
4611 instr->hydrogen()->key()->representation(), 4632 instr->hydrogen()->key()->representation(),
4612 elements_kind, 4633 elements_kind,
4613 0, 4634 0,
4614 instr->additional_index())); 4635 instr->additional_index()));
4615 if (elements_kind == EXTERNAL_FLOAT_ELEMENTS) { 4636 if (elements_kind == EXTERNAL_FLOAT_ELEMENTS) {
4616 if (CpuFeatures::IsSafeForSnapshot(SSE2)) { 4637 if (CpuFeatures::IsSafeForSnapshot(SSE2)) {
4617 CpuFeatureScope scope(masm(), SSE2); 4638 CpuFeatureScope scope(masm(), SSE2);
4618 __ cvtsd2ss(xmm0, ToDoubleRegister(instr->value())); 4639 XMMRegister xmm_scratch = double_scratch0();
4619 __ movss(operand, xmm0); 4640 __ cvtsd2ss(xmm_scratch, ToDoubleRegister(instr->value()));
4641 __ movss(operand, xmm_scratch);
4620 } else { 4642 } else {
4621 __ fld(0); 4643 __ fld(0);
4622 __ fstp_s(operand); 4644 __ fstp_s(operand);
4623 } 4645 }
4624 } else if (elements_kind == EXTERNAL_DOUBLE_ELEMENTS) { 4646 } else if (elements_kind == EXTERNAL_DOUBLE_ELEMENTS) {
4625 if (CpuFeatures::IsSafeForSnapshot(SSE2)) { 4647 if (CpuFeatures::IsSafeForSnapshot(SSE2)) {
4626 CpuFeatureScope scope(masm(), SSE2); 4648 CpuFeatureScope scope(masm(), SSE2);
4627 __ movdbl(operand, ToDoubleRegister(instr->value())); 4649 __ movdbl(operand, ToDoubleRegister(instr->value()));
4628 } else { 4650 } else {
4629 X87Mov(operand, ToX87Register(instr->value())); 4651 X87Mov(operand, ToX87Register(instr->value()));
(...skipping 442 matching lines...) Expand 10 before | Expand all | Expand 10 after
5072 __ bind(deferred->exit()); 5094 __ bind(deferred->exit());
5073 } 5095 }
5074 5096
5075 5097
5076 void LCodeGen::DoDeferredNumberTagI(LInstruction* instr, 5098 void LCodeGen::DoDeferredNumberTagI(LInstruction* instr,
5077 LOperand* value, 5099 LOperand* value,
5078 IntegerSignedness signedness) { 5100 IntegerSignedness signedness) {
5079 Label slow; 5101 Label slow;
5080 Register reg = ToRegister(value); 5102 Register reg = ToRegister(value);
5081 Register tmp = reg.is(eax) ? ecx : eax; 5103 Register tmp = reg.is(eax) ? ecx : eax;
5104 XMMRegister xmm_scratch = double_scratch0();
5082 5105
5083 // Preserve the value of all registers. 5106 // Preserve the value of all registers.
5084 PushSafepointRegistersScope scope(this); 5107 PushSafepointRegistersScope scope(this);
5085 5108
5086 Label done; 5109 Label done;
5087 5110
5088 if (signedness == SIGNED_INT32) { 5111 if (signedness == SIGNED_INT32) {
5089 // 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
5090 // 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
5091 // the value in there. If that fails, call the runtime system. 5114 // the value in there. If that fails, call the runtime system.
5092 __ SmiUntag(reg); 5115 __ SmiUntag(reg);
5093 __ xor_(reg, 0x80000000); 5116 __ xor_(reg, 0x80000000);
5094 if (CpuFeatures::IsSupported(SSE2)) { 5117 if (CpuFeatures::IsSupported(SSE2)) {
5095 CpuFeatureScope feature_scope(masm(), SSE2); 5118 CpuFeatureScope feature_scope(masm(), SSE2);
5096 __ Cvtsi2sd(xmm0, Operand(reg)); 5119 __ Cvtsi2sd(xmm_scratch, Operand(reg));
5097 } else { 5120 } else {
5098 __ push(reg); 5121 __ push(reg);
5099 __ fild_s(Operand(esp, 0)); 5122 __ fild_s(Operand(esp, 0));
5100 __ pop(reg); 5123 __ pop(reg);
5101 } 5124 }
5102 } else { 5125 } else {
5103 if (CpuFeatures::IsSupported(SSE2)) { 5126 if (CpuFeatures::IsSupported(SSE2)) {
5104 CpuFeatureScope feature_scope(masm(), SSE2); 5127 CpuFeatureScope feature_scope(masm(), SSE2);
5105 __ LoadUint32(xmm0, reg, 5128 __ LoadUint32(xmm_scratch, reg,
5106 ToDoubleRegister(LNumberTagU::cast(instr)->temp())); 5129 ToDoubleRegister(LNumberTagU::cast(instr)->temp()));
5107 } else { 5130 } else {
5108 // 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
5109 // int manually. 5132 // int manually.
5110 __ push(Immediate(0)); 5133 __ push(Immediate(0));
5111 __ push(reg); 5134 __ push(reg);
5112 __ fild_d(Operand(esp, 0)); 5135 __ fild_d(Operand(esp, 0));
5113 __ pop(reg); 5136 __ pop(reg);
5114 __ pop(reg); 5137 __ pop(reg);
5115 } 5138 }
(...skipping 15 matching lines...) Expand all
5131 // the environment's HContext or HInlinedContext value. 5154 // the environment's HContext or HInlinedContext value.
5132 // They only call Runtime::kAllocateHeapNumber. 5155 // They only call Runtime::kAllocateHeapNumber.
5133 // The corresponding HChange instructions are added in a phase that does 5156 // The corresponding HChange instructions are added in a phase that does
5134 // not have easy access to the local context. 5157 // not have easy access to the local context.
5135 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); 5158 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset));
5136 __ CallRuntimeSaveDoubles(Runtime::kAllocateHeapNumber); 5159 __ CallRuntimeSaveDoubles(Runtime::kAllocateHeapNumber);
5137 RecordSafepointWithRegisters( 5160 RecordSafepointWithRegisters(
5138 instr->pointer_map(), 0, Safepoint::kNoLazyDeopt); 5161 instr->pointer_map(), 0, Safepoint::kNoLazyDeopt);
5139 if (!reg.is(eax)) __ mov(reg, eax); 5162 if (!reg.is(eax)) __ mov(reg, eax);
5140 5163
5141 // 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
5142 // number. 5165 // number.
5143 __ bind(&done); 5166 __ bind(&done);
5144 if (CpuFeatures::IsSupported(SSE2)) { 5167 if (CpuFeatures::IsSupported(SSE2)) {
5145 CpuFeatureScope feature_scope(masm(), SSE2); 5168 CpuFeatureScope feature_scope(masm(), SSE2);
5146 __ movdbl(FieldOperand(reg, HeapNumber::kValueOffset), xmm0); 5169 __ movdbl(FieldOperand(reg, HeapNumber::kValueOffset), xmm_scratch);
5147 } else { 5170 } else {
5148 __ fstp_d(FieldOperand(reg, HeapNumber::kValueOffset)); 5171 __ fstp_d(FieldOperand(reg, HeapNumber::kValueOffset));
5149 } 5172 }
5150 __ StoreToSafepointRegisterSlot(reg, reg); 5173 __ StoreToSafepointRegisterSlot(reg, reg);
5151 } 5174 }
5152 5175
5153 5176
5154 void LCodeGen::DoNumberTagD(LNumberTagD* instr) { 5177 void LCodeGen::DoNumberTagD(LNumberTagD* instr) {
5155 class DeferredNumberTagD V8_FINAL : public LDeferredCode { 5178 class DeferredNumberTagD V8_FINAL : public LDeferredCode {
5156 public: 5179 public:
(...skipping 169 matching lines...) Expand 10 before | Expand all | Expand 10 after
5326 if (can_convert_undefined_to_nan) { 5349 if (can_convert_undefined_to_nan) {
5327 __ j(not_equal, &convert, Label::kNear); 5350 __ j(not_equal, &convert, Label::kNear);
5328 } else { 5351 } else {
5329 DeoptimizeIf(not_equal, env); 5352 DeoptimizeIf(not_equal, env);
5330 } 5353 }
5331 5354
5332 // Heap number to XMM conversion. 5355 // Heap number to XMM conversion.
5333 __ movdbl(result_reg, FieldOperand(input_reg, HeapNumber::kValueOffset)); 5356 __ movdbl(result_reg, FieldOperand(input_reg, HeapNumber::kValueOffset));
5334 5357
5335 if (deoptimize_on_minus_zero) { 5358 if (deoptimize_on_minus_zero) {
5336 XMMRegister xmm_scratch = xmm0; 5359 XMMRegister xmm_scratch = double_scratch0();
5337 __ xorps(xmm_scratch, xmm_scratch); 5360 __ xorps(xmm_scratch, xmm_scratch);
5338 __ ucomisd(result_reg, xmm_scratch); 5361 __ ucomisd(result_reg, xmm_scratch);
5339 __ j(not_zero, &done, Label::kNear); 5362 __ j(not_zero, &done, Label::kNear);
5340 __ movmskpd(temp_reg, result_reg); 5363 __ movmskpd(temp_reg, result_reg);
5341 __ test_b(temp_reg, 1); 5364 __ test_b(temp_reg, 1);
5342 DeoptimizeIf(not_zero, env); 5365 DeoptimizeIf(not_zero, env);
5343 } 5366 }
5344 __ jmp(&done, Label::kNear); 5367 __ jmp(&done, Label::kNear);
5345 5368
5346 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
5492 } else { 5515 } else {
5493 X87Register input_reg = ToX87Register(input); 5516 X87Register input_reg = ToX87Register(input);
5494 X87Fxch(input_reg); 5517 X87Fxch(input_reg);
5495 __ TruncateX87TOSToI(result_reg); 5518 __ TruncateX87TOSToI(result_reg);
5496 } 5519 }
5497 } else { 5520 } else {
5498 Label bailout, done; 5521 Label bailout, done;
5499 if (CpuFeatures::IsSafeForSnapshot(SSE2)) { 5522 if (CpuFeatures::IsSafeForSnapshot(SSE2)) {
5500 CpuFeatureScope scope(masm(), SSE2); 5523 CpuFeatureScope scope(masm(), SSE2);
5501 XMMRegister input_reg = ToDoubleRegister(input); 5524 XMMRegister input_reg = ToDoubleRegister(input);
5502 __ DoubleToI(result_reg, input_reg, xmm0, 5525 XMMRegister xmm_scratch = double_scratch0();
5526 __ DoubleToI(result_reg, input_reg, xmm_scratch,
5503 instr->hydrogen()->GetMinusZeroMode(), &bailout, Label::kNear); 5527 instr->hydrogen()->GetMinusZeroMode(), &bailout, Label::kNear);
5504 } else { 5528 } else {
5505 X87Register input_reg = ToX87Register(input); 5529 X87Register input_reg = ToX87Register(input);
5506 X87Fxch(input_reg); 5530 X87Fxch(input_reg);
5507 __ X87TOSToI(result_reg, instr->hydrogen()->GetMinusZeroMode(), 5531 __ X87TOSToI(result_reg, instr->hydrogen()->GetMinusZeroMode(),
5508 &bailout, Label::kNear); 5532 &bailout, Label::kNear);
5509 } 5533 }
5510 __ jmp(&done, Label::kNear); 5534 __ jmp(&done, Label::kNear);
5511 __ bind(&bailout); 5535 __ bind(&bailout);
5512 DeoptimizeIf(no_condition, instr->environment()); 5536 DeoptimizeIf(no_condition, instr->environment());
5513 __ bind(&done); 5537 __ bind(&done);
5514 } 5538 }
5515 } 5539 }
5516 5540
5517 5541
5518 void LCodeGen::DoDoubleToSmi(LDoubleToSmi* instr) { 5542 void LCodeGen::DoDoubleToSmi(LDoubleToSmi* instr) {
5519 LOperand* input = instr->value(); 5543 LOperand* input = instr->value();
5520 ASSERT(input->IsDoubleRegister()); 5544 ASSERT(input->IsDoubleRegister());
5521 LOperand* result = instr->result(); 5545 LOperand* result = instr->result();
5522 ASSERT(result->IsRegister()); 5546 ASSERT(result->IsRegister());
5523 Register result_reg = ToRegister(result); 5547 Register result_reg = ToRegister(result);
5524 5548
5525 Label bailout, done; 5549 Label bailout, done;
5526 if (CpuFeatures::IsSafeForSnapshot(SSE2)) { 5550 if (CpuFeatures::IsSafeForSnapshot(SSE2)) {
5527 CpuFeatureScope scope(masm(), SSE2); 5551 CpuFeatureScope scope(masm(), SSE2);
5528 XMMRegister input_reg = ToDoubleRegister(input); 5552 XMMRegister input_reg = ToDoubleRegister(input);
5529 __ DoubleToI(result_reg, input_reg, xmm0, 5553 XMMRegister xmm_scratch = double_scratch0();
5554 __ DoubleToI(result_reg, input_reg, xmm_scratch,
5530 instr->hydrogen()->GetMinusZeroMode(), &bailout, Label::kNear); 5555 instr->hydrogen()->GetMinusZeroMode(), &bailout, Label::kNear);
5531 } else { 5556 } else {
5532 X87Register input_reg = ToX87Register(input); 5557 X87Register input_reg = ToX87Register(input);
5533 X87Fxch(input_reg); 5558 X87Fxch(input_reg);
5534 __ X87TOSToI(result_reg, instr->hydrogen()->GetMinusZeroMode(), 5559 __ X87TOSToI(result_reg, instr->hydrogen()->GetMinusZeroMode(),
5535 &bailout, Label::kNear); 5560 &bailout, Label::kNear);
5536 } 5561 }
5537 __ jmp(&done, Label::kNear); 5562 __ jmp(&done, Label::kNear);
5538 __ bind(&bailout); 5563 __ bind(&bailout);
5539 DeoptimizeIf(no_condition, instr->environment()); 5564 DeoptimizeIf(no_condition, instr->environment());
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
5599 __ movzx_b(temp, FieldOperand(temp, Map::kInstanceTypeOffset)); 5624 __ movzx_b(temp, FieldOperand(temp, Map::kInstanceTypeOffset));
5600 __ and_(temp, mask); 5625 __ and_(temp, mask);
5601 __ cmp(temp, tag); 5626 __ cmp(temp, tag);
5602 DeoptimizeIf(not_equal, instr->environment()); 5627 DeoptimizeIf(not_equal, instr->environment());
5603 } 5628 }
5604 } 5629 }
5605 } 5630 }
5606 5631
5607 5632
5608 void LCodeGen::DoCheckValue(LCheckValue* instr) { 5633 void LCodeGen::DoCheckValue(LCheckValue* instr) {
5609 Handle<HeapObject> object = instr->hydrogen()->object(); 5634 Handle<HeapObject> object = instr->hydrogen()->object().handle();
5610 if (instr->hydrogen()->object_in_new_space()) { 5635 if (instr->hydrogen()->object_in_new_space()) {
5611 Register reg = ToRegister(instr->value()); 5636 Register reg = ToRegister(instr->value());
5612 Handle<Cell> cell = isolate()->factory()->NewCell(object); 5637 Handle<Cell> cell = isolate()->factory()->NewCell(object);
5613 __ cmp(reg, Operand::ForCell(cell)); 5638 __ cmp(reg, Operand::ForCell(cell));
5614 } else { 5639 } else {
5615 Operand operand = ToOperand(instr->value()); 5640 Operand operand = ToOperand(instr->value());
5616 __ cmp(operand, object); 5641 __ cmp(operand, object);
5617 } 5642 }
5618 DeoptimizeIf(not_equal, instr->environment()); 5643 DeoptimizeIf(not_equal, instr->environment());
5619 } 5644 }
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
5654 Label check_maps_; 5679 Label check_maps_;
5655 Register object_; 5680 Register object_;
5656 }; 5681 };
5657 5682
5658 if (instr->hydrogen()->CanOmitMapChecks()) return; 5683 if (instr->hydrogen()->CanOmitMapChecks()) return;
5659 5684
5660 LOperand* input = instr->value(); 5685 LOperand* input = instr->value();
5661 ASSERT(input->IsRegister()); 5686 ASSERT(input->IsRegister());
5662 Register reg = ToRegister(input); 5687 Register reg = ToRegister(input);
5663 5688
5664 SmallMapList* map_set = instr->hydrogen()->map_set();
5665
5666 DeferredCheckMaps* deferred = NULL; 5689 DeferredCheckMaps* deferred = NULL;
5667 if (instr->hydrogen()->has_migration_target()) { 5690 if (instr->hydrogen()->has_migration_target()) {
5668 deferred = new(zone()) DeferredCheckMaps(this, instr, reg, x87_stack_); 5691 deferred = new(zone()) DeferredCheckMaps(this, instr, reg, x87_stack_);
5669 __ bind(deferred->check_maps()); 5692 __ bind(deferred->check_maps());
5670 } 5693 }
5671 5694
5695 UniqueSet<Map> map_set = instr->hydrogen()->map_set();
5672 Label success; 5696 Label success;
5673 for (int i = 0; i < map_set->length() - 1; i++) { 5697 for (int i = 0; i < map_set.size() - 1; i++) {
5674 Handle<Map> map = map_set->at(i); 5698 Handle<Map> map = map_set.at(i).handle();
5675 __ CompareMap(reg, map, &success); 5699 __ CompareMap(reg, map, &success);
5676 __ j(equal, &success); 5700 __ j(equal, &success);
5677 } 5701 }
5678 5702
5679 Handle<Map> map = map_set->last(); 5703 Handle<Map> map = map_set.at(map_set.size() - 1).handle();
5680 __ CompareMap(reg, map, &success); 5704 __ CompareMap(reg, map, &success);
5681 if (instr->hydrogen()->has_migration_target()) { 5705 if (instr->hydrogen()->has_migration_target()) {
5682 __ j(not_equal, deferred->entry()); 5706 __ j(not_equal, deferred->entry());
5683 } else { 5707 } else {
5684 DeoptimizeIf(not_equal, instr->environment()); 5708 DeoptimizeIf(not_equal, instr->environment());
5685 } 5709 }
5686 5710
5687 __ bind(&success); 5711 __ bind(&success);
5688 } 5712 }
5689 5713
5690 5714
5691 void LCodeGen::DoClampDToUint8(LClampDToUint8* instr) { 5715 void LCodeGen::DoClampDToUint8(LClampDToUint8* instr) {
5692 CpuFeatureScope scope(masm(), SSE2); 5716 CpuFeatureScope scope(masm(), SSE2);
5693 XMMRegister value_reg = ToDoubleRegister(instr->unclamped()); 5717 XMMRegister value_reg = ToDoubleRegister(instr->unclamped());
5718 XMMRegister xmm_scratch = double_scratch0();
5694 Register result_reg = ToRegister(instr->result()); 5719 Register result_reg = ToRegister(instr->result());
5695 __ ClampDoubleToUint8(value_reg, xmm0, result_reg); 5720 __ ClampDoubleToUint8(value_reg, xmm_scratch, result_reg);
5696 } 5721 }
5697 5722
5698 5723
5699 void LCodeGen::DoClampIToUint8(LClampIToUint8* instr) { 5724 void LCodeGen::DoClampIToUint8(LClampIToUint8* instr) {
5700 ASSERT(instr->unclamped()->Equals(instr->result())); 5725 ASSERT(instr->unclamped()->Equals(instr->result()));
5701 Register value_reg = ToRegister(instr->result()); 5726 Register value_reg = ToRegister(instr->result());
5702 __ ClampUint8(value_reg); 5727 __ ClampUint8(value_reg);
5703 } 5728 }
5704 5729
5705 5730
5706 void LCodeGen::DoClampTToUint8(LClampTToUint8* instr) { 5731 void LCodeGen::DoClampTToUint8(LClampTToUint8* instr) {
5707 CpuFeatureScope scope(masm(), SSE2); 5732 CpuFeatureScope scope(masm(), SSE2);
5708 5733
5709 ASSERT(instr->unclamped()->Equals(instr->result())); 5734 ASSERT(instr->unclamped()->Equals(instr->result()));
5710 Register input_reg = ToRegister(instr->unclamped()); 5735 Register input_reg = ToRegister(instr->unclamped());
5736 XMMRegister xmm_scratch = double_scratch0();
5711 Label is_smi, done, heap_number; 5737 Label is_smi, done, heap_number;
5712 5738
5713 __ JumpIfSmi(input_reg, &is_smi); 5739 __ JumpIfSmi(input_reg, &is_smi);
5714 5740
5715 // Check for heap number 5741 // Check for heap number
5716 __ cmp(FieldOperand(input_reg, HeapObject::kMapOffset), 5742 __ cmp(FieldOperand(input_reg, HeapObject::kMapOffset),
5717 factory()->heap_number_map()); 5743 factory()->heap_number_map());
5718 __ j(equal, &heap_number, Label::kNear); 5744 __ j(equal, &heap_number, Label::kNear);
5719 5745
5720 // Check for undefined. Undefined is converted to zero for clamping 5746 // Check for undefined. Undefined is converted to zero for clamping
5721 // conversions. 5747 // conversions.
5722 __ cmp(input_reg, factory()->undefined_value()); 5748 __ cmp(input_reg, factory()->undefined_value());
5723 DeoptimizeIf(not_equal, instr->environment()); 5749 DeoptimizeIf(not_equal, instr->environment());
5724 __ mov(input_reg, 0); 5750 __ mov(input_reg, 0);
5725 __ jmp(&done, Label::kNear); 5751 __ jmp(&done, Label::kNear);
5726 5752
5727 // Heap number 5753 // Heap number
5728 __ bind(&heap_number); 5754 __ bind(&heap_number);
5729 __ movdbl(xmm0, FieldOperand(input_reg, HeapNumber::kValueOffset)); 5755 __ movdbl(xmm_scratch, FieldOperand(input_reg, HeapNumber::kValueOffset));
5730 __ ClampDoubleToUint8(xmm0, xmm1, input_reg); 5756 __ ClampDoubleToUint8(xmm_scratch, xmm1, input_reg);
5731 __ jmp(&done, Label::kNear); 5757 __ jmp(&done, Label::kNear);
5732 5758
5733 // smi 5759 // smi
5734 __ bind(&is_smi); 5760 __ bind(&is_smi);
5735 __ SmiUntag(input_reg); 5761 __ SmiUntag(input_reg);
5736 __ ClampUint8(input_reg); 5762 __ ClampUint8(input_reg);
5737 __ bind(&done); 5763 __ bind(&done);
5738 } 5764 }
5739 5765
5740 5766
(...skipping 628 matching lines...) Expand 10 before | Expand all | Expand 10 after
6369 FixedArray::kHeaderSize - kPointerSize)); 6395 FixedArray::kHeaderSize - kPointerSize));
6370 __ bind(&done); 6396 __ bind(&done);
6371 } 6397 }
6372 6398
6373 6399
6374 #undef __ 6400 #undef __
6375 6401
6376 } } // namespace v8::internal 6402 } } // namespace v8::internal
6377 6403
6378 #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/ia32/lithium-ia32.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698