| OLD | NEW |
| 1 //===- subzero/src/IceAssemblerX86BaseImpl.h - base x86 assembler -*- C++ -*-=// | 1 //===- subzero/src/IceAssemblerX86BaseImpl.h - base x86 assembler -*- C++ -*-=// |
| 2 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 2 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file |
| 3 // for details. All rights reserved. Use of this source code is governed by a | 3 // for details. All rights reserved. Use of this source code is governed by a |
| 4 // BSD-style license that can be found in the LICENSE file. | 4 // BSD-style license that can be found in the LICENSE file. |
| 5 // | 5 // |
| 6 // Modified by the Subzero authors. | 6 // Modified by the Subzero authors. |
| 7 // | 7 // |
| 8 //===----------------------------------------------------------------------===// | 8 //===----------------------------------------------------------------------===// |
| 9 // | 9 // |
| 10 // The Subzero Code Generator | 10 // The Subzero Code Generator |
| (...skipping 189 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 200 const Immediate &imm) { | 200 const Immediate &imm) { |
| 201 assert(Ty != IceType_i64 && "i64 not supported yet."); | 201 assert(Ty != IceType_i64 && "i64 not supported yet."); |
| 202 AssemblerBuffer::EnsureCapacity ensured(&Buffer); | 202 AssemblerBuffer::EnsureCapacity ensured(&Buffer); |
| 203 if (Ty == IceType_i16) | 203 if (Ty == IceType_i16) |
| 204 emitOperandSizeOverride(); | 204 emitOperandSizeOverride(); |
| 205 emitRexB(Ty, dst); | 205 emitRexB(Ty, dst); |
| 206 if (isByteSizedType(Ty)) { | 206 if (isByteSizedType(Ty)) { |
| 207 emitUint8(0xB0 + gprEncoding(dst)); | 207 emitUint8(0xB0 + gprEncoding(dst)); |
| 208 emitUint8(imm.value() & 0xFF); | 208 emitUint8(imm.value() & 0xFF); |
| 209 } else { | 209 } else { |
| 210 // TODO(jpp): When removing the assertion above ensure that in x86-64 we |
| 211 // emit a 64-bit immediate. |
| 210 emitUint8(0xB8 + gprEncoding(dst)); | 212 emitUint8(0xB8 + gprEncoding(dst)); |
| 211 emitImmediate(Ty, imm); | 213 emitImmediate(Ty, imm); |
| 212 } | 214 } |
| 213 } | 215 } |
| 214 | 216 |
| 215 template <class Machine> | 217 template <class Machine> |
| 216 void AssemblerX86Base<Machine>::mov(Type Ty, typename Traits::GPRRegister dst, | 218 void AssemblerX86Base<Machine>::mov(Type Ty, typename Traits::GPRRegister dst, |
| 217 typename Traits::GPRRegister src) { | 219 typename Traits::GPRRegister src) { |
| 218 AssemblerBuffer::EnsureCapacity ensured(&Buffer); | 220 AssemblerBuffer::EnsureCapacity ensured(&Buffer); |
| 219 if (Ty == IceType_i16) | 221 if (Ty == IceType_i16) |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 271 emitUint8(0xC6); | 273 emitUint8(0xC6); |
| 272 emitOperand(0, dst); | 274 emitOperand(0, dst); |
| 273 emitUint8(imm.value() & 0xFF); | 275 emitUint8(imm.value() & 0xFF); |
| 274 } else { | 276 } else { |
| 275 emitUint8(0xC7); | 277 emitUint8(0xC7); |
| 276 emitOperand(0, dst); | 278 emitOperand(0, dst); |
| 277 emitImmediate(Ty, imm); | 279 emitImmediate(Ty, imm); |
| 278 } | 280 } |
| 279 } | 281 } |
| 280 | 282 |
| 283 // TODO(jpp): test this. |
| 284 template <class Machine> |
| 285 template <typename T> |
| 286 typename std::enable_if<T::Is64Bit, void>::type |
| 287 AssemblerX86Base<Machine>::movabs(const typename Traits::GPRRegister Dst, |
| 288 uint64_t Imm64) { |
| 289 AssemblerBuffer::EnsureCapacity ensured(&Buffer); |
| 290 const bool NeedsRexW = (Imm64 & ~0xFFFFFFFFull) != 0; |
| 291 const Type RexType = NeedsRexW ? RexTypeForceRexW : RexTypeIrrelevant; |
| 292 emitRexB(RexType, Dst); |
| 293 emitUint8(0xB8 | gprEncoding(Dst)); |
| 294 // When emitting Imm64, we don't have to mask out the upper 32 bits for |
| 295 // emitInt32 will/should only emit a 32-bit constant. In reality, we are |
| 296 // paranoid, so we go ahead an mask the upper bits out anyway. |
| 297 emitInt32(Imm64 & 0xFFFFFFFF); |
| 298 if (NeedsRexW) |
| 299 emitInt32((Imm64 >> 32) & 0xFFFFFFFF); |
| 300 } |
| 301 |
| 302 // TODO(jpp): test this. |
| 281 template <class Machine> | 303 template <class Machine> |
| 282 void AssemblerX86Base<Machine>::movzx(Type SrcTy, | 304 void AssemblerX86Base<Machine>::movzx(Type SrcTy, |
| 283 typename Traits::GPRRegister dst, | 305 typename Traits::GPRRegister dst, |
| 284 typename Traits::GPRRegister src) { | 306 typename Traits::GPRRegister src) { |
| 307 if (Traits::Is64Bit && SrcTy == IceType_i32) { |
| 308 // 32-bit mov clears the upper 32 bits, hence zero-extending the 32-bit |
| 309 // operand to 64-bit. |
| 310 mov(IceType_i32, dst, src); |
| 311 return; |
| 312 } |
| 313 |
| 285 AssemblerBuffer::EnsureCapacity ensured(&Buffer); | 314 AssemblerBuffer::EnsureCapacity ensured(&Buffer); |
| 286 bool ByteSized = isByteSizedType(SrcTy); | 315 bool ByteSized = isByteSizedType(SrcTy); |
| 287 assert(ByteSized || SrcTy == IceType_i16); | 316 assert(ByteSized || SrcTy == IceType_i16); |
| 288 emitRexRB(RexTypeIrrelevant, dst, SrcTy, src); | 317 emitRexRB(RexTypeIrrelevant, dst, SrcTy, src); |
| 289 emitUint8(0x0F); | 318 emitUint8(0x0F); |
| 290 emitUint8(ByteSized ? 0xB6 : 0xB7); | 319 emitUint8(ByteSized ? 0xB6 : 0xB7); |
| 291 emitRegisterOperand(gprEncoding(dst), gprEncoding(src)); | 320 emitRegisterOperand(gprEncoding(dst), gprEncoding(src)); |
| 292 } | 321 } |
| 293 | 322 |
| 323 // TODO(jpp): test this. |
| 294 template <class Machine> | 324 template <class Machine> |
| 295 void AssemblerX86Base<Machine>::movzx(Type SrcTy, | 325 void AssemblerX86Base<Machine>::movzx(Type SrcTy, |
| 296 typename Traits::GPRRegister dst, | 326 typename Traits::GPRRegister dst, |
| 297 const typename Traits::Address &src) { | 327 const typename Traits::Address &src) { |
| 328 if (Traits::Is64Bit && SrcTy == IceType_i32) { |
| 329 // 32-bit mov clears the upper 32 bits, hence zero-extending the 32-bit |
| 330 // operand to 64-bit. |
| 331 mov(IceType_i32, dst, src); |
| 332 return; |
| 333 } |
| 334 |
| 298 AssemblerBuffer::EnsureCapacity ensured(&Buffer); | 335 AssemblerBuffer::EnsureCapacity ensured(&Buffer); |
| 299 bool ByteSized = isByteSizedType(SrcTy); | 336 bool ByteSized = isByteSizedType(SrcTy); |
| 300 assert(ByteSized || SrcTy == IceType_i16); | 337 assert(ByteSized || SrcTy == IceType_i16); |
| 301 emitRex(SrcTy, src, RexTypeIrrelevant, dst); | 338 emitRex(SrcTy, src, RexTypeIrrelevant, dst); |
| 302 emitUint8(0x0F); | 339 emitUint8(0x0F); |
| 303 emitUint8(ByteSized ? 0xB6 : 0xB7); | 340 emitUint8(ByteSized ? 0xB6 : 0xB7); |
| 304 emitOperand(gprEncoding(dst), src); | 341 emitOperand(gprEncoding(dst), src); |
| 305 } | 342 } |
| 306 | 343 |
| 307 template <class Machine> | 344 template <class Machine> |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 343 const typename Traits::Address &src) { | 380 const typename Traits::Address &src) { |
| 344 AssemblerBuffer::EnsureCapacity ensured(&Buffer); | 381 AssemblerBuffer::EnsureCapacity ensured(&Buffer); |
| 345 assert(Ty == IceType_i16 || Ty == IceType_i32); | 382 assert(Ty == IceType_i16 || Ty == IceType_i32); |
| 346 if (Ty == IceType_i16) | 383 if (Ty == IceType_i16) |
| 347 emitOperandSizeOverride(); | 384 emitOperandSizeOverride(); |
| 348 emitRex(Ty, src, dst); | 385 emitRex(Ty, src, dst); |
| 349 emitUint8(0x8D); | 386 emitUint8(0x8D); |
| 350 emitOperand(gprEncoding(dst), src); | 387 emitOperand(gprEncoding(dst), src); |
| 351 } | 388 } |
| 352 | 389 |
| 390 // TODO(jpp): test this. |
| 353 template <class Machine> | 391 template <class Machine> |
| 354 void AssemblerX86Base<Machine>::cmov(Type Ty, | 392 void AssemblerX86Base<Machine>::cmov(Type Ty, |
| 355 typename Traits::Cond::BrCond cond, | 393 typename Traits::Cond::BrCond cond, |
| 356 typename Traits::GPRRegister dst, | 394 typename Traits::GPRRegister dst, |
| 357 typename Traits::GPRRegister src) { | 395 typename Traits::GPRRegister src) { |
| 358 AssemblerBuffer::EnsureCapacity ensured(&Buffer); | 396 AssemblerBuffer::EnsureCapacity ensured(&Buffer); |
| 359 if (Ty == IceType_i16) | 397 if (Ty == IceType_i16) |
| 360 emitOperandSizeOverride(); | 398 emitOperandSizeOverride(); |
| 361 else | 399 else |
| 362 assert(Ty == IceType_i32); | 400 assert(Ty == IceType_i32 || (Traits::Is64Bit && Ty == IceType_i64)); |
| 363 emitRexRB(Ty, dst, src); | 401 emitRexRB(Ty, dst, src); |
| 364 emitUint8(0x0F); | 402 emitUint8(0x0F); |
| 365 emitUint8(0x40 + cond); | 403 emitUint8(0x40 + cond); |
| 366 emitRegisterOperand(gprEncoding(dst), gprEncoding(src)); | 404 emitRegisterOperand(gprEncoding(dst), gprEncoding(src)); |
| 367 } | 405 } |
| 368 | 406 |
| 407 // TODO(jpp): test this. |
| 369 template <class Machine> | 408 template <class Machine> |
| 370 void AssemblerX86Base<Machine>::cmov(Type Ty, | 409 void AssemblerX86Base<Machine>::cmov(Type Ty, |
| 371 typename Traits::Cond::BrCond cond, | 410 typename Traits::Cond::BrCond cond, |
| 372 typename Traits::GPRRegister dst, | 411 typename Traits::GPRRegister dst, |
| 373 const typename Traits::Address &src) { | 412 const typename Traits::Address &src) { |
| 374 AssemblerBuffer::EnsureCapacity ensured(&Buffer); | 413 AssemblerBuffer::EnsureCapacity ensured(&Buffer); |
| 375 if (Ty == IceType_i16) | 414 if (Ty == IceType_i16) |
| 376 emitOperandSizeOverride(); | 415 emitOperandSizeOverride(); |
| 377 else | 416 else |
| 378 assert(Ty == IceType_i32); | 417 assert(Ty == IceType_i32 || (Traits::Is64Bit && Ty == IceType_i64)); |
| 379 emitRex(Ty, src, dst); | 418 emitRex(Ty, src, dst); |
| 380 emitUint8(0x0F); | 419 emitUint8(0x0F); |
| 381 emitUint8(0x40 + cond); | 420 emitUint8(0x40 + cond); |
| 382 emitOperand(gprEncoding(dst), src); | 421 emitOperand(gprEncoding(dst), src); |
| 383 } | 422 } |
| 384 | 423 |
| 385 template <class Machine> void AssemblerX86Base<Machine>::rep_movsb() { | 424 template <class Machine> void AssemblerX86Base<Machine>::rep_movsb() { |
| 386 AssemblerBuffer::EnsureCapacity ensured(&Buffer); | 425 AssemblerBuffer::EnsureCapacity ensured(&Buffer); |
| 387 emitUint8(0xF3); | 426 emitUint8(0xF3); |
| 388 emitUint8(0xA4); | 427 emitUint8(0xA4); |
| (...skipping 26 matching lines...) Expand all Loading... |
| 415 void AssemblerX86Base<Machine>::movss(Type Ty, typename Traits::XmmRegister dst, | 454 void AssemblerX86Base<Machine>::movss(Type Ty, typename Traits::XmmRegister dst, |
| 416 typename Traits::XmmRegister src) { | 455 typename Traits::XmmRegister src) { |
| 417 AssemblerBuffer::EnsureCapacity ensured(&Buffer); | 456 AssemblerBuffer::EnsureCapacity ensured(&Buffer); |
| 418 emitUint8(isFloat32Asserting32Or64(Ty) ? 0xF3 : 0xF2); | 457 emitUint8(isFloat32Asserting32Or64(Ty) ? 0xF3 : 0xF2); |
| 419 emitRexRB(RexTypeIrrelevant, src, dst); | 458 emitRexRB(RexTypeIrrelevant, src, dst); |
| 420 emitUint8(0x0F); | 459 emitUint8(0x0F); |
| 421 emitUint8(0x11); | 460 emitUint8(0x11); |
| 422 emitXmmRegisterOperand(src, dst); | 461 emitXmmRegisterOperand(src, dst); |
| 423 } | 462 } |
| 424 | 463 |
| 464 // TODO(jpp): test this. |
| 425 template <class Machine> | 465 template <class Machine> |
| 426 void AssemblerX86Base<Machine>::movd(typename Traits::XmmRegister dst, | 466 void AssemblerX86Base<Machine>::movd(Type SrcTy, |
| 467 typename Traits::XmmRegister dst, |
| 427 typename Traits::GPRRegister src) { | 468 typename Traits::GPRRegister src) { |
| 428 AssemblerBuffer::EnsureCapacity ensured(&Buffer); | 469 AssemblerBuffer::EnsureCapacity ensured(&Buffer); |
| 429 emitUint8(0x66); | 470 emitUint8(0x66); |
| 430 emitRexRB(RexTypeIrrelevant, dst, src); | 471 emitRexRB(SrcTy, dst, src); |
| 431 emitUint8(0x0F); | 472 emitUint8(0x0F); |
| 432 emitUint8(0x6E); | 473 emitUint8(0x6E); |
| 433 emitRegisterOperand(gprEncoding(dst), gprEncoding(src)); | 474 emitRegisterOperand(gprEncoding(dst), gprEncoding(src)); |
| 434 } | 475 } |
| 435 | 476 |
| 477 // TODO(jpp): test this. |
| 436 template <class Machine> | 478 template <class Machine> |
| 437 void AssemblerX86Base<Machine>::movd(typename Traits::XmmRegister dst, | 479 void AssemblerX86Base<Machine>::movd(Type SrcTy, |
| 480 typename Traits::XmmRegister dst, |
| 438 const typename Traits::Address &src) { | 481 const typename Traits::Address &src) { |
| 439 AssemblerBuffer::EnsureCapacity ensured(&Buffer); | 482 AssemblerBuffer::EnsureCapacity ensured(&Buffer); |
| 440 emitUint8(0x66); | 483 emitUint8(0x66); |
| 441 emitRex(RexTypeIrrelevant, src, dst); | 484 emitRex(SrcTy, src, dst); |
| 442 emitUint8(0x0F); | 485 emitUint8(0x0F); |
| 443 emitUint8(0x6E); | 486 emitUint8(0x6E); |
| 444 emitOperand(gprEncoding(dst), src); | 487 emitOperand(gprEncoding(dst), src); |
| 445 } | 488 } |
| 446 | 489 |
| 490 // TODO(jpp): test this. |
| 447 template <class Machine> | 491 template <class Machine> |
| 448 void AssemblerX86Base<Machine>::movd(typename Traits::GPRRegister dst, | 492 void AssemblerX86Base<Machine>::movd(Type DestTy, |
| 493 typename Traits::GPRRegister dst, |
| 449 typename Traits::XmmRegister src) { | 494 typename Traits::XmmRegister src) { |
| 450 AssemblerBuffer::EnsureCapacity ensured(&Buffer); | 495 AssemblerBuffer::EnsureCapacity ensured(&Buffer); |
| 451 emitUint8(0x66); | 496 emitUint8(0x66); |
| 452 emitRexRB(RexTypeIrrelevant, src, dst); | 497 emitRexRB(DestTy, src, dst); |
| 453 emitUint8(0x0F); | 498 emitUint8(0x0F); |
| 454 emitUint8(0x7E); | 499 emitUint8(0x7E); |
| 455 emitRegisterOperand(gprEncoding(src), gprEncoding(dst)); | 500 emitRegisterOperand(gprEncoding(src), gprEncoding(dst)); |
| 456 } | 501 } |
| 457 | 502 |
| 503 // TODO(jpp): test this. |
| 458 template <class Machine> | 504 template <class Machine> |
| 459 void AssemblerX86Base<Machine>::movd(const typename Traits::Address &dst, | 505 void AssemblerX86Base<Machine>::movd(Type DestTy, |
| 506 const typename Traits::Address &dst, |
| 460 typename Traits::XmmRegister src) { | 507 typename Traits::XmmRegister src) { |
| 461 AssemblerBuffer::EnsureCapacity ensured(&Buffer); | 508 AssemblerBuffer::EnsureCapacity ensured(&Buffer); |
| 462 emitUint8(0x66); | 509 emitUint8(0x66); |
| 463 emitRex(RexTypeIrrelevant, dst, src); | 510 emitRex(DestTy, dst, src); |
| 464 emitUint8(0x0F); | 511 emitUint8(0x0F); |
| 465 emitUint8(0x7E); | 512 emitUint8(0x7E); |
| 466 emitOperand(gprEncoding(src), dst); | 513 emitOperand(gprEncoding(src), dst); |
| 467 } | 514 } |
| 468 | 515 |
| 469 template <class Machine> | 516 template <class Machine> |
| 470 void AssemblerX86Base<Machine>::movq(typename Traits::XmmRegister dst, | 517 void AssemblerX86Base<Machine>::movq(typename Traits::XmmRegister dst, |
| 471 typename Traits::XmmRegister src) { | 518 typename Traits::XmmRegister src) { |
| 472 AssemblerBuffer::EnsureCapacity ensured(&Buffer); | 519 AssemblerBuffer::EnsureCapacity ensured(&Buffer); |
| 473 emitUint8(0xF3); | 520 emitUint8(0xF3); |
| (...skipping 1003 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1477 typename Traits::XmmRegister dst, | 1524 typename Traits::XmmRegister dst, |
| 1478 const typename Traits::Address &src) { | 1525 const typename Traits::Address &src) { |
| 1479 AssemblerBuffer::EnsureCapacity ensured(&Buffer); | 1526 AssemblerBuffer::EnsureCapacity ensured(&Buffer); |
| 1480 emitUint8(0xF3); | 1527 emitUint8(0xF3); |
| 1481 emitRex(RexTypeIrrelevant, src, dst); | 1528 emitRex(RexTypeIrrelevant, src, dst); |
| 1482 emitUint8(0x0F); | 1529 emitUint8(0x0F); |
| 1483 emitUint8(0x5B); | 1530 emitUint8(0x5B); |
| 1484 emitOperand(gprEncoding(dst), src); | 1531 emitOperand(gprEncoding(dst), src); |
| 1485 } | 1532 } |
| 1486 | 1533 |
| 1534 // TODO(jpp): test this. |
| 1487 template <class Machine> | 1535 template <class Machine> |
| 1488 void AssemblerX86Base<Machine>::cvtsi2ss(Type DestTy, | 1536 void AssemblerX86Base<Machine>::cvtsi2ss(Type DestTy, |
| 1489 typename Traits::XmmRegister dst, | 1537 typename Traits::XmmRegister dst, |
| 1538 Type SrcTy, |
| 1490 typename Traits::GPRRegister src) { | 1539 typename Traits::GPRRegister src) { |
| 1491 AssemblerBuffer::EnsureCapacity ensured(&Buffer); | 1540 AssemblerBuffer::EnsureCapacity ensured(&Buffer); |
| 1492 emitUint8(isFloat32Asserting32Or64(DestTy) ? 0xF3 : 0xF2); | 1541 emitUint8(isFloat32Asserting32Or64(DestTy) ? 0xF3 : 0xF2); |
| 1493 emitRexRB(RexTypeIrrelevant, dst, src); | 1542 emitRexRB(SrcTy, dst, src); |
| 1494 emitUint8(0x0F); | 1543 emitUint8(0x0F); |
| 1495 emitUint8(0x2A); | 1544 emitUint8(0x2A); |
| 1496 emitXmmRegisterOperand(dst, src); | 1545 emitXmmRegisterOperand(dst, src); |
| 1497 } | 1546 } |
| 1498 | 1547 |
| 1548 // TODO(jpp): test this. |
| 1499 template <class Machine> | 1549 template <class Machine> |
| 1500 void AssemblerX86Base<Machine>::cvtsi2ss(Type DestTy, | 1550 void AssemblerX86Base<Machine>::cvtsi2ss(Type DestTy, |
| 1501 typename Traits::XmmRegister dst, | 1551 typename Traits::XmmRegister dst, |
| 1552 Type SrcTy, |
| 1502 const typename Traits::Address &src) { | 1553 const typename Traits::Address &src) { |
| 1503 AssemblerBuffer::EnsureCapacity ensured(&Buffer); | 1554 AssemblerBuffer::EnsureCapacity ensured(&Buffer); |
| 1504 emitUint8(isFloat32Asserting32Or64(DestTy) ? 0xF3 : 0xF2); | 1555 emitUint8(isFloat32Asserting32Or64(DestTy) ? 0xF3 : 0xF2); |
| 1505 emitRex(RexTypeIrrelevant, src, dst); | 1556 emitRex(SrcTy, src, dst); |
| 1506 emitUint8(0x0F); | 1557 emitUint8(0x0F); |
| 1507 emitUint8(0x2A); | 1558 emitUint8(0x2A); |
| 1508 emitOperand(gprEncoding(dst), src); | 1559 emitOperand(gprEncoding(dst), src); |
| 1509 } | 1560 } |
| 1510 | 1561 |
| 1511 template <class Machine> | 1562 template <class Machine> |
| 1512 void AssemblerX86Base<Machine>::cvtfloat2float( | 1563 void AssemblerX86Base<Machine>::cvtfloat2float( |
| 1513 Type SrcTy, typename Traits::XmmRegister dst, | 1564 Type SrcTy, typename Traits::XmmRegister dst, |
| 1514 typename Traits::XmmRegister src) { | 1565 typename Traits::XmmRegister src) { |
| 1515 AssemblerBuffer::EnsureCapacity ensured(&Buffer); | 1566 AssemblerBuffer::EnsureCapacity ensured(&Buffer); |
| (...skipping 10 matching lines...) Expand all Loading... |
| 1526 Type SrcTy, typename Traits::XmmRegister dst, | 1577 Type SrcTy, typename Traits::XmmRegister dst, |
| 1527 const typename Traits::Address &src) { | 1578 const typename Traits::Address &src) { |
| 1528 AssemblerBuffer::EnsureCapacity ensured(&Buffer); | 1579 AssemblerBuffer::EnsureCapacity ensured(&Buffer); |
| 1529 emitUint8(isFloat32Asserting32Or64(SrcTy) ? 0xF3 : 0xF2); | 1580 emitUint8(isFloat32Asserting32Or64(SrcTy) ? 0xF3 : 0xF2); |
| 1530 emitRex(RexTypeIrrelevant, src, dst); | 1581 emitRex(RexTypeIrrelevant, src, dst); |
| 1531 emitUint8(0x0F); | 1582 emitUint8(0x0F); |
| 1532 emitUint8(0x5A); | 1583 emitUint8(0x5A); |
| 1533 emitOperand(gprEncoding(dst), src); | 1584 emitOperand(gprEncoding(dst), src); |
| 1534 } | 1585 } |
| 1535 | 1586 |
| 1587 // TODO(jpp): test this. |
| 1536 template <class Machine> | 1588 template <class Machine> |
| 1537 void AssemblerX86Base<Machine>::cvttss2si(Type SrcTy, | 1589 void AssemblerX86Base<Machine>::cvttss2si(Type DestTy, |
| 1538 typename Traits::GPRRegister dst, | 1590 typename Traits::GPRRegister dst, |
| 1591 Type SrcTy, |
| 1539 typename Traits::XmmRegister src) { | 1592 typename Traits::XmmRegister src) { |
| 1540 AssemblerBuffer::EnsureCapacity ensured(&Buffer); | 1593 AssemblerBuffer::EnsureCapacity ensured(&Buffer); |
| 1541 emitUint8(isFloat32Asserting32Or64(SrcTy) ? 0xF3 : 0xF2); | 1594 emitUint8(isFloat32Asserting32Or64(SrcTy) ? 0xF3 : 0xF2); |
| 1542 emitRexRB(RexTypeIrrelevant, dst, src); | 1595 emitRexRB(DestTy, dst, src); |
| 1543 emitUint8(0x0F); | 1596 emitUint8(0x0F); |
| 1544 emitUint8(0x2C); | 1597 emitUint8(0x2C); |
| 1545 emitXmmRegisterOperand(dst, src); | 1598 emitXmmRegisterOperand(dst, src); |
| 1546 } | 1599 } |
| 1547 | 1600 |
| 1601 // TODO(jpp): test this. |
| 1548 template <class Machine> | 1602 template <class Machine> |
| 1549 void AssemblerX86Base<Machine>::cvttss2si(Type SrcTy, | 1603 void AssemblerX86Base<Machine>::cvttss2si(Type DestTy, |
| 1550 typename Traits::GPRRegister dst, | 1604 typename Traits::GPRRegister dst, |
| 1605 Type SrcTy, |
| 1551 const typename Traits::Address &src) { | 1606 const typename Traits::Address &src) { |
| 1552 AssemblerBuffer::EnsureCapacity ensured(&Buffer); | 1607 AssemblerBuffer::EnsureCapacity ensured(&Buffer); |
| 1553 emitUint8(isFloat32Asserting32Or64(SrcTy) ? 0xF3 : 0xF2); | 1608 emitUint8(isFloat32Asserting32Or64(SrcTy) ? 0xF3 : 0xF2); |
| 1554 emitRex(RexTypeIrrelevant, src, dst); | 1609 emitRex(DestTy, src, dst); |
| 1555 emitUint8(0x0F); | 1610 emitUint8(0x0F); |
| 1556 emitUint8(0x2C); | 1611 emitUint8(0x2C); |
| 1557 emitOperand(gprEncoding(dst), src); | 1612 emitOperand(gprEncoding(dst), src); |
| 1558 } | 1613 } |
| 1559 | 1614 |
| 1560 template <class Machine> | 1615 template <class Machine> |
| 1561 void AssemblerX86Base<Machine>::ucomiss(Type Ty, typename Traits::XmmRegister a, | 1616 void AssemblerX86Base<Machine>::ucomiss(Type Ty, typename Traits::XmmRegister a, |
| 1562 typename Traits::XmmRegister b) { | 1617 typename Traits::XmmRegister b) { |
| 1563 AssemblerBuffer::EnsureCapacity ensured(&Buffer); | 1618 AssemblerBuffer::EnsureCapacity ensured(&Buffer); |
| 1564 if (Ty == IceType_f64) | 1619 if (Ty == IceType_f64) |
| (...skipping 829 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2394 emitOperandSizeOverride(); | 2449 emitOperandSizeOverride(); |
| 2395 emitUint8(0x99); | 2450 emitUint8(0x99); |
| 2396 } | 2451 } |
| 2397 | 2452 |
| 2398 template <class Machine> void AssemblerX86Base<Machine>::cdq() { | 2453 template <class Machine> void AssemblerX86Base<Machine>::cdq() { |
| 2399 AssemblerBuffer::EnsureCapacity ensured(&Buffer); | 2454 AssemblerBuffer::EnsureCapacity ensured(&Buffer); |
| 2400 emitUint8(0x99); | 2455 emitUint8(0x99); |
| 2401 } | 2456 } |
| 2402 | 2457 |
| 2403 template <class Machine> | 2458 template <class Machine> |
| 2459 template <typename T> |
| 2460 typename std::enable_if<T::Is64Bit, void>::type |
| 2461 AssemblerX86Base<Machine>::cqo() { |
| 2462 AssemblerBuffer::EnsureCapacity ensured(&Buffer); |
| 2463 emitRexB(RexTypeForceRexW, RexRegIrrelevant); |
| 2464 emitUint8(0x99); |
| 2465 } |
| 2466 |
| 2467 template <class Machine> |
| 2404 void AssemblerX86Base<Machine>::div(Type Ty, typename Traits::GPRRegister reg) { | 2468 void AssemblerX86Base<Machine>::div(Type Ty, typename Traits::GPRRegister reg) { |
| 2405 AssemblerBuffer::EnsureCapacity ensured(&Buffer); | 2469 AssemblerBuffer::EnsureCapacity ensured(&Buffer); |
| 2406 if (Ty == IceType_i16) | 2470 if (Ty == IceType_i16) |
| 2407 emitOperandSizeOverride(); | 2471 emitOperandSizeOverride(); |
| 2408 emitRexB(Ty, reg); | 2472 emitRexB(Ty, reg); |
| 2409 if (isByteSizedArithType(Ty)) | 2473 if (isByteSizedArithType(Ty)) |
| 2410 emitUint8(0xF6); | 2474 emitUint8(0xF6); |
| 2411 else | 2475 else |
| 2412 emitUint8(0xF7); | 2476 emitUint8(0xF7); |
| 2413 emitRegisterOperand(6, gprEncoding(reg)); | 2477 emitRegisterOperand(6, gprEncoding(reg)); |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2452 emitUint8(0xF6); | 2516 emitUint8(0xF6); |
| 2453 else | 2517 else |
| 2454 emitUint8(0xF7); | 2518 emitUint8(0xF7); |
| 2455 emitOperand(7, addr); | 2519 emitOperand(7, addr); |
| 2456 } | 2520 } |
| 2457 | 2521 |
| 2458 template <class Machine> | 2522 template <class Machine> |
| 2459 void AssemblerX86Base<Machine>::imul(Type Ty, typename Traits::GPRRegister dst, | 2523 void AssemblerX86Base<Machine>::imul(Type Ty, typename Traits::GPRRegister dst, |
| 2460 typename Traits::GPRRegister src) { | 2524 typename Traits::GPRRegister src) { |
| 2461 AssemblerBuffer::EnsureCapacity ensured(&Buffer); | 2525 AssemblerBuffer::EnsureCapacity ensured(&Buffer); |
| 2462 assert(Ty == IceType_i16 || Ty == IceType_i32); | 2526 assert(Ty == IceType_i16 || Ty == IceType_i32 || |
| 2527 (Traits::Is64Bit && Ty == IceType_i64)); |
| 2463 if (Ty == IceType_i16) | 2528 if (Ty == IceType_i16) |
| 2464 emitOperandSizeOverride(); | 2529 emitOperandSizeOverride(); |
| 2465 emitRexRB(Ty, dst, src); | 2530 emitRexRB(Ty, dst, src); |
| 2466 emitUint8(0x0F); | 2531 emitUint8(0x0F); |
| 2467 emitUint8(0xAF); | 2532 emitUint8(0xAF); |
| 2468 emitRegisterOperand(gprEncoding(dst), gprEncoding(src)); | 2533 emitRegisterOperand(gprEncoding(dst), gprEncoding(src)); |
| 2469 } | 2534 } |
| 2470 | 2535 |
| 2471 template <class Machine> | 2536 template <class Machine> |
| 2472 void AssemblerX86Base<Machine>::imul(Type Ty, typename Traits::GPRRegister reg, | 2537 void AssemblerX86Base<Machine>::imul(Type Ty, typename Traits::GPRRegister reg, |
| 2473 const typename Traits::Address &address) { | 2538 const typename Traits::Address &address) { |
| 2474 AssemblerBuffer::EnsureCapacity ensured(&Buffer); | 2539 AssemblerBuffer::EnsureCapacity ensured(&Buffer); |
| 2475 assert(Ty == IceType_i16 || Ty == IceType_i32); | 2540 assert(Ty == IceType_i16 || Ty == IceType_i32 || |
| 2541 (Traits::Is64Bit && Ty == IceType_i64)); |
| 2476 if (Ty == IceType_i16) | 2542 if (Ty == IceType_i16) |
| 2477 emitOperandSizeOverride(); | 2543 emitOperandSizeOverride(); |
| 2478 emitRex(Ty, address, reg); | 2544 emitRex(Ty, address, reg); |
| 2479 emitUint8(0x0F); | 2545 emitUint8(0x0F); |
| 2480 emitUint8(0xAF); | 2546 emitUint8(0xAF); |
| 2481 emitOperand(gprEncoding(reg), address); | 2547 emitOperand(gprEncoding(reg), address); |
| 2482 } | 2548 } |
| 2483 | 2549 |
| 2484 template <class Machine> | 2550 template <class Machine> |
| 2485 void AssemblerX86Base<Machine>::imul(Type Ty, typename Traits::GPRRegister reg, | 2551 void AssemblerX86Base<Machine>::imul(Type Ty, typename Traits::GPRRegister reg, |
| (...skipping 297 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2783 AssemblerBuffer::EnsureCapacity ensured(&Buffer); | 2849 AssemblerBuffer::EnsureCapacity ensured(&Buffer); |
| 2784 emitRexB(IceType_i32, reg); | 2850 emitRexB(IceType_i32, reg); |
| 2785 emitUint8(0xF7); | 2851 emitUint8(0xF7); |
| 2786 emitUint8(0xD0 | gprEncoding(reg)); | 2852 emitUint8(0xD0 | gprEncoding(reg)); |
| 2787 } | 2853 } |
| 2788 | 2854 |
| 2789 template <class Machine> | 2855 template <class Machine> |
| 2790 void AssemblerX86Base<Machine>::bswap(Type Ty, | 2856 void AssemblerX86Base<Machine>::bswap(Type Ty, |
| 2791 typename Traits::GPRRegister reg) { | 2857 typename Traits::GPRRegister reg) { |
| 2792 AssemblerBuffer::EnsureCapacity ensured(&Buffer); | 2858 AssemblerBuffer::EnsureCapacity ensured(&Buffer); |
| 2793 assert(Ty == IceType_i32); | 2859 assert(Ty == IceType_i32 || (Traits::Is64Bit && Ty == IceType_i64)); |
| 2794 (void)Ty; | |
| 2795 emitRexB(Ty, reg); | 2860 emitRexB(Ty, reg); |
| 2796 emitUint8(0x0F); | 2861 emitUint8(0x0F); |
| 2797 emitUint8(0xC8 | gprEncoding(reg)); | 2862 emitUint8(0xC8 | gprEncoding(reg)); |
| 2798 } | 2863 } |
| 2799 | 2864 |
| 2800 template <class Machine> | 2865 template <class Machine> |
| 2801 void AssemblerX86Base<Machine>::bsf(Type Ty, typename Traits::GPRRegister dst, | 2866 void AssemblerX86Base<Machine>::bsf(Type Ty, typename Traits::GPRRegister dst, |
| 2802 typename Traits::GPRRegister src) { | 2867 typename Traits::GPRRegister src) { |
| 2803 AssemblerBuffer::EnsureCapacity ensured(&Buffer); | 2868 AssemblerBuffer::EnsureCapacity ensured(&Buffer); |
| 2804 assert(Ty == IceType_i16 || Ty == IceType_i32); | 2869 assert(Ty == IceType_i16 || Ty == IceType_i32); |
| (...skipping 477 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3282 (void)shifter; | 3347 (void)shifter; |
| 3283 if (Ty == IceType_i16) | 3348 if (Ty == IceType_i16) |
| 3284 emitOperandSizeOverride(); | 3349 emitOperandSizeOverride(); |
| 3285 emitRexB(Ty, operand.rm()); | 3350 emitRexB(Ty, operand.rm()); |
| 3286 emitUint8(isByteSizedArithType(Ty) ? 0xD2 : 0xD3); | 3351 emitUint8(isByteSizedArithType(Ty) ? 0xD2 : 0xD3); |
| 3287 emitOperand(rm, operand); | 3352 emitOperand(rm, operand); |
| 3288 } | 3353 } |
| 3289 | 3354 |
| 3290 } // end of namespace X86Internal | 3355 } // end of namespace X86Internal |
| 3291 } // end of namespace Ice | 3356 } // end of namespace Ice |
| OLD | NEW |