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/intrinsifier.h" | 8 #include "vm/intrinsifier.h" |
9 | 9 |
10 #include "vm/assembler.h" | 10 #include "vm/assembler.h" |
(...skipping 936 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
947 case Token::kSUB: __ subsd(XMM0, XMM1); break; | 947 case Token::kSUB: __ subsd(XMM0, XMM1); break; |
948 case Token::kMUL: __ mulsd(XMM0, XMM1); break; | 948 case Token::kMUL: __ mulsd(XMM0, XMM1); break; |
949 case Token::kDIV: __ divsd(XMM0, XMM1); break; | 949 case Token::kDIV: __ divsd(XMM0, XMM1); break; |
950 default: UNREACHABLE(); | 950 default: UNREACHABLE(); |
951 } | 951 } |
952 const Class& double_class = Class::Handle( | 952 const Class& double_class = Class::Handle( |
953 Isolate::Current()->object_store()->double_class()); | 953 Isolate::Current()->object_store()->double_class()); |
954 AssemblerMacros::TryAllocate(assembler, | 954 AssemblerMacros::TryAllocate(assembler, |
955 double_class, | 955 double_class, |
956 &fall_through, | 956 &fall_through, |
| 957 Assembler::kNearJump, |
957 RAX); // Result register. | 958 RAX); // Result register. |
958 __ movsd(FieldAddress(RAX, Double::value_offset()), XMM0); | 959 __ movsd(FieldAddress(RAX, Double::value_offset()), XMM0); |
959 __ ret(); | 960 __ ret(); |
960 __ Bind(&fall_through); | 961 __ Bind(&fall_through); |
961 return false; | 962 return false; |
962 } | 963 } |
963 | 964 |
964 | 965 |
965 bool Intrinsifier::Double_add(Assembler* assembler) { | 966 bool Intrinsifier::Double_add(Assembler* assembler) { |
966 return DoubleArithmeticOperations(assembler, Token::kADD); | 967 return DoubleArithmeticOperations(assembler, Token::kADD); |
(...skipping 25 matching lines...) Expand all Loading... |
992 __ SmiUntag(RAX); | 993 __ SmiUntag(RAX); |
993 __ cvtsi2sd(XMM1, RAX); | 994 __ cvtsi2sd(XMM1, RAX); |
994 __ movq(RAX, Address(RSP, + 2 * kWordSize)); | 995 __ movq(RAX, Address(RSP, + 2 * kWordSize)); |
995 __ movsd(XMM0, FieldAddress(RAX, Double::value_offset())); | 996 __ movsd(XMM0, FieldAddress(RAX, Double::value_offset())); |
996 __ mulsd(XMM0, XMM1); | 997 __ mulsd(XMM0, XMM1); |
997 const Class& double_class = Class::Handle( | 998 const Class& double_class = Class::Handle( |
998 Isolate::Current()->object_store()->double_class()); | 999 Isolate::Current()->object_store()->double_class()); |
999 AssemblerMacros::TryAllocate(assembler, | 1000 AssemblerMacros::TryAllocate(assembler, |
1000 double_class, | 1001 double_class, |
1001 &fall_through, | 1002 &fall_through, |
| 1003 Assembler::kNearJump, |
1002 RAX); // Result register. | 1004 RAX); // Result register. |
1003 __ movsd(FieldAddress(RAX, Double::value_offset()), XMM0); | 1005 __ movsd(FieldAddress(RAX, Double::value_offset()), XMM0); |
1004 __ ret(); | 1006 __ ret(); |
1005 __ Bind(&fall_through); | 1007 __ Bind(&fall_through); |
1006 return false; | 1008 return false; |
1007 } | 1009 } |
1008 | 1010 |
1009 | 1011 |
1010 // Left is double right is integer (Bigint, Mint or Smi) | 1012 // Left is double right is integer (Bigint, Mint or Smi) |
1011 bool Intrinsifier::Double_fromInteger(Assembler* assembler) { | 1013 bool Intrinsifier::Double_fromInteger(Assembler* assembler) { |
1012 Label fall_through; | 1014 Label fall_through; |
1013 __ movq(RAX, Address(RSP, +1 * kWordSize)); | 1015 __ movq(RAX, Address(RSP, +1 * kWordSize)); |
1014 __ testq(RAX, Immediate(kSmiTagMask)); | 1016 __ testq(RAX, Immediate(kSmiTagMask)); |
1015 __ j(NOT_ZERO, &fall_through, Assembler::kNearJump); | 1017 __ j(NOT_ZERO, &fall_through, Assembler::kNearJump); |
1016 // Is Smi. | 1018 // Is Smi. |
1017 __ SmiUntag(RAX); | 1019 __ SmiUntag(RAX); |
1018 __ cvtsi2sd(XMM0, RAX); | 1020 __ cvtsi2sd(XMM0, RAX); |
1019 const Class& double_class = Class::Handle( | 1021 const Class& double_class = Class::Handle( |
1020 Isolate::Current()->object_store()->double_class()); | 1022 Isolate::Current()->object_store()->double_class()); |
1021 AssemblerMacros::TryAllocate(assembler, | 1023 AssemblerMacros::TryAllocate(assembler, |
1022 double_class, | 1024 double_class, |
1023 &fall_through, | 1025 &fall_through, |
| 1026 Assembler::kNearJump, |
1024 RAX); // Result register. | 1027 RAX); // Result register. |
1025 __ movsd(FieldAddress(RAX, Double::value_offset()), XMM0); | 1028 __ movsd(FieldAddress(RAX, Double::value_offset()), XMM0); |
1026 __ ret(); | 1029 __ ret(); |
1027 __ Bind(&fall_through); | 1030 __ Bind(&fall_through); |
1028 return false; | 1031 return false; |
1029 } | 1032 } |
1030 | 1033 |
1031 | 1034 |
1032 bool Intrinsifier::Double_isNaN(Assembler* assembler) { | 1035 bool Intrinsifier::Double_isNaN(Assembler* assembler) { |
1033 const Bool& bool_true = Bool::ZoneHandle(Bool::True()); | 1036 const Bool& bool_true = Bool::ZoneHandle(Bool::True()); |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1091 case kCosine: __ fcos(); break; | 1094 case kCosine: __ fcos(); break; |
1092 default: | 1095 default: |
1093 UNREACHABLE(); | 1096 UNREACHABLE(); |
1094 } | 1097 } |
1095 const Class& double_class = Class::Handle( | 1098 const Class& double_class = Class::Handle( |
1096 Isolate::Current()->object_store()->double_class()); | 1099 Isolate::Current()->object_store()->double_class()); |
1097 Label alloc_failed; | 1100 Label alloc_failed; |
1098 AssemblerMacros::TryAllocate(assembler, | 1101 AssemblerMacros::TryAllocate(assembler, |
1099 double_class, | 1102 double_class, |
1100 &alloc_failed, | 1103 &alloc_failed, |
| 1104 Assembler::kNearJump, |
1101 RAX); // Result register. | 1105 RAX); // Result register. |
1102 __ fstpl(FieldAddress(RAX, Double::value_offset())); | 1106 __ fstpl(FieldAddress(RAX, Double::value_offset())); |
1103 __ ret(); | 1107 __ ret(); |
1104 | 1108 |
1105 __ Bind(&is_smi); // smi -> double. | 1109 __ Bind(&is_smi); // smi -> double. |
1106 __ SmiUntag(RAX); | 1110 __ SmiUntag(RAX); |
1107 __ pushq(RAX); | 1111 __ pushq(RAX); |
1108 __ fildl(Address(RSP, 0)); | 1112 __ fildl(Address(RSP, 0)); |
1109 __ popq(RAX); | 1113 __ popq(RAX); |
1110 __ jmp(&double_op); | 1114 __ jmp(&double_op); |
(...skipping 11 matching lines...) Expand all Loading... |
1122 TestLastArgumentIsDouble(assembler, &is_smi, &fall_through); | 1126 TestLastArgumentIsDouble(assembler, &is_smi, &fall_through); |
1123 // Argument is double and is in RAX. | 1127 // Argument is double and is in RAX. |
1124 __ movsd(XMM1, FieldAddress(RAX, Double::value_offset())); | 1128 __ movsd(XMM1, FieldAddress(RAX, Double::value_offset())); |
1125 __ Bind(&double_op); | 1129 __ Bind(&double_op); |
1126 __ sqrtsd(XMM0, XMM1); | 1130 __ sqrtsd(XMM0, XMM1); |
1127 const Class& double_class = Class::Handle( | 1131 const Class& double_class = Class::Handle( |
1128 Isolate::Current()->object_store()->double_class()); | 1132 Isolate::Current()->object_store()->double_class()); |
1129 AssemblerMacros::TryAllocate(assembler, | 1133 AssemblerMacros::TryAllocate(assembler, |
1130 double_class, | 1134 double_class, |
1131 &fall_through, | 1135 &fall_through, |
| 1136 Assembler::kNearJump, |
1132 RAX); // Result register. | 1137 RAX); // Result register. |
1133 __ movsd(FieldAddress(RAX, Double::value_offset()), XMM0); | 1138 __ movsd(FieldAddress(RAX, Double::value_offset()), XMM0); |
1134 __ ret(); | 1139 __ ret(); |
1135 __ Bind(&is_smi); | 1140 __ Bind(&is_smi); |
1136 __ SmiUntag(RAX); | 1141 __ SmiUntag(RAX); |
1137 __ cvtsi2sd(XMM1, RAX); | 1142 __ cvtsi2sd(XMM1, RAX); |
1138 __ jmp(&double_op); | 1143 __ jmp(&double_op); |
1139 __ Bind(&fall_through); | 1144 __ Bind(&fall_through); |
1140 return false; | 1145 return false; |
1141 } | 1146 } |
(...skipping 178 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1320 __ LoadObject(RAX, bool_true); | 1325 __ LoadObject(RAX, bool_true); |
1321 __ ret(); | 1326 __ ret(); |
1322 return true; | 1327 return true; |
1323 } | 1328 } |
1324 | 1329 |
1325 #undef __ | 1330 #undef __ |
1326 | 1331 |
1327 } // namespace dart | 1332 } // namespace dart |
1328 | 1333 |
1329 #endif // defined TARGET_ARCH_X64 | 1334 #endif // defined TARGET_ARCH_X64 |
OLD | NEW |