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 379 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
390 for (int i = 0; i < translation_size; ++i) { | 390 for (int i = 0; i < translation_size; ++i) { |
391 LOperand* value = environment->values()->at(i); | 391 LOperand* value = environment->values()->at(i); |
392 // spilled_registers_ and spilled_double_registers_ are either | 392 // spilled_registers_ and spilled_double_registers_ are either |
393 // both NULL or both set. | 393 // both NULL or both set. |
394 if (environment->spilled_registers() != NULL && value != NULL) { | 394 if (environment->spilled_registers() != NULL && value != NULL) { |
395 if (value->IsRegister() && | 395 if (value->IsRegister() && |
396 environment->spilled_registers()[value->index()] != NULL) { | 396 environment->spilled_registers()[value->index()] != NULL) { |
397 translation->MarkDuplicate(); | 397 translation->MarkDuplicate(); |
398 AddToTranslation(translation, | 398 AddToTranslation(translation, |
399 environment->spilled_registers()[value->index()], | 399 environment->spilled_registers()[value->index()], |
400 environment->HasTaggedValueAt(i)); | 400 environment->HasTaggedValueAt(i), |
| 401 environment->HasUint32ValueAt(i)); |
401 } else if ( | 402 } else if ( |
402 value->IsDoubleRegister() && | 403 value->IsDoubleRegister() && |
403 environment->spilled_double_registers()[value->index()] != NULL) { | 404 environment->spilled_double_registers()[value->index()] != NULL) { |
404 translation->MarkDuplicate(); | 405 translation->MarkDuplicate(); |
405 AddToTranslation( | 406 AddToTranslation( |
406 translation, | 407 translation, |
407 environment->spilled_double_registers()[value->index()], | 408 environment->spilled_double_registers()[value->index()], |
| 409 false, |
408 false); | 410 false); |
409 } | 411 } |
410 } | 412 } |
411 | 413 |
412 AddToTranslation(translation, value, environment->HasTaggedValueAt(i)); | 414 AddToTranslation(translation, |
| 415 value, |
| 416 environment->HasTaggedValueAt(i), |
| 417 environment->HasUint32ValueAt(i)); |
413 } | 418 } |
414 } | 419 } |
415 | 420 |
416 | 421 |
417 void LCodeGen::AddToTranslation(Translation* translation, | 422 void LCodeGen::AddToTranslation(Translation* translation, |
418 LOperand* op, | 423 LOperand* op, |
419 bool is_tagged) { | 424 bool is_tagged, |
| 425 bool is_uint32) { |
420 if (op == NULL) { | 426 if (op == NULL) { |
421 // TODO(twuerthinger): Introduce marker operands to indicate that this value | 427 // TODO(twuerthinger): Introduce marker operands to indicate that this value |
422 // is not present and must be reconstructed from the deoptimizer. Currently | 428 // is not present and must be reconstructed from the deoptimizer. Currently |
423 // this is only used for the arguments object. | 429 // this is only used for the arguments object. |
424 translation->StoreArgumentsObject(); | 430 translation->StoreArgumentsObject(); |
425 } else if (op->IsStackSlot()) { | 431 } else if (op->IsStackSlot()) { |
426 if (is_tagged) { | 432 if (is_tagged) { |
427 translation->StoreStackSlot(op->index()); | 433 translation->StoreStackSlot(op->index()); |
| 434 } else if (is_uint32) { |
| 435 translation->StoreUint32StackSlot(op->index()); |
428 } else { | 436 } else { |
429 translation->StoreInt32StackSlot(op->index()); | 437 translation->StoreInt32StackSlot(op->index()); |
430 } | 438 } |
431 } else if (op->IsDoubleStackSlot()) { | 439 } else if (op->IsDoubleStackSlot()) { |
432 translation->StoreDoubleStackSlot(op->index()); | 440 translation->StoreDoubleStackSlot(op->index()); |
433 } else if (op->IsArgument()) { | 441 } else if (op->IsArgument()) { |
434 ASSERT(is_tagged); | 442 ASSERT(is_tagged); |
435 int src_index = GetStackSlotCount() + op->index(); | 443 int src_index = GetStackSlotCount() + op->index(); |
436 translation->StoreStackSlot(src_index); | 444 translation->StoreStackSlot(src_index); |
437 } else if (op->IsRegister()) { | 445 } else if (op->IsRegister()) { |
438 Register reg = ToRegister(op); | 446 Register reg = ToRegister(op); |
439 if (is_tagged) { | 447 if (is_tagged) { |
440 translation->StoreRegister(reg); | 448 translation->StoreRegister(reg); |
| 449 } else if (is_uint32) { |
| 450 translation->StoreUint32Register(reg); |
441 } else { | 451 } else { |
442 translation->StoreInt32Register(reg); | 452 translation->StoreInt32Register(reg); |
443 } | 453 } |
444 } else if (op->IsDoubleRegister()) { | 454 } else if (op->IsDoubleRegister()) { |
445 XMMRegister reg = ToDoubleRegister(op); | 455 XMMRegister reg = ToDoubleRegister(op); |
446 translation->StoreDoubleRegister(reg); | 456 translation->StoreDoubleRegister(reg); |
447 } else if (op->IsConstantOperand()) { | 457 } else if (op->IsConstantOperand()) { |
448 HConstant* constant = chunk()->LookupConstant(LConstantOperand::cast(op)); | 458 HConstant* constant = chunk()->LookupConstant(LConstantOperand::cast(op)); |
449 int src_index = DefineDeoptimizationLiteral(constant->handle()); | 459 int src_index = DefineDeoptimizationLiteral(constant->handle()); |
450 translation->StoreLiteral(src_index); | 460 translation->StoreLiteral(src_index); |
(...skipping 2264 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2715 __ movsxwq(result, operand); | 2725 __ movsxwq(result, operand); |
2716 break; | 2726 break; |
2717 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS: | 2727 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS: |
2718 __ movzxwq(result, operand); | 2728 __ movzxwq(result, operand); |
2719 break; | 2729 break; |
2720 case EXTERNAL_INT_ELEMENTS: | 2730 case EXTERNAL_INT_ELEMENTS: |
2721 __ movsxlq(result, operand); | 2731 __ movsxlq(result, operand); |
2722 break; | 2732 break; |
2723 case EXTERNAL_UNSIGNED_INT_ELEMENTS: | 2733 case EXTERNAL_UNSIGNED_INT_ELEMENTS: |
2724 __ movl(result, operand); | 2734 __ movl(result, operand); |
2725 __ testl(result, result); | 2735 if (!instr->hydrogen()->CheckFlag(HInstruction::kUint32)) { |
2726 // TODO(danno): we could be more clever here, perhaps having a special | 2736 __ testl(result, result); |
2727 // version of the stub that detects if the overflow case actually | 2737 DeoptimizeIf(negative, instr->environment()); |
2728 // happens, and generate code that returns a double rather than int. | 2738 } |
2729 DeoptimizeIf(negative, instr->environment()); | |
2730 break; | 2739 break; |
2731 case EXTERNAL_FLOAT_ELEMENTS: | 2740 case EXTERNAL_FLOAT_ELEMENTS: |
2732 case EXTERNAL_DOUBLE_ELEMENTS: | 2741 case EXTERNAL_DOUBLE_ELEMENTS: |
2733 case FAST_ELEMENTS: | 2742 case FAST_ELEMENTS: |
2734 case FAST_SMI_ELEMENTS: | 2743 case FAST_SMI_ELEMENTS: |
2735 case FAST_DOUBLE_ELEMENTS: | 2744 case FAST_DOUBLE_ELEMENTS: |
2736 case FAST_HOLEY_ELEMENTS: | 2745 case FAST_HOLEY_ELEMENTS: |
2737 case FAST_HOLEY_SMI_ELEMENTS: | 2746 case FAST_HOLEY_SMI_ELEMENTS: |
2738 case FAST_HOLEY_DOUBLE_ELEMENTS: | 2747 case FAST_HOLEY_DOUBLE_ELEMENTS: |
2739 case DICTIONARY_ELEMENTS: | 2748 case DICTIONARY_ELEMENTS: |
(...skipping 1242 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3982 LOperand* output = instr->result(); | 3991 LOperand* output = instr->result(); |
3983 ASSERT(output->IsDoubleRegister()); | 3992 ASSERT(output->IsDoubleRegister()); |
3984 if (input->IsRegister()) { | 3993 if (input->IsRegister()) { |
3985 __ cvtlsi2sd(ToDoubleRegister(output), ToRegister(input)); | 3994 __ cvtlsi2sd(ToDoubleRegister(output), ToRegister(input)); |
3986 } else { | 3995 } else { |
3987 __ cvtlsi2sd(ToDoubleRegister(output), ToOperand(input)); | 3996 __ cvtlsi2sd(ToDoubleRegister(output), ToOperand(input)); |
3988 } | 3997 } |
3989 } | 3998 } |
3990 | 3999 |
3991 | 4000 |
| 4001 void LCodeGen::DoUint32ToDouble(LUint32ToDouble* instr) { |
| 4002 LOperand* input = instr->InputAt(0); |
| 4003 LOperand* output = instr->result(); |
| 4004 LOperand* temp = instr->TempAt(0); |
| 4005 |
| 4006 __ LoadUint32(ToDoubleRegister(output), |
| 4007 ToRegister(input), |
| 4008 ToDoubleRegister(temp)); |
| 4009 } |
| 4010 |
| 4011 |
3992 void LCodeGen::DoNumberTagI(LNumberTagI* instr) { | 4012 void LCodeGen::DoNumberTagI(LNumberTagI* instr) { |
3993 LOperand* input = instr->InputAt(0); | 4013 LOperand* input = instr->InputAt(0); |
3994 ASSERT(input->IsRegister() && input->Equals(instr->result())); | 4014 ASSERT(input->IsRegister() && input->Equals(instr->result())); |
3995 Register reg = ToRegister(input); | 4015 Register reg = ToRegister(input); |
3996 | 4016 |
3997 __ Integer32ToSmi(reg, reg); | 4017 __ Integer32ToSmi(reg, reg); |
3998 } | 4018 } |
3999 | 4019 |
4000 | 4020 |
| 4021 void LCodeGen::DoNumberTagU(LNumberTagU* instr) { |
| 4022 class DeferredNumberTagU: public LDeferredCode { |
| 4023 public: |
| 4024 DeferredNumberTagU(LCodeGen* codegen, LNumberTagU* instr) |
| 4025 : LDeferredCode(codegen), instr_(instr) { } |
| 4026 virtual void Generate() { |
| 4027 codegen()->DoDeferredNumberTagU(instr_); |
| 4028 } |
| 4029 virtual LInstruction* instr() { return instr_; } |
| 4030 private: |
| 4031 LNumberTagU* instr_; |
| 4032 }; |
| 4033 |
| 4034 LOperand* input = instr->InputAt(0); |
| 4035 ASSERT(input->IsRegister() && input->Equals(instr->result())); |
| 4036 Register reg = ToRegister(input); |
| 4037 |
| 4038 DeferredNumberTagU* deferred = new(zone()) DeferredNumberTagU(this, instr); |
| 4039 __ cmpl(reg, Immediate(Smi::kMaxValue)); |
| 4040 __ j(above, deferred->entry()); |
| 4041 __ Integer32ToSmi(reg, reg); |
| 4042 __ bind(deferred->exit()); |
| 4043 } |
| 4044 |
| 4045 |
| 4046 void LCodeGen::DoDeferredNumberTagU(LNumberTagU* instr) { |
| 4047 Label slow; |
| 4048 Register reg = ToRegister(instr->InputAt(0)); |
| 4049 Register tmp = reg.is(rax) ? rcx : rax; |
| 4050 |
| 4051 // Preserve the value of all registers. |
| 4052 PushSafepointRegistersScope scope(this); |
| 4053 |
| 4054 Label done; |
| 4055 __ LoadUint32(xmm0, reg, xmm1); |
| 4056 |
| 4057 if (FLAG_inline_new) { |
| 4058 __ AllocateHeapNumber(reg, tmp, &slow); |
| 4059 __ jmp(&done, Label::kNear); |
| 4060 } |
| 4061 |
| 4062 // Slow case: Call the runtime system to do the number allocation. |
| 4063 __ bind(&slow); |
| 4064 |
| 4065 // Put a valid pointer value in the stack slot where the result |
| 4066 // register is stored, as this register is in the pointer map, but contains an |
| 4067 // integer value. |
| 4068 __ StoreToSafepointRegisterSlot(reg, Immediate(0)); |
| 4069 |
| 4070 CallRuntimeFromDeferred(Runtime::kAllocateHeapNumber, 0, instr); |
| 4071 if (!reg.is(rax)) __ movq(reg, rax); |
| 4072 |
| 4073 // Done. Put the value in xmm0 into the value of the allocated heap |
| 4074 // number. |
| 4075 __ bind(&done); |
| 4076 __ movsd(FieldOperand(reg, HeapNumber::kValueOffset), xmm0); |
| 4077 __ StoreToSafepointRegisterSlot(reg, reg); |
| 4078 } |
| 4079 |
| 4080 |
4001 void LCodeGen::DoNumberTagD(LNumberTagD* instr) { | 4081 void LCodeGen::DoNumberTagD(LNumberTagD* instr) { |
4002 class DeferredNumberTagD: public LDeferredCode { | 4082 class DeferredNumberTagD: public LDeferredCode { |
4003 public: | 4083 public: |
4004 DeferredNumberTagD(LCodeGen* codegen, LNumberTagD* instr) | 4084 DeferredNumberTagD(LCodeGen* codegen, LNumberTagD* instr) |
4005 : LDeferredCode(codegen), instr_(instr) { } | 4085 : LDeferredCode(codegen), instr_(instr) { } |
4006 virtual void Generate() { codegen()->DoDeferredNumberTagD(instr_); } | 4086 virtual void Generate() { codegen()->DoDeferredNumberTagD(instr_); } |
4007 virtual LInstruction* instr() { return instr_; } | 4087 virtual LInstruction* instr() { return instr_; } |
4008 private: | 4088 private: |
4009 LNumberTagD* instr_; | 4089 LNumberTagD* instr_; |
4010 }; | 4090 }; |
(...skipping 1151 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5162 FixedArray::kHeaderSize - kPointerSize)); | 5242 FixedArray::kHeaderSize - kPointerSize)); |
5163 __ bind(&done); | 5243 __ bind(&done); |
5164 } | 5244 } |
5165 | 5245 |
5166 | 5246 |
5167 #undef __ | 5247 #undef __ |
5168 | 5248 |
5169 } } // namespace v8::internal | 5249 } } // namespace v8::internal |
5170 | 5250 |
5171 #endif // V8_TARGET_ARCH_X64 | 5251 #endif // V8_TARGET_ARCH_X64 |
OLD | NEW |