| OLD | NEW |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 |
| OLD | NEW |