| OLD | NEW |
| 1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 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 2419 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2430 __ Bind(&deopt); | 2430 __ Bind(&deopt); |
| 2431 Deoptimize(instr->environment()); | 2431 Deoptimize(instr->environment()); |
| 2432 __ Bind(&div_ok); | 2432 __ Bind(&div_ok); |
| 2433 } else { | 2433 } else { |
| 2434 ASSERT(instr->temp() == NULL); | 2434 ASSERT(instr->temp() == NULL); |
| 2435 } | 2435 } |
| 2436 } | 2436 } |
| 2437 } | 2437 } |
| 2438 | 2438 |
| 2439 | 2439 |
| 2440 void LCodeGen::DoDoubleToI(LDoubleToI* instr) { | 2440 void LCodeGen::DoDoubleToIntOrSmi(LDoubleToIntOrSmi* instr) { |
| 2441 DoubleRegister input = ToDoubleRegister(instr->value()); | 2441 DoubleRegister input = ToDoubleRegister(instr->value()); |
| 2442 Register result = ToRegister32(instr->result()); |
| 2443 Label done, deopt; |
| 2442 | 2444 |
| 2443 if (instr->truncating()) { | 2445 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { |
| 2444 Register result = ToRegister(instr->result()); | 2446 __ JumpIfMinusZero(input, &deopt); |
| 2445 Register scratch1 = ToRegister(instr->temp1()); | 2447 } |
| 2446 Register scratch2 = ToRegister(instr->temp2()); | |
| 2447 __ ECMA262ToInt32(result, input, scratch1, scratch2); | |
| 2448 } else { | |
| 2449 Register result = ToRegister32(instr->result()); | |
| 2450 ASSERT((instr->temp1() == NULL) && (instr->temp2() == NULL)); | |
| 2451 Label done, deopt; | |
| 2452 | 2448 |
| 2453 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { | 2449 __ TryConvertDoubleToInt32(result, input, double_scratch(), &done); |
| 2454 // Check for an input of -0.0, using the result register as a scratch. | 2450 __ Bind(&deopt); |
| 2455 __ Fmov(result, input); | 2451 Deoptimize(instr->environment()); |
| 2456 __ Cmp(result, 1); | 2452 __ Bind(&done); |
| 2457 __ B(&deopt, vs); | |
| 2458 } | |
| 2459 | 2453 |
| 2460 __ TryConvertDoubleToInt32(result, input, double_scratch(), &done); | 2454 if (instr->tag_result()) { |
| 2461 __ Bind(&deopt); | 2455 __ SmiTag(result.X()); |
| 2462 Deoptimize(instr->environment()); | |
| 2463 __ Bind(&done); | |
| 2464 } | 2456 } |
| 2465 } | 2457 } |
| 2466 | 2458 |
| 2467 | 2459 |
| 2468 // TODO(jbramley): This is almost the same as DoDoubleToI. Can we merge them? | |
| 2469 void LCodeGen::DoDoubleToSmi(LDoubleToSmi* instr) { | |
| 2470 DoubleRegister input = ToDoubleRegister(instr->value()); | |
| 2471 | |
| 2472 if (instr->truncating()) { | |
| 2473 Register result = ToRegister(instr->result()); | |
| 2474 Register scratch1 = ToRegister(instr->temp1()); | |
| 2475 Register scratch2 = ToRegister(instr->temp2()); | |
| 2476 __ ECMA262ToInt32(result, input, scratch1, scratch2); | |
| 2477 } else { | |
| 2478 Register result = ToRegister32(instr->result()); | |
| 2479 ASSERT((instr->temp1() == NULL) && (instr->temp2() == NULL)); | |
| 2480 Label done, deopt; | |
| 2481 | |
| 2482 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { | |
| 2483 // Check for an input of -0.0, using the result register as a scratch. | |
| 2484 __ Fmov(result, input); | |
| 2485 __ Cmp(result, 1); | |
| 2486 __ B(&deopt, vs); | |
| 2487 } | |
| 2488 | |
| 2489 __ TryConvertDoubleToInt32(result, input, double_scratch(), &done); | |
| 2490 __ Bind(&deopt); | |
| 2491 Deoptimize(instr->environment()); | |
| 2492 __ Bind(&done); | |
| 2493 } | |
| 2494 __ SmiTag(ToRegister(instr->result())); | |
| 2495 } | |
| 2496 | |
| 2497 | |
| 2498 void LCodeGen::DoDrop(LDrop* instr) { | 2460 void LCodeGen::DoDrop(LDrop* instr) { |
| 2499 TODO_UNIMPLEMENTED("DoDrop is untested."); | 2461 TODO_UNIMPLEMENTED("DoDrop is untested."); |
| 2500 __ Drop(instr->count()); | 2462 __ Drop(instr->count()); |
| 2501 } | 2463 } |
| 2502 | 2464 |
| 2503 | 2465 |
| 2504 void LCodeGen::DoDummyUse(LDummyUse* instr) { | 2466 void LCodeGen::DoDummyUse(LDummyUse* instr) { |
| 2505 // Nothing to see here, move on! | 2467 // Nothing to see here, move on! |
| 2506 } | 2468 } |
| 2507 | 2469 |
| (...skipping 1184 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3692 | 3654 |
| 3693 void LCodeGen::DoMathFloor(LMathFloor* instr) { | 3655 void LCodeGen::DoMathFloor(LMathFloor* instr) { |
| 3694 // TODO(jbramley): If we could provide a double result, we could use frintm | 3656 // TODO(jbramley): If we could provide a double result, we could use frintm |
| 3695 // and produce a valid double result in a single instruction. | 3657 // and produce a valid double result in a single instruction. |
| 3696 DoubleRegister input = ToDoubleRegister(instr->value()); | 3658 DoubleRegister input = ToDoubleRegister(instr->value()); |
| 3697 Register result = ToRegister(instr->result()); | 3659 Register result = ToRegister(instr->result()); |
| 3698 Label deopt; | 3660 Label deopt; |
| 3699 Label done; | 3661 Label done; |
| 3700 | 3662 |
| 3701 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { | 3663 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { |
| 3702 // Check for an input of -0.0, using the result register as a scratch. | 3664 __ JumpIfMinusZero(input, &deopt); |
| 3703 __ Fmov(result, input); | |
| 3704 __ Cmp(result, 1); | |
| 3705 __ B(&deopt, vs); | |
| 3706 } | 3665 } |
| 3707 | 3666 |
| 3708 __ Fcvtms(result, input); | 3667 __ Fcvtms(result, input); |
| 3709 | 3668 |
| 3710 // Check that the result fits into a 32-bit integer. | 3669 // Check that the result fits into a 32-bit integer. |
| 3711 // - The result did not overflow. | 3670 // - The result did not overflow. |
| 3712 __ Cmp(result, Operand(result, SXTW)); | 3671 __ Cmp(result, Operand(result, SXTW)); |
| 3713 // - The input was not NaN. | 3672 // - The input was not NaN. |
| 3714 __ Fccmp(input, input, NoFlag, eq); | 3673 __ Fccmp(input, input, NoFlag, eq); |
| 3715 __ B(&done, eq); | 3674 __ B(&done, eq); |
| (...skipping 590 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4306 | 4265 |
| 4307 // Heap number map check. | 4266 // Heap number map check. |
| 4308 Label* not_heap_number = allow_undefined_as_nan ? &convert_undefined | 4267 Label* not_heap_number = allow_undefined_as_nan ? &convert_undefined |
| 4309 : &deopt; | 4268 : &deopt; |
| 4310 __ Ldr(scratch, FieldMemOperand(input, HeapObject::kMapOffset)); | 4269 __ Ldr(scratch, FieldMemOperand(input, HeapObject::kMapOffset)); |
| 4311 __ JumpIfNotRoot(scratch, Heap::kHeapNumberMapRootIndex, not_heap_number); | 4270 __ JumpIfNotRoot(scratch, Heap::kHeapNumberMapRootIndex, not_heap_number); |
| 4312 | 4271 |
| 4313 // Load heap number. | 4272 // Load heap number. |
| 4314 __ Ldr(result, FieldMemOperand(input, HeapNumber::kValueOffset)); | 4273 __ Ldr(result, FieldMemOperand(input, HeapNumber::kValueOffset)); |
| 4315 if (instr->hydrogen()->deoptimize_on_minus_zero()) { | 4274 if (instr->hydrogen()->deoptimize_on_minus_zero()) { |
| 4316 ASM_UNIMPLEMENTED_BREAK("NumberUntagD - deopt on minus zero"); | 4275 __ JumpIfMinusZero(result, &deopt); |
| 4317 } | 4276 } |
| 4318 __ B(&done); | 4277 __ B(&done); |
| 4319 | 4278 |
| 4320 if (allow_undefined_as_nan) { | 4279 if (allow_undefined_as_nan) { |
| 4321 Label load_nan; | 4280 Label load_nan; |
| 4322 | 4281 |
| 4323 __ Bind(&convert_undefined); | 4282 __ Bind(&convert_undefined); |
| 4324 // Convert undefined (and hole) to NaN. | 4283 // Convert undefined (and hole) to NaN. |
| 4325 if (mode == NUMBER_CANDIDATE_IS_ANY_TAGGED_CONVERT_HOLE) { | 4284 if (mode == NUMBER_CANDIDATE_IS_ANY_TAGGED_CONVERT_HOLE) { |
| 4326 __ JumpIfRoot(input, Heap::kUndefinedValueRootIndex, &load_nan); | 4285 __ JumpIfRoot(input, Heap::kUndefinedValueRootIndex, &load_nan); |
| (...skipping 951 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5278 | 5237 |
| 5279 void LCodeGen::DoTrapAllocationMemento(LTrapAllocationMemento* instr) { | 5238 void LCodeGen::DoTrapAllocationMemento(LTrapAllocationMemento* instr) { |
| 5280 Register object = ToRegister(instr->object()); | 5239 Register object = ToRegister(instr->object()); |
| 5281 Register temp1 = ToRegister(instr->temp1()); | 5240 Register temp1 = ToRegister(instr->temp1()); |
| 5282 Register temp2 = ToRegister(instr->temp2()); | 5241 Register temp2 = ToRegister(instr->temp2()); |
| 5283 __ TestJSArrayForAllocationSiteInfo(object, temp1, temp2); | 5242 __ TestJSArrayForAllocationSiteInfo(object, temp1, temp2); |
| 5284 DeoptimizeIf(eq, instr->environment()); | 5243 DeoptimizeIf(eq, instr->environment()); |
| 5285 } | 5244 } |
| 5286 | 5245 |
| 5287 | 5246 |
| 5247 void LCodeGen::DoTruncateDoubleToIntOrSmi(LTruncateDoubleToIntOrSmi* instr) { |
| 5248 DoubleRegister input = ToDoubleRegister(instr->value()); |
| 5249 Register result = ToRegister(instr->result()); |
| 5250 __ ECMA262ToInt32(result, input, |
| 5251 ToRegister(instr->temp1()), |
| 5252 ToRegister(instr->temp2()), |
| 5253 instr->tag_result() |
| 5254 ? MacroAssembler::SMI |
| 5255 : MacroAssembler::INT32_IN_W); |
| 5256 } |
| 5257 |
| 5258 |
| 5288 void LCodeGen::DoTypeof(LTypeof* instr) { | 5259 void LCodeGen::DoTypeof(LTypeof* instr) { |
| 5289 Register input = ToRegister(instr->value()); | 5260 Register input = ToRegister(instr->value()); |
| 5290 __ Push(input); | 5261 __ Push(input); |
| 5291 CallRuntime(Runtime::kTypeof, 1, instr); | 5262 CallRuntime(Runtime::kTypeof, 1, instr); |
| 5292 } | 5263 } |
| 5293 | 5264 |
| 5294 | 5265 |
| 5295 void LCodeGen::DoTypeofIsAndBranch(LTypeofIsAndBranch* instr) { | 5266 void LCodeGen::DoTypeofIsAndBranch(LTypeofIsAndBranch* instr) { |
| 5296 Handle<String> type_name = instr->type_literal(); | 5267 Handle<String> type_name = instr->type_literal(); |
| 5297 Label* true_label = instr->TrueLabel(chunk_); | 5268 Label* true_label = instr->TrueLabel(chunk_); |
| (...skipping 189 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5487 __ Bind(&out_of_object); | 5458 __ Bind(&out_of_object); |
| 5488 __ Ldr(result, FieldMemOperand(object, JSObject::kPropertiesOffset)); | 5459 __ Ldr(result, FieldMemOperand(object, JSObject::kPropertiesOffset)); |
| 5489 // Index is equal to negated out of object property index plus 1. | 5460 // Index is equal to negated out of object property index plus 1. |
| 5490 __ Sub(result, result, Operand::UntagSmiAndScale(index, kPointerSizeLog2)); | 5461 __ Sub(result, result, Operand::UntagSmiAndScale(index, kPointerSizeLog2)); |
| 5491 __ Ldr(result, FieldMemOperand(result, | 5462 __ Ldr(result, FieldMemOperand(result, |
| 5492 FixedArray::kHeaderSize - kPointerSize)); | 5463 FixedArray::kHeaderSize - kPointerSize)); |
| 5493 __ Bind(&done); | 5464 __ Bind(&done); |
| 5494 } | 5465 } |
| 5495 | 5466 |
| 5496 } } // namespace v8::internal | 5467 } } // namespace v8::internal |
| OLD | NEW |