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 |