OLD | NEW |
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 3246 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3257 // If smi, handle it directly. | 3257 // If smi, handle it directly. |
3258 EmitIntegerMathAbs(instr); | 3258 EmitIntegerMathAbs(instr); |
3259 __ bind(deferred->exit()); | 3259 __ bind(deferred->exit()); |
3260 } | 3260 } |
3261 } | 3261 } |
3262 | 3262 |
3263 | 3263 |
3264 void LCodeGen::DoMathFloor(LUnaryMathOperation* instr) { | 3264 void LCodeGen::DoMathFloor(LUnaryMathOperation* instr) { |
3265 DoubleRegister input = ToDoubleRegister(instr->value()); | 3265 DoubleRegister input = ToDoubleRegister(instr->value()); |
3266 Register result = ToRegister(instr->result()); | 3266 Register result = ToRegister(instr->result()); |
3267 FPURegister single_scratch = double_scratch0().low(); | |
3268 Register scratch1 = scratch0(); | 3267 Register scratch1 = scratch0(); |
3269 Register except_flag = ToRegister(instr->temp()); | 3268 Register except_flag = ToRegister(instr->temp()); |
3270 | 3269 |
3271 __ EmitFPUTruncate(kRoundToMinusInf, | 3270 __ EmitFPUTruncate(kRoundToMinusInf, |
3272 single_scratch, | 3271 result, |
3273 input, | 3272 input, |
3274 scratch1, | 3273 scratch1, |
| 3274 double_scratch0(), |
3275 except_flag); | 3275 except_flag); |
3276 | 3276 |
3277 // Deopt if the operation did not succeed. | 3277 // Deopt if the operation did not succeed. |
3278 DeoptimizeIf(ne, instr->environment(), except_flag, Operand(zero_reg)); | 3278 DeoptimizeIf(ne, instr->environment(), except_flag, Operand(zero_reg)); |
3279 | 3279 |
3280 // Load the result. | |
3281 __ mfc1(result, single_scratch); | |
3282 | |
3283 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { | 3280 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { |
3284 // Test for -0. | 3281 // Test for -0. |
3285 Label done; | 3282 Label done; |
3286 __ Branch(&done, ne, result, Operand(zero_reg)); | 3283 __ Branch(&done, ne, result, Operand(zero_reg)); |
3287 __ mfc1(scratch1, input.high()); | 3284 __ mfc1(scratch1, input.high()); |
3288 __ And(scratch1, scratch1, Operand(HeapNumber::kSignMask)); | 3285 __ And(scratch1, scratch1, Operand(HeapNumber::kSignMask)); |
3289 DeoptimizeIf(ne, instr->environment(), scratch1, Operand(zero_reg)); | 3286 DeoptimizeIf(ne, instr->environment(), scratch1, Operand(zero_reg)); |
3290 __ bind(&done); | 3287 __ bind(&done); |
3291 } | 3288 } |
3292 } | 3289 } |
3293 | 3290 |
3294 | 3291 |
3295 void LCodeGen::DoMathRound(LUnaryMathOperation* instr) { | 3292 void LCodeGen::DoMathRound(LUnaryMathOperation* instr) { |
3296 DoubleRegister input = ToDoubleRegister(instr->value()); | 3293 DoubleRegister input = ToDoubleRegister(instr->value()); |
3297 Register result = ToRegister(instr->result()); | 3294 Register result = ToRegister(instr->result()); |
| 3295 DoubleRegister double_scratch1 = ToDoubleRegister(instr->temp()); |
3298 Register scratch = scratch0(); | 3296 Register scratch = scratch0(); |
3299 Label done, check_sign_on_zero; | 3297 Label done, check_sign_on_zero; |
3300 | 3298 |
3301 // Extract exponent bits. | 3299 // Extract exponent bits. |
3302 __ mfc1(result, input.high()); | 3300 __ mfc1(result, input.high()); |
3303 __ Ext(scratch, | 3301 __ Ext(scratch, |
3304 result, | 3302 result, |
3305 HeapNumber::kExponentShift, | 3303 HeapNumber::kExponentShift, |
3306 HeapNumber::kExponentBits); | 3304 HeapNumber::kExponentBits); |
3307 | 3305 |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3339 Label skip2; | 3337 Label skip2; |
3340 // ARM uses 'mi' here, which is 'lt' | 3338 // ARM uses 'mi' here, which is 'lt' |
3341 // Negating it results in 'ge' | 3339 // Negating it results in 'ge' |
3342 __ Branch(&skip2, ge, result, Operand(zero_reg)); | 3340 __ Branch(&skip2, ge, result, Operand(zero_reg)); |
3343 __ mov(result, zero_reg); | 3341 __ mov(result, zero_reg); |
3344 __ Branch(&done); | 3342 __ Branch(&done); |
3345 __ bind(&skip2); | 3343 __ bind(&skip2); |
3346 } | 3344 } |
3347 | 3345 |
3348 Register except_flag = scratch; | 3346 Register except_flag = scratch; |
3349 | |
3350 __ EmitFPUTruncate(kRoundToMinusInf, | 3347 __ EmitFPUTruncate(kRoundToMinusInf, |
3351 double_scratch0().low(), | 3348 result, |
3352 double_scratch0(), | 3349 double_scratch0(), |
3353 result, | 3350 at, |
| 3351 double_scratch1, |
3354 except_flag); | 3352 except_flag); |
3355 | 3353 |
3356 DeoptimizeIf(ne, instr->environment(), except_flag, Operand(zero_reg)); | 3354 DeoptimizeIf(ne, instr->environment(), except_flag, Operand(zero_reg)); |
3357 | 3355 |
3358 __ mfc1(result, double_scratch0().low()); | |
3359 | |
3360 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { | 3356 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { |
3361 // Test for -0. | 3357 // Test for -0. |
3362 __ Branch(&done, ne, result, Operand(zero_reg)); | 3358 __ Branch(&done, ne, result, Operand(zero_reg)); |
3363 __ bind(&check_sign_on_zero); | 3359 __ bind(&check_sign_on_zero); |
3364 __ mfc1(scratch, input.high()); | 3360 __ mfc1(scratch, input.high()); |
3365 __ And(scratch, scratch, Operand(HeapNumber::kSignMask)); | 3361 __ And(scratch, scratch, Operand(HeapNumber::kSignMask)); |
3366 DeoptimizeIf(ne, instr->environment(), scratch, Operand(zero_reg)); | 3362 DeoptimizeIf(ne, instr->environment(), scratch, Operand(zero_reg)); |
3367 } | 3363 } |
3368 __ bind(&done); | 3364 __ bind(&done); |
3369 } | 3365 } |
(...skipping 1016 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4386 __ cvt_d_w(result_reg, result_reg); | 4382 __ cvt_d_w(result_reg, result_reg); |
4387 __ bind(&done); | 4383 __ bind(&done); |
4388 } | 4384 } |
4389 | 4385 |
4390 | 4386 |
4391 void LCodeGen::DoDeferredTaggedToI(LTaggedToI* instr) { | 4387 void LCodeGen::DoDeferredTaggedToI(LTaggedToI* instr) { |
4392 Register input_reg = ToRegister(instr->value()); | 4388 Register input_reg = ToRegister(instr->value()); |
4393 Register scratch1 = scratch0(); | 4389 Register scratch1 = scratch0(); |
4394 Register scratch2 = ToRegister(instr->temp()); | 4390 Register scratch2 = ToRegister(instr->temp()); |
4395 DoubleRegister double_scratch = double_scratch0(); | 4391 DoubleRegister double_scratch = double_scratch0(); |
4396 FPURegister single_scratch = double_scratch.low(); | 4392 DoubleRegister double_scratch2 = ToDoubleRegister(instr->temp3()); |
4397 | 4393 |
4398 ASSERT(!scratch1.is(input_reg) && !scratch1.is(scratch2)); | 4394 ASSERT(!scratch1.is(input_reg) && !scratch1.is(scratch2)); |
4399 ASSERT(!scratch2.is(input_reg) && !scratch2.is(scratch1)); | 4395 ASSERT(!scratch2.is(input_reg) && !scratch2.is(scratch1)); |
4400 | 4396 |
4401 Label done; | 4397 Label done; |
4402 | 4398 |
4403 // The input is a tagged HeapObject. | 4399 // The input is a tagged HeapObject. |
4404 // Heap number map check. | 4400 // Heap number map check. |
4405 __ lw(scratch1, FieldMemOperand(input_reg, HeapObject::kMapOffset)); | 4401 __ lw(scratch1, FieldMemOperand(input_reg, HeapObject::kMapOffset)); |
4406 __ LoadRoot(at, Heap::kHeapNumberMapRootIndex); | 4402 __ LoadRoot(at, Heap::kHeapNumberMapRootIndex); |
4407 // This 'at' value and scratch1 map value are used for tests in both clauses | 4403 // This 'at' value and scratch1 map value are used for tests in both clauses |
4408 // of the if. | 4404 // of the if. |
4409 | 4405 |
4410 if (instr->truncating()) { | 4406 if (instr->truncating()) { |
4411 Register scratch3 = ToRegister(instr->temp2()); | 4407 Register scratch3 = ToRegister(instr->temp2()); |
4412 DoubleRegister double_scratch2 = ToDoubleRegister(instr->temp3()); | 4408 FPURegister single_scratch = double_scratch.low(); |
4413 ASSERT(!scratch3.is(input_reg) && | 4409 ASSERT(!scratch3.is(input_reg) && |
4414 !scratch3.is(scratch1) && | 4410 !scratch3.is(scratch1) && |
4415 !scratch3.is(scratch2)); | 4411 !scratch3.is(scratch2)); |
4416 // Performs a truncating conversion of a floating point number as used by | 4412 // Performs a truncating conversion of a floating point number as used by |
4417 // the JS bitwise operations. | 4413 // the JS bitwise operations. |
4418 Label heap_number; | 4414 Label heap_number; |
4419 __ Branch(&heap_number, eq, scratch1, Operand(at)); // HeapNumber map? | 4415 __ Branch(&heap_number, eq, scratch1, Operand(at)); // HeapNumber map? |
4420 // Check for undefined. Undefined is converted to zero for truncating | 4416 // Check for undefined. Undefined is converted to zero for truncating |
4421 // conversions. | 4417 // conversions. |
4422 __ LoadRoot(at, Heap::kUndefinedValueRootIndex); | 4418 __ LoadRoot(at, Heap::kUndefinedValueRootIndex); |
(...skipping 14 matching lines...) Expand all Loading... |
4437 } else { | 4433 } else { |
4438 // Deoptimize if we don't have a heap number. | 4434 // Deoptimize if we don't have a heap number. |
4439 DeoptimizeIf(ne, instr->environment(), scratch1, Operand(at)); | 4435 DeoptimizeIf(ne, instr->environment(), scratch1, Operand(at)); |
4440 | 4436 |
4441 // Load the double value. | 4437 // Load the double value. |
4442 __ ldc1(double_scratch, | 4438 __ ldc1(double_scratch, |
4443 FieldMemOperand(input_reg, HeapNumber::kValueOffset)); | 4439 FieldMemOperand(input_reg, HeapNumber::kValueOffset)); |
4444 | 4440 |
4445 Register except_flag = scratch2; | 4441 Register except_flag = scratch2; |
4446 __ EmitFPUTruncate(kRoundToZero, | 4442 __ EmitFPUTruncate(kRoundToZero, |
4447 single_scratch, | 4443 input_reg, |
4448 double_scratch, | 4444 double_scratch, |
4449 scratch1, | 4445 scratch1, |
| 4446 double_scratch2, |
4450 except_flag, | 4447 except_flag, |
4451 kCheckForInexactConversion); | 4448 kCheckForInexactConversion); |
4452 | 4449 |
4453 // Deopt if the operation did not succeed. | 4450 // Deopt if the operation did not succeed. |
4454 DeoptimizeIf(ne, instr->environment(), except_flag, Operand(zero_reg)); | 4451 DeoptimizeIf(ne, instr->environment(), except_flag, Operand(zero_reg)); |
4455 | 4452 |
4456 // Load the result. | |
4457 __ mfc1(input_reg, single_scratch); | |
4458 | |
4459 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { | 4453 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { |
4460 __ Branch(&done, ne, input_reg, Operand(zero_reg)); | 4454 __ Branch(&done, ne, input_reg, Operand(zero_reg)); |
4461 | 4455 |
4462 __ mfc1(scratch1, double_scratch.high()); | 4456 __ mfc1(scratch1, double_scratch.high()); |
4463 __ And(scratch1, scratch1, Operand(HeapNumber::kSignMask)); | 4457 __ And(scratch1, scratch1, Operand(HeapNumber::kSignMask)); |
4464 DeoptimizeIf(ne, instr->environment(), scratch1, Operand(zero_reg)); | 4458 DeoptimizeIf(ne, instr->environment(), scratch1, Operand(zero_reg)); |
4465 } | 4459 } |
4466 } | 4460 } |
4467 __ bind(&done); | 4461 __ bind(&done); |
4468 } | 4462 } |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4510 instr->hydrogen()->deoptimize_on_minus_zero(), | 4504 instr->hydrogen()->deoptimize_on_minus_zero(), |
4511 instr->environment()); | 4505 instr->environment()); |
4512 } | 4506 } |
4513 | 4507 |
4514 | 4508 |
4515 void LCodeGen::DoDoubleToI(LDoubleToI* instr) { | 4509 void LCodeGen::DoDoubleToI(LDoubleToI* instr) { |
4516 Register result_reg = ToRegister(instr->result()); | 4510 Register result_reg = ToRegister(instr->result()); |
4517 Register scratch1 = scratch0(); | 4511 Register scratch1 = scratch0(); |
4518 Register scratch2 = ToRegister(instr->temp()); | 4512 Register scratch2 = ToRegister(instr->temp()); |
4519 DoubleRegister double_input = ToDoubleRegister(instr->value()); | 4513 DoubleRegister double_input = ToDoubleRegister(instr->value()); |
4520 FPURegister single_scratch = double_scratch0().low(); | |
4521 | 4514 |
4522 if (instr->truncating()) { | 4515 if (instr->truncating()) { |
4523 Register scratch3 = ToRegister(instr->temp2()); | 4516 Register scratch3 = ToRegister(instr->temp2()); |
| 4517 FPURegister single_scratch = double_scratch0().low(); |
4524 __ EmitECMATruncate(result_reg, | 4518 __ EmitECMATruncate(result_reg, |
4525 double_input, | 4519 double_input, |
4526 single_scratch, | 4520 single_scratch, |
4527 scratch1, | 4521 scratch1, |
4528 scratch2, | 4522 scratch2, |
4529 scratch3); | 4523 scratch3); |
4530 } else { | 4524 } else { |
4531 Register except_flag = scratch2; | 4525 Register except_flag = scratch2; |
4532 | 4526 |
4533 __ EmitFPUTruncate(kRoundToMinusInf, | 4527 __ EmitFPUTruncate(kRoundToMinusInf, |
4534 single_scratch, | 4528 result_reg, |
4535 double_input, | 4529 double_input, |
4536 scratch1, | 4530 scratch1, |
| 4531 double_scratch0(), |
4537 except_flag, | 4532 except_flag, |
4538 kCheckForInexactConversion); | 4533 kCheckForInexactConversion); |
4539 | 4534 |
4540 // Deopt if the operation did not succeed (except_flag != 0). | 4535 // Deopt if the operation did not succeed (except_flag != 0). |
4541 DeoptimizeIf(ne, instr->environment(), except_flag, Operand(zero_reg)); | 4536 DeoptimizeIf(ne, instr->environment(), except_flag, Operand(zero_reg)); |
4542 | |
4543 // Load the result. | |
4544 __ mfc1(result_reg, single_scratch); | |
4545 } | 4537 } |
4546 } | 4538 } |
4547 | 4539 |
4548 | 4540 |
4549 void LCodeGen::DoCheckSmi(LCheckSmi* instr) { | 4541 void LCodeGen::DoCheckSmi(LCheckSmi* instr) { |
4550 LOperand* input = instr->value(); | 4542 LOperand* input = instr->value(); |
4551 __ And(at, ToRegister(input), Operand(kSmiTagMask)); | 4543 __ And(at, ToRegister(input), Operand(kSmiTagMask)); |
4552 DeoptimizeIf(ne, instr->environment(), at, Operand(zero_reg)); | 4544 DeoptimizeIf(ne, instr->environment(), at, Operand(zero_reg)); |
4553 } | 4545 } |
4554 | 4546 |
(...skipping 946 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5501 __ Subu(scratch, result, scratch); | 5493 __ Subu(scratch, result, scratch); |
5502 __ lw(result, FieldMemOperand(scratch, | 5494 __ lw(result, FieldMemOperand(scratch, |
5503 FixedArray::kHeaderSize - kPointerSize)); | 5495 FixedArray::kHeaderSize - kPointerSize)); |
5504 __ bind(&done); | 5496 __ bind(&done); |
5505 } | 5497 } |
5506 | 5498 |
5507 | 5499 |
5508 #undef __ | 5500 #undef __ |
5509 | 5501 |
5510 } } // namespace v8::internal | 5502 } } // namespace v8::internal |
OLD | NEW |