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 1178 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1189 __ ret(); | 1189 __ ret(); |
1190 __ Bind(&is_zero); | 1190 __ Bind(&is_zero); |
1191 // Check for negative zero (get the sign bit). | 1191 // Check for negative zero (get the sign bit). |
1192 __ movmskpd(RAX, XMM0); | 1192 __ movmskpd(RAX, XMM0); |
1193 __ testq(RAX, Immediate(1)); | 1193 __ testq(RAX, Immediate(1)); |
1194 __ j(NOT_ZERO, &is_true, Assembler::kNearJump); | 1194 __ j(NOT_ZERO, &is_true, Assembler::kNearJump); |
1195 __ jmp(&is_false, Assembler::kNearJump); | 1195 __ jmp(&is_false, Assembler::kNearJump); |
1196 } | 1196 } |
1197 | 1197 |
1198 | 1198 |
1199 enum TrigonometricFunctions { | |
1200 kSine, | |
1201 kCosine, | |
1202 }; | |
1203 | |
1204 | |
1205 static void EmitTrigonometric(Assembler* assembler, | |
1206 TrigonometricFunctions kind) { | |
1207 Label fall_through, is_smi, double_op; | |
1208 TestLastArgumentIsDouble(assembler, &is_smi, &fall_through); | |
1209 // Argument is double and is in EAX. | |
1210 __ fldl(FieldAddress(RAX, Double::value_offset())); | |
1211 __ Bind(&double_op); | |
1212 switch (kind) { | |
1213 case kSine: __ fsin(); break; | |
1214 case kCosine: __ fcos(); break; | |
1215 default: | |
1216 UNREACHABLE(); | |
1217 } | |
1218 const Class& double_class = Class::Handle( | |
1219 Isolate::Current()->object_store()->double_class()); | |
1220 Label alloc_failed; | |
1221 __ TryAllocate(double_class, | |
1222 &alloc_failed, | |
1223 Assembler::kNearJump, | |
1224 RAX, // Result register. | |
1225 kNoRegister); // Pool pointer might not be loaded. | |
1226 __ fstpl(FieldAddress(RAX, Double::value_offset())); | |
1227 __ ret(); | |
1228 | |
1229 __ Bind(&is_smi); // smi -> double. | |
1230 __ SmiUntag(RAX); | |
1231 __ pushq(RAX); | |
1232 __ fildl(Address(RSP, 0)); | |
1233 __ popq(RAX); | |
1234 __ jmp(&double_op); | |
1235 | |
1236 __ Bind(&alloc_failed); | |
1237 __ ffree(0); | |
1238 __ fincstp(); | |
1239 | |
1240 __ Bind(&fall_through); | |
1241 } | |
1242 | |
1243 | |
1244 void Intrinsifier::Double_toInt(Assembler* assembler) { | 1199 void Intrinsifier::Double_toInt(Assembler* assembler) { |
1245 __ movq(RAX, Address(RSP, +1 * kWordSize)); | 1200 __ movq(RAX, Address(RSP, +1 * kWordSize)); |
1246 __ movsd(XMM0, FieldAddress(RAX, Double::value_offset())); | 1201 __ movsd(XMM0, FieldAddress(RAX, Double::value_offset())); |
1247 __ cvttsd2siq(RAX, XMM0); | 1202 __ cvttsd2siq(RAX, XMM0); |
1248 // Overflow is signalled with minint. | 1203 // Overflow is signalled with minint. |
1249 Label fall_through; | 1204 Label fall_through; |
1250 // Check for overflow and that it fits into Smi. | 1205 // Check for overflow and that it fits into Smi. |
1251 __ movq(RCX, RAX); | 1206 __ movq(RCX, RAX); |
1252 __ shlq(RCX, Immediate(1)); | 1207 __ shlq(RCX, Immediate(1)); |
1253 __ j(OVERFLOW, &fall_through, Assembler::kNearJump); | 1208 __ j(OVERFLOW, &fall_through, Assembler::kNearJump); |
(...skipping 20 matching lines...) Expand all Loading... |
1274 __ movsd(FieldAddress(RAX, Double::value_offset()), XMM0); | 1229 __ movsd(FieldAddress(RAX, Double::value_offset()), XMM0); |
1275 __ ret(); | 1230 __ ret(); |
1276 __ Bind(&is_smi); | 1231 __ Bind(&is_smi); |
1277 __ SmiUntag(RAX); | 1232 __ SmiUntag(RAX); |
1278 __ cvtsi2sd(XMM1, RAX); | 1233 __ cvtsi2sd(XMM1, RAX); |
1279 __ jmp(&double_op); | 1234 __ jmp(&double_op); |
1280 __ Bind(&fall_through); | 1235 __ Bind(&fall_through); |
1281 } | 1236 } |
1282 | 1237 |
1283 | 1238 |
1284 void Intrinsifier::Math_sin(Assembler* assembler) { | |
1285 EmitTrigonometric(assembler, kSine); | |
1286 } | |
1287 | |
1288 | |
1289 void Intrinsifier::Math_cos(Assembler* assembler) { | |
1290 EmitTrigonometric(assembler, kCosine); | |
1291 } | |
1292 | |
1293 | |
1294 // var state = ((_A * (_state[kSTATE_LO])) + _state[kSTATE_HI]) & _MASK_64; | 1239 // var state = ((_A * (_state[kSTATE_LO])) + _state[kSTATE_HI]) & _MASK_64; |
1295 // _state[kSTATE_LO] = state & _MASK_32; | 1240 // _state[kSTATE_LO] = state & _MASK_32; |
1296 // _state[kSTATE_HI] = state >> 32; | 1241 // _state[kSTATE_HI] = state >> 32; |
1297 void Intrinsifier::Random_nextState(Assembler* assembler) { | 1242 void Intrinsifier::Random_nextState(Assembler* assembler) { |
1298 const Library& math_lib = Library::Handle(Library::MathLibrary()); | 1243 const Library& math_lib = Library::Handle(Library::MathLibrary()); |
1299 ASSERT(!math_lib.IsNull()); | 1244 ASSERT(!math_lib.IsNull()); |
1300 const Class& random_class = Class::Handle( | 1245 const Class& random_class = Class::Handle( |
1301 math_lib.LookupClassAllowPrivate(Symbols::_Random())); | 1246 math_lib.LookupClassAllowPrivate(Symbols::_Random())); |
1302 ASSERT(!random_class.IsNull()); | 1247 ASSERT(!random_class.IsNull()); |
1303 const Field& state_field = Field::ZoneHandle( | 1248 const Field& state_field = Field::ZoneHandle( |
(...skipping 394 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1698 | 1643 |
1699 void Intrinsifier::TwoByteString_equality(Assembler* assembler) { | 1644 void Intrinsifier::TwoByteString_equality(Assembler* assembler) { |
1700 StringEquality(assembler, kTwoByteStringCid); | 1645 StringEquality(assembler, kTwoByteStringCid); |
1701 } | 1646 } |
1702 | 1647 |
1703 #undef __ | 1648 #undef __ |
1704 | 1649 |
1705 } // namespace dart | 1650 } // namespace dart |
1706 | 1651 |
1707 #endif // defined TARGET_ARCH_X64 | 1652 #endif // defined TARGET_ARCH_X64 |
OLD | NEW |