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

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

Issue 6881003: Prevent deopt when assigning double values to typed arrays (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Fixes to make ia32 tests run Created 9 years, 8 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
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 265 matching lines...) Expand 10 before | Expand all | Expand 10 after
276 276
277 277
278 XMMRegister LCodeGen::ToDoubleRegister(LOperand* op) const { 278 XMMRegister LCodeGen::ToDoubleRegister(LOperand* op) const {
279 ASSERT(op->IsDoubleRegister()); 279 ASSERT(op->IsDoubleRegister());
280 return ToDoubleRegister(op->index()); 280 return ToDoubleRegister(op->index());
281 } 281 }
282 282
283 283
284 int LCodeGen::ToInteger32(LConstantOperand* op) const { 284 int LCodeGen::ToInteger32(LConstantOperand* op) const {
285 Handle<Object> value = chunk_->LookupLiteral(op); 285 Handle<Object> value = chunk_->LookupLiteral(op);
286 ASSERT(chunk_->LookupLiteralRepresentation(op).IsInteger32()); 286 ASSERT(chunk_->LookupLiteralRepresentation(op).IsInteger());
287 ASSERT(static_cast<double>(static_cast<int32_t>(value->Number())) == 287 ASSERT(static_cast<double>(static_cast<int32_t>(value->Number())) ==
288 value->Number()); 288 value->Number());
289 return static_cast<int32_t>(value->Number()); 289 return static_cast<int32_t>(value->Number());
290 } 290 }
291 291
292 292
293 Immediate LCodeGen::ToImmediate(LOperand* op) { 293 Immediate LCodeGen::ToImmediate(LOperand* op) {
294 LConstantOperand* const_op = LConstantOperand::cast(op); 294 LConstantOperand* const_op = LConstantOperand::cast(op);
295 Handle<Object> literal = chunk_->LookupLiteral(const_op); 295 Handle<Object> literal = chunk_->LookupLiteral(const_op);
296 Representation r = chunk_->LookupLiteralRepresentation(const_op); 296 Representation r = chunk_->LookupLiteralRepresentation(const_op);
297 if (r.IsInteger32()) { 297 if (r.IsInteger()) {
298 ASSERT(literal->IsNumber()); 298 ASSERT(literal->IsNumber());
299 return Immediate(static_cast<int32_t>(literal->Number())); 299 if (r.IsClampedRoundedInteger8()) {
300 return Immediate(ClampToUInt8(literal->Number()));
301 } else {
302 return Immediate(static_cast<int32_t>(literal->Number()));
303 }
300 } else if (r.IsDouble()) { 304 } else if (r.IsDouble()) {
301 Abort("unsupported double immediate"); 305 Abort("unsupported double immediate");
302 } 306 }
303 ASSERT(r.IsTagged()); 307 ASSERT(r.IsTagged());
304 return Immediate(literal); 308 return Immediate(literal);
305 } 309 }
306 310
307 311
308 Operand LCodeGen::ToOperand(LOperand* op) const { 312 Operand LCodeGen::ToOperand(LOperand* op) const {
309 if (op->IsRegister()) return Operand(ToRegister(op)); 313 if (op->IsRegister()) return Operand(ToRegister(op));
(...skipping 966 matching lines...) Expand 10 before | Expand all | Expand 10 after
1276 __ jmp(chunk_->GetAssemblyLabel(right_block)); 1280 __ jmp(chunk_->GetAssemblyLabel(right_block));
1277 } 1281 }
1278 } 1282 }
1279 1283
1280 1284
1281 void LCodeGen::DoBranch(LBranch* instr) { 1285 void LCodeGen::DoBranch(LBranch* instr) {
1282 int true_block = chunk_->LookupDestination(instr->true_block_id()); 1286 int true_block = chunk_->LookupDestination(instr->true_block_id());
1283 int false_block = chunk_->LookupDestination(instr->false_block_id()); 1287 int false_block = chunk_->LookupDestination(instr->false_block_id());
1284 1288
1285 Representation r = instr->hydrogen()->representation(); 1289 Representation r = instr->hydrogen()->representation();
1286 if (r.IsInteger32()) { 1290 if (r.IsInteger()) {
1287 Register reg = ToRegister(instr->InputAt(0)); 1291 Register reg = ToRegister(instr->InputAt(0));
1288 __ test(reg, Operand(reg)); 1292 __ test(reg, Operand(reg));
1289 EmitBranch(true_block, false_block, not_zero); 1293 EmitBranch(true_block, false_block, not_zero);
1290 } else if (r.IsDouble()) { 1294 } else if (r.IsDouble()) {
1291 XMMRegister reg = ToDoubleRegister(instr->InputAt(0)); 1295 XMMRegister reg = ToDoubleRegister(instr->InputAt(0));
1292 __ xorpd(xmm0, xmm0); 1296 __ xorpd(xmm0, xmm0);
1293 __ ucomisd(reg, xmm0); 1297 __ ucomisd(reg, xmm0);
1294 EmitBranch(true_block, false_block, not_equal); 1298 EmitBranch(true_block, false_block, not_equal);
1295 } else { 1299 } else {
1296 ASSERT(r.IsTagged()); 1300 ASSERT(r.IsTagged());
(...skipping 1361 matching lines...) Expand 10 before | Expand all | Expand 10 after
2658 2662
2659 ASSERT(instr->InputAt(0)->Equals(instr->result())); 2663 ASSERT(instr->InputAt(0)->Equals(instr->result()));
2660 Representation r = instr->hydrogen()->value()->representation(); 2664 Representation r = instr->hydrogen()->value()->representation();
2661 2665
2662 if (r.IsDouble()) { 2666 if (r.IsDouble()) {
2663 XMMRegister scratch = xmm0; 2667 XMMRegister scratch = xmm0;
2664 XMMRegister input_reg = ToDoubleRegister(instr->InputAt(0)); 2668 XMMRegister input_reg = ToDoubleRegister(instr->InputAt(0));
2665 __ pxor(scratch, scratch); 2669 __ pxor(scratch, scratch);
2666 __ subsd(scratch, input_reg); 2670 __ subsd(scratch, input_reg);
2667 __ pand(input_reg, scratch); 2671 __ pand(input_reg, scratch);
2668 } else if (r.IsInteger32()) { 2672 } else if (r.IsInteger()) {
2669 EmitIntegerMathAbs(instr); 2673 EmitIntegerMathAbs(instr);
2670 } else { // Tagged case. 2674 } else { // Tagged case.
2671 DeferredMathAbsTaggedHeapNumber* deferred = 2675 DeferredMathAbsTaggedHeapNumber* deferred =
2672 new DeferredMathAbsTaggedHeapNumber(this, instr); 2676 new DeferredMathAbsTaggedHeapNumber(this, instr);
2673 Register input_reg = ToRegister(instr->InputAt(0)); 2677 Register input_reg = ToRegister(instr->InputAt(0));
2674 // Smi check. 2678 // Smi check.
2675 __ test(input_reg, Immediate(kSmiTagMask)); 2679 __ test(input_reg, Immediate(kSmiTagMask));
2676 __ j(not_zero, deferred->entry()); 2680 __ j(not_zero, deferred->entry());
2677 EmitIntegerMathAbs(instr); 2681 EmitIntegerMathAbs(instr);
2678 __ bind(deferred->exit()); 2682 __ bind(deferred->exit());
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after
2773 Representation exponent_type = instr->hydrogen()->right()->representation(); 2777 Representation exponent_type = instr->hydrogen()->right()->representation();
2774 2778
2775 if (exponent_type.IsDouble()) { 2779 if (exponent_type.IsDouble()) {
2776 // It is safe to use ebx directly since the instruction is marked 2780 // It is safe to use ebx directly since the instruction is marked
2777 // as a call. 2781 // as a call.
2778 __ PrepareCallCFunction(4, ebx); 2782 __ PrepareCallCFunction(4, ebx);
2779 __ movdbl(Operand(esp, 0 * kDoubleSize), ToDoubleRegister(left)); 2783 __ movdbl(Operand(esp, 0 * kDoubleSize), ToDoubleRegister(left));
2780 __ movdbl(Operand(esp, 1 * kDoubleSize), ToDoubleRegister(right)); 2784 __ movdbl(Operand(esp, 1 * kDoubleSize), ToDoubleRegister(right));
2781 __ CallCFunction(ExternalReference::power_double_double_function(isolate()), 2785 __ CallCFunction(ExternalReference::power_double_double_function(isolate()),
2782 4); 2786 4);
2783 } else if (exponent_type.IsInteger32()) { 2787 } else if (exponent_type.IsInteger()) {
2784 // It is safe to use ebx directly since the instruction is marked 2788 // It is safe to use ebx directly since the instruction is marked
2785 // as a call. 2789 // as a call.
2786 ASSERT(!ToRegister(right).is(ebx)); 2790 ASSERT(!ToRegister(right).is(ebx));
2787 __ PrepareCallCFunction(4, ebx); 2791 __ PrepareCallCFunction(4, ebx);
2788 __ movdbl(Operand(esp, 0 * kDoubleSize), ToDoubleRegister(left)); 2792 __ movdbl(Operand(esp, 0 * kDoubleSize), ToDoubleRegister(left));
2789 __ mov(Operand(esp, 1 * kDoubleSize), ToRegister(right)); 2793 __ mov(Operand(esp, 1 * kDoubleSize), ToRegister(right));
2790 __ CallCFunction(ExternalReference::power_double_int_function(isolate()), 2794 __ CallCFunction(ExternalReference::power_double_int_function(isolate()),
2791 4); 2795 4);
2792 } else { 2796 } else {
2793 ASSERT(exponent_type.IsTagged()); 2797 ASSERT(exponent_type.IsTagged());
(...skipping 250 matching lines...) Expand 10 before | Expand all | Expand 10 after
3044 Register external_pointer = ToRegister(instr->external_pointer()); 3048 Register external_pointer = ToRegister(instr->external_pointer());
3045 Register key = ToRegister(instr->key()); 3049 Register key = ToRegister(instr->key());
3046 ExternalArrayType array_type = instr->array_type(); 3050 ExternalArrayType array_type = instr->array_type();
3047 if (array_type == kExternalFloatArray) { 3051 if (array_type == kExternalFloatArray) {
3048 __ cvtsd2ss(xmm0, ToDoubleRegister(instr->value())); 3052 __ cvtsd2ss(xmm0, ToDoubleRegister(instr->value()));
3049 __ movss(Operand(external_pointer, key, times_4, 0), xmm0); 3053 __ movss(Operand(external_pointer, key, times_4, 0), xmm0);
3050 } else { 3054 } else {
3051 Register value = ToRegister(instr->value()); 3055 Register value = ToRegister(instr->value());
3052 switch (array_type) { 3056 switch (array_type) {
3053 case kExternalPixelArray: { 3057 case kExternalPixelArray: {
3054 // Clamp the value to [0..255]. 3058 ASSERT(value.is(eax));
3055 Register temp = ToRegister(instr->TempAt(0)); 3059 __ mov_b(Operand(external_pointer, key, times_1, 0), value);
3056 // The dec_b below requires that the clamped value is in a byte
3057 // register. eax is an arbitrary choice to satisfy this requirement, we
3058 // hinted the register allocator to give us eax when building the
3059 // instruction.
3060 ASSERT(temp.is(eax));
3061 __ mov(temp, ToRegister(instr->value()));
3062 NearLabel done;
3063 __ test(temp, Immediate(0xFFFFFF00));
3064 __ j(zero, &done);
3065 __ setcc(negative, temp); // 1 if negative, 0 if positive.
3066 __ dec_b(temp); // 0 if negative, 255 if positive.
3067 __ bind(&done);
3068 __ mov_b(Operand(external_pointer, key, times_1, 0), temp);
3069 break; 3060 break;
3070 } 3061 }
3071 case kExternalByteArray: 3062 case kExternalByteArray:
3072 case kExternalUnsignedByteArray: 3063 case kExternalUnsignedByteArray:
3073 __ mov_b(Operand(external_pointer, key, times_1, 0), value); 3064 __ mov_b(Operand(external_pointer, key, times_1, 0), value);
3074 break; 3065 break;
3075 case kExternalShortArray: 3066 case kExternalShortArray:
3076 case kExternalUnsignedShortArray: 3067 case kExternalUnsignedShortArray:
3077 __ mov_w(Operand(external_pointer, key, times_2, 0), value); 3068 __ mov_w(Operand(external_pointer, key, times_2, 0), value);
3078 break; 3069 break;
(...skipping 196 matching lines...) Expand 10 before | Expand all | Expand 10 after
3275 DeferredStringCharFromCode(LCodeGen* codegen, LStringCharFromCode* instr) 3266 DeferredStringCharFromCode(LCodeGen* codegen, LStringCharFromCode* instr)
3276 : LDeferredCode(codegen), instr_(instr) { } 3267 : LDeferredCode(codegen), instr_(instr) { }
3277 virtual void Generate() { codegen()->DoDeferredStringCharFromCode(instr_); } 3268 virtual void Generate() { codegen()->DoDeferredStringCharFromCode(instr_); }
3278 private: 3269 private:
3279 LStringCharFromCode* instr_; 3270 LStringCharFromCode* instr_;
3280 }; 3271 };
3281 3272
3282 DeferredStringCharFromCode* deferred = 3273 DeferredStringCharFromCode* deferred =
3283 new DeferredStringCharFromCode(this, instr); 3274 new DeferredStringCharFromCode(this, instr);
3284 3275
3285 ASSERT(instr->hydrogen()->value()->representation().IsInteger32()); 3276 ASSERT(instr->hydrogen()->value()->representation().IsInteger());
3286 Register char_code = ToRegister(instr->char_code()); 3277 Register char_code = ToRegister(instr->char_code());
3287 Register result = ToRegister(instr->result()); 3278 Register result = ToRegister(instr->result());
3288 ASSERT(!char_code.is(result)); 3279 ASSERT(!char_code.is(result));
3289 3280
3290 __ cmp(char_code, String::kMaxAsciiCharCode); 3281 __ cmp(char_code, String::kMaxAsciiCharCode);
3291 __ j(above, deferred->entry()); 3282 __ j(above, deferred->entry());
3292 __ Set(result, Immediate(factory()->single_character_string_cache())); 3283 __ Set(result, Immediate(factory()->single_character_string_cache()));
3293 __ mov(result, FieldOperand(result, 3284 __ mov(result, FieldOperand(result,
3294 char_code, times_pointer_size, 3285 char_code, times_pointer_size,
3295 FixedArray::kHeaderSize)); 3286 FixedArray::kHeaderSize));
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
3341 3332
3342 void LCodeGen::DoInteger32ToDouble(LInteger32ToDouble* instr) { 3333 void LCodeGen::DoInteger32ToDouble(LInteger32ToDouble* instr) {
3343 LOperand* input = instr->InputAt(0); 3334 LOperand* input = instr->InputAt(0);
3344 ASSERT(input->IsRegister() || input->IsStackSlot()); 3335 ASSERT(input->IsRegister() || input->IsStackSlot());
3345 LOperand* output = instr->result(); 3336 LOperand* output = instr->result();
3346 ASSERT(output->IsDoubleRegister()); 3337 ASSERT(output->IsDoubleRegister());
3347 __ cvtsi2sd(ToDoubleRegister(output), ToOperand(input)); 3338 __ cvtsi2sd(ToDoubleRegister(output), ToOperand(input));
3348 } 3339 }
3349 3340
3350 3341
3342 void LCodeGen::DoInteger32ToClamped(LInteger32ToClamped* instr) {
3343 LOperand* input = instr->InputAt(0);
3344 ASSERT(input->IsRegister());
3345 Register reg = ToRegister(input);
3346 ASSERT(reg.is(ToRegister(instr->result())));
3347 __ ClampUInt8(reg);
3348 }
3349
3350
3351 void LCodeGen::DoNumberTagI(LNumberTagI* instr) { 3351 void LCodeGen::DoNumberTagI(LNumberTagI* instr) {
3352 class DeferredNumberTagI: public LDeferredCode { 3352 class DeferredNumberTagI: public LDeferredCode {
3353 public: 3353 public:
3354 DeferredNumberTagI(LCodeGen* codegen, LNumberTagI* instr) 3354 DeferredNumberTagI(LCodeGen* codegen, LNumberTagI* instr)
3355 : LDeferredCode(codegen), instr_(instr) { } 3355 : LDeferredCode(codegen), instr_(instr) { }
3356 virtual void Generate() { codegen()->DoDeferredNumberTagI(instr_); } 3356 virtual void Generate() { codegen()->DoDeferredNumberTagI(instr_); }
3357 private: 3357 private:
3358 LNumberTagI* instr_; 3358 LNumberTagI* instr_;
3359 }; 3359 };
3360 3360
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after
3454 } 3454 }
3455 3455
3456 3456
3457 void LCodeGen::DoSmiUntag(LSmiUntag* instr) { 3457 void LCodeGen::DoSmiUntag(LSmiUntag* instr) {
3458 LOperand* input = instr->InputAt(0); 3458 LOperand* input = instr->InputAt(0);
3459 ASSERT(input->IsRegister() && input->Equals(instr->result())); 3459 ASSERT(input->IsRegister() && input->Equals(instr->result()));
3460 if (instr->needs_check()) { 3460 if (instr->needs_check()) {
3461 __ test(ToRegister(input), Immediate(kSmiTagMask)); 3461 __ test(ToRegister(input), Immediate(kSmiTagMask));
3462 DeoptimizeIf(not_zero, instr->environment()); 3462 DeoptimizeIf(not_zero, instr->environment());
3463 } 3463 }
3464 __ SmiUntag(ToRegister(input)); 3464 Register input_reg = ToRegister(input);
3465 __ SmiUntag(input_reg);
3466
3467 if (instr->should_clamp()) {
3468 __ ClampUInt8(input_reg);
3469 }
3465 } 3470 }
3466 3471
3467 3472
3468 void LCodeGen::EmitNumberUntagD(Register input_reg, 3473 void LCodeGen::EmitNumberUntagD(Register input_reg,
3469 XMMRegister result_reg, 3474 XMMRegister result_reg,
3470 LEnvironment* env) { 3475 LEnvironment* env) {
3471 NearLabel load_smi, heap_number, done; 3476 NearLabel load_smi, heap_number, done;
3472 3477
3473 // Smi check. 3478 // Smi check.
3474 __ test(input_reg, Immediate(kSmiTagMask)); 3479 __ test(input_reg, Immediate(kSmiTagMask));
(...skipping 30 matching lines...) Expand all
3505 public: 3510 public:
3506 DeferredTaggedToI(LCodeGen* codegen, LTaggedToI* instr) 3511 DeferredTaggedToI(LCodeGen* codegen, LTaggedToI* instr)
3507 : LDeferredCode(codegen), instr_(instr) { } 3512 : LDeferredCode(codegen), instr_(instr) { }
3508 virtual void Generate() { codegen()->DoDeferredTaggedToI(instr_); } 3513 virtual void Generate() { codegen()->DoDeferredTaggedToI(instr_); }
3509 private: 3514 private:
3510 LTaggedToI* instr_; 3515 LTaggedToI* instr_;
3511 }; 3516 };
3512 3517
3513 3518
3514 void LCodeGen::DoDeferredTaggedToI(LTaggedToI* instr) { 3519 void LCodeGen::DoDeferredTaggedToI(LTaggedToI* instr) {
3515 NearLabel done, heap_number; 3520 NearLabel done;
3516 Register input_reg = ToRegister(instr->InputAt(0)); 3521 Register input_reg = ToRegister(instr->InputAt(0));
3517 3522
3518 // Heap number map check. 3523 // Heap number map check.
3519 __ cmp(FieldOperand(input_reg, HeapObject::kMapOffset), 3524 __ cmp(FieldOperand(input_reg, HeapObject::kMapOffset),
3520 factory()->heap_number_map()); 3525 factory()->heap_number_map());
3521 3526
3522 if (instr->truncating()) { 3527 Representation r = instr->hydrogen()->representation();
3528 if (r.IsClampedRoundedInteger8()) {
3529 NearLabel heap_number;
3523 __ j(equal, &heap_number); 3530 __ j(equal, &heap_number);
3524 // Check for undefined. Undefined is converted to zero for truncating 3531 // Check for undefined. Undefined is converted to zero for truncating
3525 // conversions. 3532 // conversions.
3533 __ cmp(input_reg, factory()->undefined_value());
3534 DeoptimizeIf(not_equal, instr->environment());
3535 __ mov(input_reg, 0);
3536 __ jmp(&done);
3537
3538 __ bind(&heap_number);
3539 XMMRegister xmm_temp = ToDoubleRegister(instr->TempAt(0));
3540 __ movdbl(xmm_temp, FieldOperand(input_reg, HeapNumber::kValueOffset));
3541 __ ClampDoubleToUInt8(xmm_temp, input_reg);
3542 } else if (r.IsTruncatedInteger32()) {
3543 NearLabel heap_number;
3544 __ j(equal, &heap_number);
3545 // Check for undefined. Undefined is converted to zero for truncating
3546 // conversions.
3526 __ cmp(input_reg, factory()->undefined_value()); 3547 __ cmp(input_reg, factory()->undefined_value());
3527 DeoptimizeIf(not_equal, instr->environment()); 3548 DeoptimizeIf(not_equal, instr->environment());
3528 __ mov(input_reg, 0); 3549 __ mov(input_reg, 0);
3529 __ jmp(&done); 3550 __ jmp(&done);
3530 3551
3531 __ bind(&heap_number); 3552 __ bind(&heap_number);
3532 if (CpuFeatures::IsSupported(SSE3)) { 3553 if (CpuFeatures::IsSupported(SSE3)) {
3533 CpuFeatures::Scope scope(SSE3); 3554 CpuFeatures::Scope scope(SSE3);
3534 NearLabel convert; 3555 NearLabel convert;
3535 // Use more powerful conversion when sse3 is available. 3556 // Use more powerful conversion when sse3 is available.
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
3600 Register input_reg = ToRegister(input); 3621 Register input_reg = ToRegister(input);
3601 3622
3602 DeferredTaggedToI* deferred = new DeferredTaggedToI(this, instr); 3623 DeferredTaggedToI* deferred = new DeferredTaggedToI(this, instr);
3603 3624
3604 // Smi check. 3625 // Smi check.
3605 __ test(input_reg, Immediate(kSmiTagMask)); 3626 __ test(input_reg, Immediate(kSmiTagMask));
3606 __ j(not_zero, deferred->entry()); 3627 __ j(not_zero, deferred->entry());
3607 3628
3608 // Smi to int32 conversion 3629 // Smi to int32 conversion
3609 __ SmiUntag(input_reg); // Untag smi. 3630 __ SmiUntag(input_reg); // Untag smi.
3631 Representation r = instr->hydrogen()->representation();
3632 if (r.IsClampedRoundedInteger8()) {
3633 __ ClampUInt8(input_reg);
3634 }
3610 3635
3611 __ bind(deferred->exit()); 3636 __ bind(deferred->exit());
3612 } 3637 }
3613 3638
3614 3639
3615 void LCodeGen::DoNumberUntagD(LNumberUntagD* instr) { 3640 void LCodeGen::DoNumberUntagD(LNumberUntagD* instr) {
3616 LOperand* input = instr->InputAt(0); 3641 LOperand* input = instr->InputAt(0);
3617 ASSERT(input->IsRegister()); 3642 ASSERT(input->IsRegister());
3618 LOperand* result = instr->result(); 3643 LOperand* result = instr->result();
3619 ASSERT(result->IsDoubleRegister()); 3644 ASSERT(result->IsDoubleRegister());
3620 3645
3621 Register input_reg = ToRegister(input); 3646 Register input_reg = ToRegister(input);
3622 XMMRegister result_reg = ToDoubleRegister(result); 3647 XMMRegister result_reg = ToDoubleRegister(result);
3623 3648
3624 EmitNumberUntagD(input_reg, result_reg, instr->environment()); 3649 EmitNumberUntagD(input_reg, result_reg, instr->environment());
3625 } 3650 }
3626 3651
3627 3652
3628 void LCodeGen::DoDoubleToI(LDoubleToI* instr) { 3653 void LCodeGen::DoDoubleToI(LDoubleToI* instr) {
3629 LOperand* input = instr->InputAt(0); 3654 LOperand* input = instr->InputAt(0);
3630 ASSERT(input->IsDoubleRegister()); 3655 ASSERT(input->IsDoubleRegister());
3631 LOperand* result = instr->result(); 3656 LOperand* result = instr->result();
3632 ASSERT(result->IsRegister()); 3657 ASSERT(result->IsRegister());
3633 3658
3634 XMMRegister input_reg = ToDoubleRegister(input); 3659 XMMRegister input_reg = ToDoubleRegister(input);
3635 Register result_reg = ToRegister(result); 3660 Register result_reg = ToRegister(result);
3636 3661
3637 if (instr->truncating()) { 3662 Representation r = instr->hydrogen()->representation();
3663 if (r.IsClampedRoundedInteger8()) {
3664 __ ClampDoubleToUInt8(input_reg, result_reg);
3665 } else if (r.IsTruncatedInteger32()) {
3638 // Performs a truncating conversion of a floating point number as used by 3666 // Performs a truncating conversion of a floating point number as used by
3639 // the JS bitwise operations. 3667 // the JS bitwise operations.
3640 __ cvttsd2si(result_reg, Operand(input_reg)); 3668 __ cvttsd2si(result_reg, Operand(input_reg));
3641 __ cmp(result_reg, 0x80000000u); 3669 __ cmp(result_reg, 0x80000000u);
3642 if (CpuFeatures::IsSupported(SSE3)) { 3670 if (CpuFeatures::IsSupported(SSE3)) {
3643 // This will deoptimize if the exponent of the input in out of range. 3671 // This will deoptimize if the exponent of the input in out of range.
3644 CpuFeatures::Scope scope(SSE3); 3672 CpuFeatures::Scope scope(SSE3);
3645 NearLabel convert, done; 3673 NearLabel convert, done;
3646 __ j(not_equal, &done); 3674 __ j(not_equal, &done);
3647 __ sub(Operand(esp), Immediate(kDoubleSize)); 3675 __ sub(Operand(esp), Immediate(kDoubleSize));
(...skipping 560 matching lines...) Expand 10 before | Expand all | Expand 10 after
4208 ASSERT(osr_pc_offset_ == -1); 4236 ASSERT(osr_pc_offset_ == -1);
4209 osr_pc_offset_ = masm()->pc_offset(); 4237 osr_pc_offset_ = masm()->pc_offset();
4210 } 4238 }
4211 4239
4212 4240
4213 #undef __ 4241 #undef __
4214 4242
4215 } } // namespace v8::internal 4243 } } // namespace v8::internal
4216 4244
4217 #endif // V8_TARGET_ARCH_IA32 4245 #endif // V8_TARGET_ARCH_IA32
OLDNEW
« src/hydrogen.cc ('K') | « src/hydrogen-instructions.cc ('k') | src/ia32/lithium-ia32.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698