| OLD | NEW |
| 1 // Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_IA32. | 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_IA32. |
| 6 #if defined(TARGET_ARCH_IA32) | 6 #if defined(TARGET_ARCH_IA32) |
| 7 | 7 |
| 8 #include "vm/opt_code_generator.h" | 8 #include "vm/opt_code_generator.h" |
| 9 | 9 |
| 10 #include "vm/assembler_macros.h" | 10 #include "vm/assembler_macros.h" |
| (...skipping 841 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 852 deopt_blob->label()); | 852 deopt_blob->label()); |
| 853 PropagateBackLocalClass(node->operand(), double_class_); | 853 PropagateBackLocalClass(node->operand(), double_class_); |
| 854 } | 854 } |
| 855 const bool using_temp = | 855 const bool using_temp = |
| 856 (node->info() != NULL) && node->info()->allow_temp(); | 856 (node->info() != NULL) && node->info()->allow_temp(); |
| 857 if (!using_temp) { | 857 if (!using_temp) { |
| 858 const Code& stub = | 858 const Code& stub = |
| 859 Code::Handle(StubCode::GetAllocationStubForClass(double_class_)); | 859 Code::Handle(StubCode::GetAllocationStubForClass(double_class_)); |
| 860 const ExternalLabel label(double_class_.ToCString(), stub.EntryPoint()); | 860 const ExternalLabel label(double_class_.ToCString(), stub.EntryPoint()); |
| 861 __ pushl(kOperandRegister); | 861 __ pushl(kOperandRegister); |
| 862 GenerateCall(node->token_index(), &label); | 862 GenerateCall(node->token_index(), &label, PcDescriptors::kOther); |
| 863 ASSERT(kResultRegister == EAX); | 863 ASSERT(kResultRegister == EAX); |
| 864 __ popl(kOperandRegister); | 864 __ popl(kOperandRegister); |
| 865 } else if (info.is_temp()) { | 865 } else if (info.is_temp()) { |
| 866 __ movl(kResultRegister, kOperandRegister); | 866 __ movl(kResultRegister, kOperandRegister); |
| 867 } else { | 867 } else { |
| 868 const Double& double_object = | 868 const Double& double_object = |
| 869 Double::ZoneHandle(Double::New(0.0, Heap::kOld)); | 869 Double::ZoneHandle(Double::New(0.0, Heap::kOld)); |
| 870 __ LoadObject(kResultRegister, double_object); | 870 __ LoadObject(kResultRegister, double_object); |
| 871 } | 871 } |
| 872 __ movsd(XMM0, FieldAddress(kOperandRegister, Double::value_offset())); | 872 __ movsd(XMM0, FieldAddress(kOperandRegister, Double::value_offset())); |
| (...skipping 269 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1142 (node->info() != NULL) && node->info()->allow_temp(); | 1142 (node->info() != NULL) && node->info()->allow_temp(); |
| 1143 if (!using_temp) { | 1143 if (!using_temp) { |
| 1144 // Parent node cannot handle a temporary double object, allocate one | 1144 // Parent node cannot handle a temporary double object, allocate one |
| 1145 // each time. | 1145 // each time. |
| 1146 result_register = kAllocatedRegister; | 1146 result_register = kAllocatedRegister; |
| 1147 const Code& stub = | 1147 const Code& stub = |
| 1148 Code::Handle(StubCode::GetAllocationStubForClass(double_class_)); | 1148 Code::Handle(StubCode::GetAllocationStubForClass(double_class_)); |
| 1149 const ExternalLabel label(double_class_.ToCString(), stub.EntryPoint()); | 1149 const ExternalLabel label(double_class_.ToCString(), stub.EntryPoint()); |
| 1150 __ pushl(kLeftRegister); | 1150 __ pushl(kLeftRegister); |
| 1151 __ pushl(kRightRegister); | 1151 __ pushl(kRightRegister); |
| 1152 GenerateCall(node->token_index(), &label); | 1152 GenerateCall(node->token_index(), &label, PcDescriptors::kOther); |
| 1153 __ movl(result_register, EAX); | 1153 __ movl(result_register, EAX); |
| 1154 __ popl(kRightRegister); | 1154 __ popl(kRightRegister); |
| 1155 __ popl(kLeftRegister); | 1155 __ popl(kLeftRegister); |
| 1156 } else if (left_info.IsClass(double_class_) && left_info.is_temp()) { | 1156 } else if (left_info.IsClass(double_class_) && left_info.is_temp()) { |
| 1157 result_register = kLeftRegister; | 1157 result_register = kLeftRegister; |
| 1158 } else if (right_info.IsClass(double_class_) && right_info.is_temp()) { | 1158 } else if (right_info.IsClass(double_class_) && right_info.is_temp()) { |
| 1159 result_register = kRightRegister; | 1159 result_register = kRightRegister; |
| 1160 } else { | 1160 } else { |
| 1161 result_register = kAllocatedRegister; | 1161 result_register = kAllocatedRegister; |
| 1162 // Use inlined temporary double object. | 1162 // Use inlined temporary double object. |
| (...skipping 1802 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2965 target.ToFullyQualifiedCString(), | 2965 target.ToFullyQualifiedCString(), |
| 2966 Recognizer::KindToCString(recognized)); | 2966 Recognizer::KindToCString(recognized)); |
| 2967 } | 2967 } |
| 2968 if ((recognized == Recognizer::kIntegerToDouble) && | 2968 if ((recognized == Recognizer::kIntegerToDouble) && |
| 2969 AtIdNodeHasClassAt(node, node->id(), smi_class_, 0)) { | 2969 AtIdNodeHasClassAt(node, node->id(), smi_class_, 0)) { |
| 2970 // TODO(srdjan): Check if we could use temporary double instead of | 2970 // TODO(srdjan): Check if we could use temporary double instead of |
| 2971 // allocating a new object every time. | 2971 // allocating a new object every time. |
| 2972 const Code& stub = | 2972 const Code& stub = |
| 2973 Code::Handle(StubCode::GetAllocationStubForClass(double_class_)); | 2973 Code::Handle(StubCode::GetAllocationStubForClass(double_class_)); |
| 2974 const ExternalLabel label(double_class_.ToCString(), stub.EntryPoint()); | 2974 const ExternalLabel label(double_class_.ToCString(), stub.EntryPoint()); |
| 2975 GenerateCall(node->token_index(), &label); | 2975 GenerateCall(node->token_index(), &label, PcDescriptors::kOther); |
| 2976 // EAX is double object. | 2976 // EAX is double object. |
| 2977 DeoptimizationBlob* deopt_blob = | 2977 DeoptimizationBlob* deopt_blob = |
| 2978 AddDeoptimizationBlob(node, EBX, kDeoptIntegerToDouble); | 2978 AddDeoptimizationBlob(node, EBX, kDeoptIntegerToDouble); |
| 2979 __ popl(EBX); // Receiver | 2979 __ popl(EBX); // Receiver |
| 2980 __ testl(EBX, Immediate(kSmiTagMask)); | 2980 __ testl(EBX, Immediate(kSmiTagMask)); |
| 2981 __ j(NOT_ZERO, deopt_blob->label()); // Deoptimize if not Smi. | 2981 __ j(NOT_ZERO, deopt_blob->label()); // Deoptimize if not Smi. |
| 2982 __ SmiUntag(EBX); | 2982 __ SmiUntag(EBX); |
| 2983 __ cvtsi2sd(XMM0, EBX); | 2983 __ cvtsi2sd(XMM0, EBX); |
| 2984 __ movsd(FieldAddress(EAX, Double::value_offset()), XMM0); | 2984 __ movsd(FieldAddress(EAX, Double::value_offset()), XMM0); |
| 2985 return true; | 2985 return true; |
| (...skipping 27 matching lines...) Expand all Loading... |
| 3013 EBX, // Class register. | 3013 EBX, // Class register. |
| 3014 &call_method, | 3014 &call_method, |
| 3015 EAX); // Result register. | 3015 EAX); // Result register. |
| 3016 __ movsd(FieldAddress(EAX, Double::value_offset()), XMM0); | 3016 __ movsd(FieldAddress(EAX, Double::value_offset()), XMM0); |
| 3017 __ jmp(&done); | 3017 __ jmp(&done); |
| 3018 __ Bind(&smi_to_double); | 3018 __ Bind(&smi_to_double); |
| 3019 __ Bind(&call_method); | 3019 __ Bind(&call_method); |
| 3020 __ LoadObject(ECX, node->function()); | 3020 __ LoadObject(ECX, node->function()); |
| 3021 __ LoadObject(EDX, ArgumentsDescriptor(node->arguments()->length(), | 3021 __ LoadObject(EDX, ArgumentsDescriptor(node->arguments()->length(), |
| 3022 node->arguments()->names())); | 3022 node->arguments()->names())); |
| 3023 GenerateCall(node->token_index(), &StubCode::CallStaticFunctionLabel()); | 3023 GenerateCall(node->token_index(), &StubCode::CallStaticFunctionLabel(), |
| 3024 PcDescriptors::kFuncCall); |
| 3024 __ Bind(&done); | 3025 __ Bind(&done); |
| 3025 return true; | 3026 return true; |
| 3026 } | 3027 } |
| 3027 return false; | 3028 return false; |
| 3028 } | 3029 } |
| 3029 | 3030 |
| 3030 | 3031 |
| 3031 void OptimizingCodeGenerator::VisitStaticCallNode(StaticCallNode* node) { | 3032 void OptimizingCodeGenerator::VisitStaticCallNode(StaticCallNode* node) { |
| 3032 node->arguments()->Visit(this); | 3033 node->arguments()->Visit(this); |
| 3033 if (TryInlineStaticCall(node)) { | 3034 if (TryInlineStaticCall(node)) { |
| 3034 // Static method is inlined, result is in EAX. | 3035 // Static method is inlined, result is in EAX. |
| 3035 } else { | 3036 } else { |
| 3036 __ LoadObject(ECX, node->function()); | 3037 __ LoadObject(ECX, node->function()); |
| 3037 __ LoadObject(EDX, ArgumentsDescriptor(node->arguments()->length(), | 3038 __ LoadObject(EDX, ArgumentsDescriptor(node->arguments()->length(), |
| 3038 node->arguments()->names())); | 3039 node->arguments()->names())); |
| 3039 GenerateCall(node->token_index(), &StubCode::CallStaticFunctionLabel()); | 3040 GenerateCall(node->token_index(), &StubCode::CallStaticFunctionLabel(), |
| 3041 PcDescriptors::kFuncCall); |
| 3040 } | 3042 } |
| 3041 __ addl(ESP, Immediate(node->arguments()->length() * kWordSize)); | 3043 __ addl(ESP, Immediate(node->arguments()->length() * kWordSize)); |
| 3042 // Result is in EAX. | 3044 // Result is in EAX. |
| 3043 HandleResult(node, EAX); | 3045 HandleResult(node, EAX); |
| 3044 } | 3046 } |
| 3045 | 3047 |
| 3046 | 3048 |
| 3047 void OptimizingCodeGenerator::VisitReturnNode(ReturnNode* node) { | 3049 void OptimizingCodeGenerator::VisitReturnNode(ReturnNode* node) { |
| 3048 if ((node->inlined_finally_list_length() > 0) || FLAG_enable_type_checks) { | 3050 if ((node->inlined_finally_list_length() > 0) || FLAG_enable_type_checks) { |
| 3049 CodeGenerator::VisitReturnNode(node); | 3051 CodeGenerator::VisitReturnNode(node); |
| (...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3146 } | 3148 } |
| 3147 } | 3149 } |
| 3148 // TODO(srdjan): Implement unary kSUB (negate) Mint. | 3150 // TODO(srdjan): Implement unary kSUB (negate) Mint. |
| 3149 CodeGenerator::VisitUnaryOpNode(node); | 3151 CodeGenerator::VisitUnaryOpNode(node); |
| 3150 } | 3152 } |
| 3151 | 3153 |
| 3152 | 3154 |
| 3153 } // namespace dart | 3155 } // namespace dart |
| 3154 | 3156 |
| 3155 #endif // defined TARGET_ARCH_IA32 | 3157 #endif // defined TARGET_ARCH_IA32 |
| OLD | NEW |