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

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

Issue 6625084: ARM: Improved double to integer truncation.... (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: '' Created 9 years, 9 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/arm/lithium-arm.cc ('k') | src/arm/macro-assembler-arm.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 2011 the V8 project authors. All rights reserved. 1 // Copyright 2011 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 3292 matching lines...) Expand 10 before | Expand all | Expand 10 after
3303 public: 3303 public:
3304 DeferredTaggedToI(LCodeGen* codegen, LTaggedToI* instr) 3304 DeferredTaggedToI(LCodeGen* codegen, LTaggedToI* instr)
3305 : LDeferredCode(codegen), instr_(instr) { } 3305 : LDeferredCode(codegen), instr_(instr) { }
3306 virtual void Generate() { codegen()->DoDeferredTaggedToI(instr_); } 3306 virtual void Generate() { codegen()->DoDeferredTaggedToI(instr_); }
3307 private: 3307 private:
3308 LTaggedToI* instr_; 3308 LTaggedToI* instr_;
3309 }; 3309 };
3310 3310
3311 3311
3312 void LCodeGen::DoDeferredTaggedToI(LTaggedToI* instr) { 3312 void LCodeGen::DoDeferredTaggedToI(LTaggedToI* instr) {
3313 Register input_reg = ToRegister(instr->InputAt(0));
3314 Register scratch1 = scratch0();
3315 Register scratch2 = ToRegister(instr->TempAt(0));
3316 DwVfpRegister double_scratch = double_scratch0();
3317 SwVfpRegister single_scratch = double_scratch.low();
3318
3319 ASSERT(!scratch1.is(input_reg) && !scratch1.is(scratch2));
3320 ASSERT(!scratch2.is(input_reg) && !scratch2.is(scratch1));
3321
3313 Label done; 3322 Label done;
3314 Register input_reg = ToRegister(instr->InputAt(0));
3315 Register scratch = scratch0();
3316 DoubleRegister dbl_scratch = d0;
3317 SwVfpRegister flt_scratch = s0;
3318 DoubleRegister dbl_tmp = ToDoubleRegister(instr->TempAt(0));
3319 3323
3320 // Heap number map check. 3324 // Heap number map check.
3321 __ ldr(scratch, FieldMemOperand(input_reg, HeapObject::kMapOffset)); 3325 __ ldr(scratch1, FieldMemOperand(input_reg, HeapObject::kMapOffset));
3322 __ LoadRoot(ip, Heap::kHeapNumberMapRootIndex); 3326 __ LoadRoot(ip, Heap::kHeapNumberMapRootIndex);
3323 __ cmp(scratch, Operand(ip)); 3327 __ cmp(scratch1, Operand(ip));
3324 3328
3325 if (instr->truncating()) { 3329 if (instr->truncating()) {
3330 Register scratch3 = ToRegister(instr->TempAt(1));
3331 DwVfpRegister double_scratch2 = ToDoubleRegister(instr->TempAt(2));
3332 ASSERT(!scratch3.is(input_reg) &&
3333 !scratch3.is(scratch1) &&
3334 !scratch3.is(scratch2));
3335 // Performs a truncating conversion of a floating point number as used by
3336 // the JS bitwise operations.
3326 Label heap_number; 3337 Label heap_number;
3327 __ b(eq, &heap_number); 3338 __ b(eq, &heap_number);
3328 // Check for undefined. Undefined is converted to zero for truncating 3339 // Check for undefined. Undefined is converted to zero for truncating
3329 // conversions. 3340 // conversions.
3330 __ LoadRoot(ip, Heap::kUndefinedValueRootIndex); 3341 __ LoadRoot(ip, Heap::kUndefinedValueRootIndex);
3331 __ cmp(input_reg, Operand(ip)); 3342 __ cmp(input_reg, Operand(ip));
3332 DeoptimizeIf(ne, instr->environment()); 3343 DeoptimizeIf(ne, instr->environment());
3333 __ mov(input_reg, Operand(0)); 3344 __ mov(input_reg, Operand(0));
3334 __ b(&done); 3345 __ b(&done);
3335 3346
3336 __ bind(&heap_number); 3347 __ bind(&heap_number);
3337 __ sub(ip, input_reg, Operand(kHeapObjectTag)); 3348 __ sub(scratch1, input_reg, Operand(kHeapObjectTag));
3338 __ vldr(dbl_tmp, ip, HeapNumber::kValueOffset); 3349 __ vldr(double_scratch2, scratch1, HeapNumber::kValueOffset);
3339 __ vcmp(dbl_tmp, 0.0); // Sets overflow bit in FPSCR flags if NaN. 3350
3340 __ vcvt_s32_f64(flt_scratch, dbl_tmp); 3351 __ EmitECMATruncate(input_reg,
3341 __ vmov(input_reg, flt_scratch); // 32-bit result of conversion. 3352 double_scratch2,
3342 __ vmrs(pc); // Move vector status bits to normal status bits. 3353 single_scratch,
3343 // Overflow bit is set if dbl_tmp is Nan. 3354 scratch1,
3344 __ cmn(input_reg, Operand(1), vc); // 0x7fffffff + 1 -> overflow. 3355 scratch2,
3345 __ cmp(input_reg, Operand(1), vc); // 0x80000000 - 1 -> overflow. 3356 scratch3);
3346 DeoptimizeIf(vs, instr->environment()); // Saturation may have occured.
3347 3357
3348 } else { 3358 } else {
3359 CpuFeatures::Scope scope(VFP3);
3349 // Deoptimize if we don't have a heap number. 3360 // Deoptimize if we don't have a heap number.
3350 DeoptimizeIf(ne, instr->environment()); 3361 DeoptimizeIf(ne, instr->environment());
3351 3362
3352 __ sub(ip, input_reg, Operand(kHeapObjectTag)); 3363 __ sub(ip, input_reg, Operand(kHeapObjectTag));
3353 __ vldr(dbl_tmp, ip, HeapNumber::kValueOffset); 3364 __ vldr(double_scratch, ip, HeapNumber::kValueOffset);
3354 __ vcvt_s32_f64(flt_scratch, dbl_tmp); 3365 __ EmitVFPTruncate(kRoundToZero,
3355 __ vmov(input_reg, flt_scratch); // 32-bit result of conversion. 3366 single_scratch,
3356 // Non-truncating conversion means that we cannot lose bits, so we convert 3367 double_scratch,
3357 // back to check; note that using non-overlapping s and d regs would be 3368 scratch1,
3358 // slightly faster. 3369 scratch2,
3359 __ vcvt_f64_s32(dbl_scratch, flt_scratch); 3370 kCheckForInexactConversion);
3360 __ VFPCompareAndSetFlags(dbl_scratch, dbl_tmp); 3371 DeoptimizeIf(ne, instr->environment());
3361 DeoptimizeIf(ne, instr->environment()); // Not equal or unordered. 3372 // Load the result.
3373 __ vmov(input_reg, single_scratch);
3374
3362 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { 3375 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
3363 __ tst(input_reg, Operand(input_reg)); 3376 __ cmp(input_reg, Operand(0));
3364 __ b(ne, &done); 3377 __ b(ne, &done);
3365 __ vmov(lr, ip, dbl_tmp); 3378 __ vmov(scratch1, double_scratch.high());
3366 __ tst(ip, Operand(1 << 31)); // Test sign bit. 3379 __ tst(scratch1, Operand(HeapNumber::kSignMask));
3367 DeoptimizeIf(ne, instr->environment()); 3380 DeoptimizeIf(ne, instr->environment());
3368 } 3381 }
3369 } 3382 }
3370 __ bind(&done); 3383 __ bind(&done);
3371 } 3384 }
3372 3385
3373 3386
3374 void LCodeGen::DoTaggedToI(LTaggedToI* instr) { 3387 void LCodeGen::DoTaggedToI(LTaggedToI* instr) {
3375 LOperand* input = instr->InputAt(0); 3388 LOperand* input = instr->InputAt(0);
3376 ASSERT(input->IsRegister()); 3389 ASSERT(input->IsRegister());
(...skipping 21 matching lines...) Expand all
3398 ASSERT(result->IsDoubleRegister()); 3411 ASSERT(result->IsDoubleRegister());
3399 3412
3400 Register input_reg = ToRegister(input); 3413 Register input_reg = ToRegister(input);
3401 DoubleRegister result_reg = ToDoubleRegister(result); 3414 DoubleRegister result_reg = ToDoubleRegister(result);
3402 3415
3403 EmitNumberUntagD(input_reg, result_reg, instr->environment()); 3416 EmitNumberUntagD(input_reg, result_reg, instr->environment());
3404 } 3417 }
3405 3418
3406 3419
3407 void LCodeGen::DoDoubleToI(LDoubleToI* instr) { 3420 void LCodeGen::DoDoubleToI(LDoubleToI* instr) {
3408 LOperand* input = instr->InputAt(0); 3421 Register result_reg = ToRegister(instr->result());
3409 ASSERT(input->IsDoubleRegister());
3410 LOperand* result = instr->result();
3411 ASSERT(result->IsRegister());
3412
3413 DoubleRegister double_input = ToDoubleRegister(input);
3414 Register result_reg = ToRegister(result);
3415 SwVfpRegister single_scratch = double_scratch0().low();
3416 Register scratch1 = scratch0(); 3422 Register scratch1 = scratch0();
3417 Register scratch2 = ToRegister(instr->TempAt(0)); 3423 Register scratch2 = ToRegister(instr->TempAt(0));
3424 DwVfpRegister double_input = ToDoubleRegister(instr->InputAt(0));
3425 DwVfpRegister double_scratch = double_scratch0();
3426 SwVfpRegister single_scratch = double_scratch0().low();
3418 3427
3419 __ EmitVFPTruncate(kRoundToZero, 3428 Label done;
3420 single_scratch,
3421 double_input,
3422 scratch1,
3423 scratch2);
3424 3429
3425 // Deoptimize if we had a vfp invalid exception. 3430 if (instr->truncating()) {
3426 DeoptimizeIf(ne, instr->environment()); 3431 Register scratch3 = ToRegister(instr->TempAt(1));
3427 3432 __ EmitECMATruncate(result_reg,
3428 // Retrieve the result. 3433 double_input,
3429 __ vmov(result_reg, single_scratch); 3434 single_scratch,
3430 3435 scratch1,
3431 if (!instr->truncating()) { 3436 scratch2,
3432 // Convert result back to double and compare with input 3437 scratch3);
3433 // to check if the conversion was exact. 3438 } else {
3434 __ vmov(single_scratch, result_reg); 3439 VFPRoundingMode rounding_mode = kRoundToMinusInf;
3435 __ vcvt_f64_s32(double_scratch0(), single_scratch); 3440 __ EmitVFPTruncate(rounding_mode,
3436 __ VFPCompareAndSetFlags(double_scratch0(), double_input); 3441 single_scratch,
3442 double_input,
3443 scratch1,
3444 scratch2,
3445 kCheckForInexactConversion);
3446 // Deoptimize if we had a vfp invalid exception,
3447 // including inexact operation.
3437 DeoptimizeIf(ne, instr->environment()); 3448 DeoptimizeIf(ne, instr->environment());
3438 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { 3449 // Retrieve the result.
3439 Label done; 3450 __ vmov(result_reg, single_scratch);
3440 __ cmp(result_reg, Operand(0));
3441 __ b(ne, &done);
3442 // Check for -0.
3443 __ vmov(scratch1, double_input.high());
3444 __ tst(scratch1, Operand(HeapNumber::kSignMask));
3445 DeoptimizeIf(ne, instr->environment());
3446
3447 __ bind(&done);
3448 }
3449 } 3451 }
3452 __ bind(&done);
3450 } 3453 }
3451 3454
3452 3455
3453 void LCodeGen::DoCheckSmi(LCheckSmi* instr) { 3456 void LCodeGen::DoCheckSmi(LCheckSmi* instr) {
3454 LOperand* input = instr->InputAt(0); 3457 LOperand* input = instr->InputAt(0);
3455 ASSERT(input->IsRegister()); 3458 ASSERT(input->IsRegister());
3456 __ tst(ToRegister(input), Operand(kSmiTagMask)); 3459 __ tst(ToRegister(input), Operand(kSmiTagMask));
3457 DeoptimizeIf(instr->condition(), instr->environment()); 3460 DeoptimizeIf(instr->condition(), instr->environment());
3458 } 3461 }
3459 3462
(...skipping 417 matching lines...) Expand 10 before | Expand all | Expand 10 after
3877 ASSERT(!environment->HasBeenRegistered()); 3880 ASSERT(!environment->HasBeenRegistered());
3878 RegisterEnvironmentForDeoptimization(environment); 3881 RegisterEnvironmentForDeoptimization(environment);
3879 ASSERT(osr_pc_offset_ == -1); 3882 ASSERT(osr_pc_offset_ == -1);
3880 osr_pc_offset_ = masm()->pc_offset(); 3883 osr_pc_offset_ = masm()->pc_offset();
3881 } 3884 }
3882 3885
3883 3886
3884 #undef __ 3887 #undef __
3885 3888
3886 } } // namespace v8::internal 3889 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/arm/lithium-arm.cc ('k') | src/arm/macro-assembler-arm.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698