OLD | NEW |
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, 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_X64. | 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_X64. |
6 #if defined(TARGET_ARCH_X64) | 6 #if defined(TARGET_ARCH_X64) |
7 | 7 |
8 #include "vm/flow_graph_compiler.h" | 8 #include "vm/flow_graph_compiler.h" |
9 | 9 |
10 #include "lib/error.h" | 10 #include "lib/error.h" |
(...skipping 246 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
257 const Register kClassIdReg = R10; | 257 const Register kClassIdReg = R10; |
258 __ LoadClassId(kClassIdReg, kInstanceReg); | 258 __ LoadClassId(kClassIdReg, kInstanceReg); |
259 // If type is an interface, we can skip the class equality check. | 259 // If type is an interface, we can skip the class equality check. |
260 if (!type_class.is_interface()) { | 260 if (!type_class.is_interface()) { |
261 __ cmpl(kClassIdReg, Immediate(type_class.id())); | 261 __ cmpl(kClassIdReg, Immediate(type_class.id())); |
262 __ j(EQUAL, is_instance_lbl); | 262 __ j(EQUAL, is_instance_lbl); |
263 } | 263 } |
264 // Bool interface can be implemented only by core class Bool. | 264 // Bool interface can be implemented only by core class Bool. |
265 // (see ClassFinalizer::ResolveInterfaces for list of restricted interfaces). | 265 // (see ClassFinalizer::ResolveInterfaces for list of restricted interfaces). |
266 if (type.IsBoolInterface()) { | 266 if (type.IsBoolInterface()) { |
267 __ cmpl(kClassIdReg, Immediate(kBool)); | 267 __ cmpl(kClassIdReg, Immediate(kBoolCid)); |
268 __ j(EQUAL, is_instance_lbl); | 268 __ j(EQUAL, is_instance_lbl); |
269 __ jmp(is_not_instance_lbl); | 269 __ jmp(is_not_instance_lbl); |
270 return false; | 270 return false; |
271 } | 271 } |
272 if (type.IsFunctionInterface()) { | 272 if (type.IsFunctionInterface()) { |
273 // Check if instance is a closure. | 273 // Check if instance is a closure. |
274 const Immediate raw_null = | 274 const Immediate raw_null = |
275 Immediate(reinterpret_cast<intptr_t>(Object::null())); | 275 Immediate(reinterpret_cast<intptr_t>(Object::null())); |
276 __ LoadClassById(R13, kClassIdReg); | 276 __ LoadClassById(R13, kClassIdReg); |
277 __ movq(R13, FieldAddress(R13, Class::signature_function_offset())); | 277 __ movq(R13, FieldAddress(R13, Class::signature_function_offset())); |
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
344 const TypeParameter& type_param = TypeParameter::Cast(type); | 344 const TypeParameter& type_param = TypeParameter::Cast(type); |
345 // Load instantiator (or null) and instantiator type arguments on stack. | 345 // Load instantiator (or null) and instantiator type arguments on stack. |
346 __ movq(RDX, Address(RSP, 0)); // Get instantiator type arguments. | 346 __ movq(RDX, Address(RSP, 0)); // Get instantiator type arguments. |
347 // RDX: instantiator type arguments. | 347 // RDX: instantiator type arguments. |
348 // Check if type argument is Dynamic. | 348 // Check if type argument is Dynamic. |
349 __ cmpq(RDX, raw_null); | 349 __ cmpq(RDX, raw_null); |
350 __ j(EQUAL, is_instance_lbl); | 350 __ j(EQUAL, is_instance_lbl); |
351 // Can handle only type arguments that are instances of TypeArguments. | 351 // Can handle only type arguments that are instances of TypeArguments. |
352 // (runtime checks canonicalize type arguments). | 352 // (runtime checks canonicalize type arguments). |
353 Label fall_through; | 353 Label fall_through; |
354 __ CompareClassId(RDX, kTypeArguments); | 354 __ CompareClassId(RDX, kTypeArgumentsCid); |
355 __ j(NOT_EQUAL, &fall_through); | 355 __ j(NOT_EQUAL, &fall_through); |
356 __ movq(RDI, | 356 __ movq(RDI, |
357 FieldAddress(RDX, TypeArguments::type_at_offset(type_param.index()))); | 357 FieldAddress(RDX, TypeArguments::type_at_offset(type_param.index()))); |
358 // RDI: Concrete type of type. | 358 // RDI: Concrete type of type. |
359 // Check if type argument is dynamic. | 359 // Check if type argument is dynamic. |
360 __ CompareObject(RDI, Type::ZoneHandle(Type::DynamicType())); | 360 __ CompareObject(RDI, Type::ZoneHandle(Type::DynamicType())); |
361 __ j(EQUAL, is_instance_lbl); | 361 __ j(EQUAL, is_instance_lbl); |
362 __ cmpq(RDI, raw_null); | 362 __ cmpq(RDI, raw_null); |
363 __ j(EQUAL, is_instance_lbl); | 363 __ j(EQUAL, is_instance_lbl); |
364 const Type& object_type = Type::ZoneHandle(Type::ObjectType()); | 364 const Type& object_type = Type::ZoneHandle(Type::ObjectType()); |
(...skipping 518 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
883 __ movq(RAX, raw_null); | 883 __ movq(RAX, raw_null); |
884 __ ret(); | 884 __ ret(); |
885 } | 885 } |
886 | 886 |
887 | 887 |
888 void FlowGraphCompiler::GenerateInlinedMathSqrt(Label* done) { | 888 void FlowGraphCompiler::GenerateInlinedMathSqrt(Label* done) { |
889 Label smi_to_double, double_op, call_method; | 889 Label smi_to_double, double_op, call_method; |
890 __ movq(RAX, Address(RSP, 0)); | 890 __ movq(RAX, Address(RSP, 0)); |
891 __ testq(RAX, Immediate(kSmiTagMask)); | 891 __ testq(RAX, Immediate(kSmiTagMask)); |
892 __ j(ZERO, &smi_to_double); | 892 __ j(ZERO, &smi_to_double); |
893 __ CompareClassId(RAX, kDouble); | 893 __ CompareClassId(RAX, kDoubleCid); |
894 __ j(NOT_EQUAL, &call_method); | 894 __ j(NOT_EQUAL, &call_method); |
895 __ movsd(XMM1, FieldAddress(RAX, Double::value_offset())); | 895 __ movsd(XMM1, FieldAddress(RAX, Double::value_offset())); |
896 __ Bind(&double_op); | 896 __ Bind(&double_op); |
897 __ sqrtsd(XMM0, XMM1); | 897 __ sqrtsd(XMM0, XMM1); |
898 AssemblerMacros::TryAllocate(assembler_, | 898 AssemblerMacros::TryAllocate(assembler_, |
899 double_class_, | 899 double_class_, |
900 &call_method, | 900 &call_method, |
901 RAX); // Result register. | 901 RAX); // Result register. |
902 __ movsd(FieldAddress(RAX, Double::value_offset()), XMM0); | 902 __ movsd(FieldAddress(RAX, Double::value_offset()), XMM0); |
903 __ Drop(1); | 903 __ Drop(1); |
(...skipping 156 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1060 } | 1060 } |
1061 | 1061 |
1062 | 1062 |
1063 // Checks class id of instance against all 'class_ids'. Jump to 'deopt' label | 1063 // Checks class id of instance against all 'class_ids'. Jump to 'deopt' label |
1064 // if no match or instance is Smi. | 1064 // if no match or instance is Smi. |
1065 void FlowGraphCompiler::EmitClassChecksNoSmi(const ICData& ic_data, | 1065 void FlowGraphCompiler::EmitClassChecksNoSmi(const ICData& ic_data, |
1066 Register instance_reg, | 1066 Register instance_reg, |
1067 Register temp_reg, | 1067 Register temp_reg, |
1068 Label* deopt) { | 1068 Label* deopt) { |
1069 Label ok; | 1069 Label ok; |
1070 ASSERT(ic_data.GetReceiverClassIdAt(0) != kSmi); | 1070 ASSERT(ic_data.GetReceiverClassIdAt(0) != kSmiCid); |
1071 __ testq(instance_reg, Immediate(kSmiTagMask)); | 1071 __ testq(instance_reg, Immediate(kSmiTagMask)); |
1072 __ j(ZERO, deopt); | 1072 __ j(ZERO, deopt); |
1073 Label is_ok; | 1073 Label is_ok; |
1074 const intptr_t num_checks = ic_data.NumberOfChecks(); | 1074 const intptr_t num_checks = ic_data.NumberOfChecks(); |
1075 const bool use_near_jump = num_checks < 5; | 1075 const bool use_near_jump = num_checks < 5; |
1076 __ LoadClassId(temp_reg, instance_reg); | 1076 __ LoadClassId(temp_reg, instance_reg); |
1077 for (intptr_t i = 0; i < num_checks; i++) { | 1077 for (intptr_t i = 0; i < num_checks; i++) { |
1078 __ cmpl(temp_reg, Immediate(ic_data.GetReceiverClassIdAt(i))); | 1078 __ cmpl(temp_reg, Immediate(ic_data.GetReceiverClassIdAt(i))); |
1079 if (i == (num_checks - 1)) { | 1079 if (i == (num_checks - 1)) { |
1080 __ j(NOT_EQUAL, deopt); | 1080 __ j(NOT_EQUAL, deopt); |
1081 } else { | 1081 } else { |
1082 if (use_near_jump) { | 1082 if (use_near_jump) { |
1083 __ j(EQUAL, &is_ok, Assembler::kNearJump); | 1083 __ j(EQUAL, &is_ok, Assembler::kNearJump); |
1084 } else { | 1084 } else { |
1085 __ j(EQUAL, &is_ok); | 1085 __ j(EQUAL, &is_ok); |
1086 } | 1086 } |
1087 } | 1087 } |
1088 } | 1088 } |
1089 __ Bind(&is_ok); | 1089 __ Bind(&is_ok); |
1090 } | 1090 } |
1091 | 1091 |
1092 | 1092 |
1093 void FlowGraphCompiler::LoadDoubleOrSmiToXmm(XmmRegister result, | 1093 void FlowGraphCompiler::LoadDoubleOrSmiToXmm(XmmRegister result, |
1094 Register reg, | 1094 Register reg, |
1095 Register temp, | 1095 Register temp, |
1096 Label* not_double_or_smi) { | 1096 Label* not_double_or_smi) { |
1097 Label is_smi, done; | 1097 Label is_smi, done; |
1098 __ testq(reg, Immediate(kSmiTagMask)); | 1098 __ testq(reg, Immediate(kSmiTagMask)); |
1099 __ j(ZERO, &is_smi); | 1099 __ j(ZERO, &is_smi); |
1100 __ CompareClassId(reg, kDouble); | 1100 __ CompareClassId(reg, kDoubleCid); |
1101 __ j(NOT_EQUAL, not_double_or_smi); | 1101 __ j(NOT_EQUAL, not_double_or_smi); |
1102 __ movsd(result, FieldAddress(reg, Double::value_offset())); | 1102 __ movsd(result, FieldAddress(reg, Double::value_offset())); |
1103 __ jmp(&done); | 1103 __ jmp(&done); |
1104 __ Bind(&is_smi); | 1104 __ Bind(&is_smi); |
1105 __ movq(temp, reg); | 1105 __ movq(temp, reg); |
1106 __ SmiUntag(temp); | 1106 __ SmiUntag(temp); |
1107 __ cvtsi2sd(result, temp); | 1107 __ cvtsi2sd(result, temp); |
1108 __ Bind(&done); | 1108 __ Bind(&done); |
1109 } | 1109 } |
1110 | 1110 |
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1215 void ParallelMoveResolver::Exchange(const Address& mem1, const Address& mem2) { | 1215 void ParallelMoveResolver::Exchange(const Address& mem1, const Address& mem2) { |
1216 __ Exchange(mem1, mem2); | 1216 __ Exchange(mem1, mem2); |
1217 } | 1217 } |
1218 | 1218 |
1219 | 1219 |
1220 #undef __ | 1220 #undef __ |
1221 | 1221 |
1222 } // namespace dart | 1222 } // namespace dart |
1223 | 1223 |
1224 #endif // defined TARGET_ARCH_X64 | 1224 #endif // defined TARGET_ARCH_X64 |
OLD | NEW |