| OLD | NEW |
| 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, 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 1083 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1094 case Token::kSUB: __ subsd(XMM0, XMM1); break; | 1094 case Token::kSUB: __ subsd(XMM0, XMM1); break; |
| 1095 case Token::kMUL: __ mulsd(XMM0, XMM1); break; | 1095 case Token::kMUL: __ mulsd(XMM0, XMM1); break; |
| 1096 case Token::kDIV: __ divsd(XMM0, XMM1); break; | 1096 case Token::kDIV: __ divsd(XMM0, XMM1); break; |
| 1097 default: UNREACHABLE(); | 1097 default: UNREACHABLE(); |
| 1098 } | 1098 } |
| 1099 const Class& double_class = Class::Handle( | 1099 const Class& double_class = Class::Handle( |
| 1100 Isolate::Current()->object_store()->double_class()); | 1100 Isolate::Current()->object_store()->double_class()); |
| 1101 __ TryAllocate(double_class, | 1101 __ TryAllocate(double_class, |
| 1102 &fall_through, | 1102 &fall_through, |
| 1103 Assembler::kNearJump, | 1103 Assembler::kNearJump, |
| 1104 RAX); // Result register. | 1104 RAX, // Result register. |
| 1105 kNoRegister); // Pool pointer might not be loaded. |
| 1105 __ movsd(FieldAddress(RAX, Double::value_offset()), XMM0); | 1106 __ movsd(FieldAddress(RAX, Double::value_offset()), XMM0); |
| 1106 __ ret(); | 1107 __ ret(); |
| 1107 __ Bind(&fall_through); | 1108 __ Bind(&fall_through); |
| 1108 } | 1109 } |
| 1109 | 1110 |
| 1110 | 1111 |
| 1111 void Intrinsifier::Double_add(Assembler* assembler) { | 1112 void Intrinsifier::Double_add(Assembler* assembler) { |
| 1112 return DoubleArithmeticOperations(assembler, Token::kADD); | 1113 return DoubleArithmeticOperations(assembler, Token::kADD); |
| 1113 } | 1114 } |
| 1114 | 1115 |
| (...skipping 23 matching lines...) Expand all Loading... |
| 1138 __ SmiUntag(RAX); | 1139 __ SmiUntag(RAX); |
| 1139 __ cvtsi2sd(XMM1, RAX); | 1140 __ cvtsi2sd(XMM1, RAX); |
| 1140 __ movq(RAX, Address(RSP, + 2 * kWordSize)); | 1141 __ movq(RAX, Address(RSP, + 2 * kWordSize)); |
| 1141 __ movsd(XMM0, FieldAddress(RAX, Double::value_offset())); | 1142 __ movsd(XMM0, FieldAddress(RAX, Double::value_offset())); |
| 1142 __ mulsd(XMM0, XMM1); | 1143 __ mulsd(XMM0, XMM1); |
| 1143 const Class& double_class = Class::Handle( | 1144 const Class& double_class = Class::Handle( |
| 1144 Isolate::Current()->object_store()->double_class()); | 1145 Isolate::Current()->object_store()->double_class()); |
| 1145 __ TryAllocate(double_class, | 1146 __ TryAllocate(double_class, |
| 1146 &fall_through, | 1147 &fall_through, |
| 1147 Assembler::kNearJump, | 1148 Assembler::kNearJump, |
| 1148 RAX); // Result register. | 1149 RAX, // Result register. |
| 1150 kNoRegister); // Pool pointer might not be loaded. |
| 1149 __ movsd(FieldAddress(RAX, Double::value_offset()), XMM0); | 1151 __ movsd(FieldAddress(RAX, Double::value_offset()), XMM0); |
| 1150 __ ret(); | 1152 __ ret(); |
| 1151 __ Bind(&fall_through); | 1153 __ Bind(&fall_through); |
| 1152 } | 1154 } |
| 1153 | 1155 |
| 1154 | 1156 |
| 1155 // Left is double right is integer (Bigint, Mint or Smi) | 1157 // Left is double right is integer (Bigint, Mint or Smi) |
| 1156 void Intrinsifier::Double_fromInteger(Assembler* assembler) { | 1158 void Intrinsifier::Double_fromInteger(Assembler* assembler) { |
| 1157 Label fall_through; | 1159 Label fall_through; |
| 1158 __ movq(RAX, Address(RSP, +1 * kWordSize)); | 1160 __ movq(RAX, Address(RSP, +1 * kWordSize)); |
| 1159 __ testq(RAX, Immediate(kSmiTagMask)); | 1161 __ testq(RAX, Immediate(kSmiTagMask)); |
| 1160 __ j(NOT_ZERO, &fall_through, Assembler::kNearJump); | 1162 __ j(NOT_ZERO, &fall_through, Assembler::kNearJump); |
| 1161 // Is Smi. | 1163 // Is Smi. |
| 1162 __ SmiUntag(RAX); | 1164 __ SmiUntag(RAX); |
| 1163 __ cvtsi2sd(XMM0, RAX); | 1165 __ cvtsi2sd(XMM0, RAX); |
| 1164 const Class& double_class = Class::Handle( | 1166 const Class& double_class = Class::Handle( |
| 1165 Isolate::Current()->object_store()->double_class()); | 1167 Isolate::Current()->object_store()->double_class()); |
| 1166 __ TryAllocate(double_class, | 1168 __ TryAllocate(double_class, |
| 1167 &fall_through, | 1169 &fall_through, |
| 1168 Assembler::kNearJump, | 1170 Assembler::kNearJump, |
| 1169 RAX); // Result register. | 1171 RAX, // Result register. |
| 1172 kNoRegister); // Pool pointer might not be loaded. |
| 1170 __ movsd(FieldAddress(RAX, Double::value_offset()), XMM0); | 1173 __ movsd(FieldAddress(RAX, Double::value_offset()), XMM0); |
| 1171 __ ret(); | 1174 __ ret(); |
| 1172 __ Bind(&fall_through); | 1175 __ Bind(&fall_through); |
| 1173 } | 1176 } |
| 1174 | 1177 |
| 1175 | 1178 |
| 1176 void Intrinsifier::Double_getIsNaN(Assembler* assembler) { | 1179 void Intrinsifier::Double_getIsNaN(Assembler* assembler) { |
| 1177 Label is_true; | 1180 Label is_true; |
| 1178 __ movq(RAX, Address(RSP, +1 * kWordSize)); | 1181 __ movq(RAX, Address(RSP, +1 * kWordSize)); |
| 1179 __ movsd(XMM0, FieldAddress(RAX, Double::value_offset())); | 1182 __ movsd(XMM0, FieldAddress(RAX, Double::value_offset())); |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1229 case kCosine: __ fcos(); break; | 1232 case kCosine: __ fcos(); break; |
| 1230 default: | 1233 default: |
| 1231 UNREACHABLE(); | 1234 UNREACHABLE(); |
| 1232 } | 1235 } |
| 1233 const Class& double_class = Class::Handle( | 1236 const Class& double_class = Class::Handle( |
| 1234 Isolate::Current()->object_store()->double_class()); | 1237 Isolate::Current()->object_store()->double_class()); |
| 1235 Label alloc_failed; | 1238 Label alloc_failed; |
| 1236 __ TryAllocate(double_class, | 1239 __ TryAllocate(double_class, |
| 1237 &alloc_failed, | 1240 &alloc_failed, |
| 1238 Assembler::kNearJump, | 1241 Assembler::kNearJump, |
| 1239 RAX); // Result register. | 1242 RAX, // Result register. |
| 1243 kNoRegister); // Pool pointer might not be loaded. |
| 1240 __ fstpl(FieldAddress(RAX, Double::value_offset())); | 1244 __ fstpl(FieldAddress(RAX, Double::value_offset())); |
| 1241 __ ret(); | 1245 __ ret(); |
| 1242 | 1246 |
| 1243 __ Bind(&is_smi); // smi -> double. | 1247 __ Bind(&is_smi); // smi -> double. |
| 1244 __ SmiUntag(RAX); | 1248 __ SmiUntag(RAX); |
| 1245 __ pushq(RAX); | 1249 __ pushq(RAX); |
| 1246 __ fildl(Address(RSP, 0)); | 1250 __ fildl(Address(RSP, 0)); |
| 1247 __ popq(RAX); | 1251 __ popq(RAX); |
| 1248 __ jmp(&double_op); | 1252 __ jmp(&double_op); |
| 1249 | 1253 |
| (...skipping 26 matching lines...) Expand all Loading... |
| 1276 TestLastArgumentIsDouble(assembler, &is_smi, &fall_through); | 1280 TestLastArgumentIsDouble(assembler, &is_smi, &fall_through); |
| 1277 // Argument is double and is in RAX. | 1281 // Argument is double and is in RAX. |
| 1278 __ movsd(XMM1, FieldAddress(RAX, Double::value_offset())); | 1282 __ movsd(XMM1, FieldAddress(RAX, Double::value_offset())); |
| 1279 __ Bind(&double_op); | 1283 __ Bind(&double_op); |
| 1280 __ sqrtsd(XMM0, XMM1); | 1284 __ sqrtsd(XMM0, XMM1); |
| 1281 const Class& double_class = Class::Handle( | 1285 const Class& double_class = Class::Handle( |
| 1282 Isolate::Current()->object_store()->double_class()); | 1286 Isolate::Current()->object_store()->double_class()); |
| 1283 __ TryAllocate(double_class, | 1287 __ TryAllocate(double_class, |
| 1284 &fall_through, | 1288 &fall_through, |
| 1285 Assembler::kNearJump, | 1289 Assembler::kNearJump, |
| 1286 RAX); // Result register. | 1290 RAX, // Result register. |
| 1291 kNoRegister); // Pool pointer might not be loaded. |
| 1287 __ movsd(FieldAddress(RAX, Double::value_offset()), XMM0); | 1292 __ movsd(FieldAddress(RAX, Double::value_offset()), XMM0); |
| 1288 __ ret(); | 1293 __ ret(); |
| 1289 __ Bind(&is_smi); | 1294 __ Bind(&is_smi); |
| 1290 __ SmiUntag(RAX); | 1295 __ SmiUntag(RAX); |
| 1291 __ cvtsi2sd(XMM1, RAX); | 1296 __ cvtsi2sd(XMM1, RAX); |
| 1292 __ jmp(&double_op); | 1297 __ jmp(&double_op); |
| 1293 __ Bind(&fall_through); | 1298 __ Bind(&fall_through); |
| 1294 } | 1299 } |
| 1295 | 1300 |
| 1296 | 1301 |
| (...skipping 343 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1640 | 1645 |
| 1641 __ Bind(&fall_through); | 1646 __ Bind(&fall_through); |
| 1642 } | 1647 } |
| 1643 | 1648 |
| 1644 | 1649 |
| 1645 #undef __ | 1650 #undef __ |
| 1646 | 1651 |
| 1647 } // namespace dart | 1652 } // namespace dart |
| 1648 | 1653 |
| 1649 #endif // defined TARGET_ARCH_X64 | 1654 #endif // defined TARGET_ARCH_X64 |
| OLD | NEW |