OLD | NEW |
1 //===- subzero/src/IceInstX8632.h - Low-level x86 instructions --*- C++ -*-===// | 1 //===- subzero/src/IceInstX8632.h - Low-level x86 instructions --*- C++ -*-===// |
2 // | 2 // |
3 // The Subzero Code Generator | 3 // The Subzero Code Generator |
4 // | 4 // |
5 // This file is distributed under the University of Illinois Open Source | 5 // This file is distributed under the University of Illinois Open Source |
6 // License. See LICENSE.TXT for details. | 6 // License. See LICENSE.TXT for details. |
7 // | 7 // |
8 //===----------------------------------------------------------------------===// | 8 //===----------------------------------------------------------------------===// |
9 // | 9 // |
10 // This file declares the InstX8632 and OperandX8632 classes and | 10 // This file declares the InstX8632 and OperandX8632 classes and |
(...skipping 411 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
422 virtual void dump(const Cfg *Func) const; | 422 virtual void dump(const Cfg *Func) const; |
423 static bool classof(const Inst *Inst) { return isClassof(Inst, Call); } | 423 static bool classof(const Inst *Inst) { return isClassof(Inst, Call); } |
424 | 424 |
425 private: | 425 private: |
426 InstX8632Call(Cfg *Func, Variable *Dest, Operand *CallTarget); | 426 InstX8632Call(Cfg *Func, Variable *Dest, Operand *CallTarget); |
427 InstX8632Call(const InstX8632Call &) LLVM_DELETED_FUNCTION; | 427 InstX8632Call(const InstX8632Call &) LLVM_DELETED_FUNCTION; |
428 InstX8632Call &operator=(const InstX8632Call &) LLVM_DELETED_FUNCTION; | 428 InstX8632Call &operator=(const InstX8632Call &) LLVM_DELETED_FUNCTION; |
429 virtual ~InstX8632Call() {} | 429 virtual ~InstX8632Call() {} |
430 }; | 430 }; |
431 | 431 |
| 432 // Emit a one-operand (GPR) instruction. |
| 433 void emitIASVarTyGPR(const Cfg *Func, Type Ty, const Variable *Var, |
| 434 const x86::AssemblerX86::GPREmitterOneOp &Emitter); |
| 435 |
432 // Instructions of the form x := op(x). | 436 // Instructions of the form x := op(x). |
433 template <InstX8632::InstKindX8632 K> | 437 template <InstX8632::InstKindX8632 K> |
434 class InstX8632Inplaceop : public InstX8632 { | 438 class InstX8632InplaceopGPR : public InstX8632 { |
435 public: | 439 public: |
436 static InstX8632Inplaceop *create(Cfg *Func, Operand *SrcDest) { | 440 static InstX8632InplaceopGPR *create(Cfg *Func, Operand *SrcDest) { |
437 return new (Func->allocate<InstX8632Inplaceop>()) | 441 return new (Func->allocate<InstX8632InplaceopGPR>()) |
438 InstX8632Inplaceop(Func, SrcDest); | 442 InstX8632InplaceopGPR(Func, SrcDest); |
439 } | 443 } |
440 virtual void emit(const Cfg *Func) const { | 444 virtual void emit(const Cfg *Func) const { |
441 Ostream &Str = Func->getContext()->getStrEmit(); | 445 Ostream &Str = Func->getContext()->getStrEmit(); |
442 assert(getSrcSize() == 1); | 446 assert(getSrcSize() == 1); |
443 Str << "\t" << Opcode << "\t"; | 447 Str << "\t" << Opcode << "\t"; |
444 getSrc(0)->emit(Func); | 448 getSrc(0)->emit(Func); |
445 Str << "\n"; | 449 Str << "\n"; |
446 } | 450 } |
| 451 virtual void emitIAS(const Cfg *Func) const { |
| 452 assert(getSrcSize() == 1); |
| 453 const Variable *Var = getDest(); |
| 454 Type Ty = Var->getType(); |
| 455 emitIASVarTyGPR(Func, Ty, Var, Emitter); |
| 456 } |
447 virtual void dump(const Cfg *Func) const { | 457 virtual void dump(const Cfg *Func) const { |
448 Ostream &Str = Func->getContext()->getStrDump(); | 458 Ostream &Str = Func->getContext()->getStrDump(); |
449 dumpDest(Func); | 459 dumpDest(Func); |
450 Str << " = " << Opcode << "." << getDest()->getType() << " "; | 460 Str << " = " << Opcode << "." << getDest()->getType() << " "; |
451 dumpSources(Func); | 461 dumpSources(Func); |
452 } | 462 } |
453 static bool classof(const Inst *Inst) { return isClassof(Inst, K); } | 463 static bool classof(const Inst *Inst) { return isClassof(Inst, K); } |
454 | 464 |
455 private: | 465 private: |
456 InstX8632Inplaceop(Cfg *Func, Operand *SrcDest) | 466 InstX8632InplaceopGPR(Cfg *Func, Operand *SrcDest) |
457 : InstX8632(Func, K, 1, llvm::dyn_cast<Variable>(SrcDest)) { | 467 : InstX8632(Func, K, 1, llvm::dyn_cast<Variable>(SrcDest)) { |
458 addSource(SrcDest); | 468 addSource(SrcDest); |
459 } | 469 } |
460 InstX8632Inplaceop(const InstX8632Inplaceop &) LLVM_DELETED_FUNCTION; | 470 InstX8632InplaceopGPR(const InstX8632InplaceopGPR &) LLVM_DELETED_FUNCTION; |
461 InstX8632Inplaceop & | 471 InstX8632InplaceopGPR & |
462 operator=(const InstX8632Inplaceop &) LLVM_DELETED_FUNCTION; | 472 operator=(const InstX8632InplaceopGPR &) LLVM_DELETED_FUNCTION; |
463 virtual ~InstX8632Inplaceop() {} | 473 virtual ~InstX8632InplaceopGPR() {} |
464 static const char *Opcode; | 474 static const char *Opcode; |
| 475 static const x86::AssemblerX86::GPREmitterOneOp Emitter; |
465 }; | 476 }; |
466 | 477 |
| 478 // Emit a two-operand (GPR) instruction, where the dest operand is a |
| 479 // Variable that's guaranteed to be a register. |
| 480 void emitIASRegOpTyGPR(const Cfg *Func, Type Ty, const Variable *Dst, |
| 481 const Operand *Src, |
| 482 const x86::AssemblerX86::GPREmitterRegOp &Emitter); |
| 483 |
467 // Instructions of the form x := op(y) | 484 // Instructions of the form x := op(y) |
468 template <InstX8632::InstKindX8632 K> | 485 template <InstX8632::InstKindX8632 K> |
469 class InstX8632Unaryop : public InstX8632 { | 486 class InstX8632UnaryopGPR : public InstX8632 { |
470 public: | 487 public: |
471 static InstX8632Unaryop *create(Cfg *Func, Variable *Dest, Operand *Src) { | 488 static InstX8632UnaryopGPR *create(Cfg *Func, Variable *Dest, Operand *Src) { |
472 return new (Func->allocate<InstX8632Unaryop>()) | 489 return new (Func->allocate<InstX8632UnaryopGPR>()) |
473 InstX8632Unaryop(Func, Dest, Src); | 490 InstX8632UnaryopGPR(Func, Dest, Src); |
474 } | 491 } |
475 virtual void emit(const Cfg *Func) const { | 492 virtual void emit(const Cfg *Func) const { |
476 Ostream &Str = Func->getContext()->getStrEmit(); | 493 Ostream &Str = Func->getContext()->getStrEmit(); |
477 assert(getSrcSize() == 1); | 494 assert(getSrcSize() == 1); |
478 Str << "\t" << Opcode << "\t"; | 495 Str << "\t" << Opcode << "\t"; |
479 getDest()->emit(Func); | 496 getDest()->emit(Func); |
480 Str << ", "; | 497 Str << ", "; |
481 getSrc(0)->emit(Func); | 498 getSrc(0)->emit(Func); |
482 Str << "\n"; | 499 Str << "\n"; |
483 } | 500 } |
484 virtual void emitIAS(const Cfg *Func) const { emit(Func); } | 501 virtual void emitIAS(const Cfg *Func) const { |
| 502 assert(getSrcSize() == 1); |
| 503 const Variable *Var = getDest(); |
| 504 Type Ty = Var->getType(); |
| 505 const Operand *Src = getSrc(0); |
| 506 emitIASRegOpTyGPR(Func, Ty, Var, Src, Emitter); |
| 507 } |
485 virtual void dump(const Cfg *Func) const { | 508 virtual void dump(const Cfg *Func) const { |
486 Ostream &Str = Func->getContext()->getStrDump(); | 509 Ostream &Str = Func->getContext()->getStrDump(); |
487 dumpDest(Func); | 510 dumpDest(Func); |
488 Str << " = " << Opcode << "." << getDest()->getType() << " "; | 511 Str << " = " << Opcode << "." << getDest()->getType() << " "; |
489 dumpSources(Func); | 512 dumpSources(Func); |
490 } | 513 } |
491 static bool classof(const Inst *Inst) { return isClassof(Inst, K); } | 514 static bool classof(const Inst *Inst) { return isClassof(Inst, K); } |
492 | 515 |
493 private: | 516 private: |
494 InstX8632Unaryop(Cfg *Func, Variable *Dest, Operand *Src) | 517 InstX8632UnaryopGPR(Cfg *Func, Variable *Dest, Operand *Src) |
495 : InstX8632(Func, K, 1, Dest) { | 518 : InstX8632(Func, K, 1, Dest) { |
496 addSource(Src); | 519 addSource(Src); |
497 } | 520 } |
498 InstX8632Unaryop(const InstX8632Unaryop &) LLVM_DELETED_FUNCTION; | 521 InstX8632UnaryopGPR(const InstX8632UnaryopGPR &) LLVM_DELETED_FUNCTION; |
499 InstX8632Unaryop &operator=(const InstX8632Unaryop &) LLVM_DELETED_FUNCTION; | 522 InstX8632UnaryopGPR & |
500 virtual ~InstX8632Unaryop() {} | 523 operator=(const InstX8632UnaryopGPR &) LLVM_DELETED_FUNCTION; |
| 524 virtual ~InstX8632UnaryopGPR() {} |
501 static const char *Opcode; | 525 static const char *Opcode; |
| 526 static const x86::AssemblerX86::GPREmitterRegOp Emitter; |
502 }; | 527 }; |
503 | 528 |
504 void emitIASVarOperandTyXMM(const Cfg *Func, Type Ty, const Variable *Var, | 529 void emitIASVarOperandTyXMM(const Cfg *Func, Type Ty, const Variable *Var, |
505 const Operand *Src, | 530 const Operand *Src, |
506 const x86::AssemblerX86::TypedXmmEmitters &Emitter); | 531 const x86::AssemblerX86::XmmEmitterTwoOps &Emitter); |
507 | 532 |
508 template <InstX8632::InstKindX8632 K> | 533 template <InstX8632::InstKindX8632 K> |
509 class InstX8632UnaryopXmm : public InstX8632 { | 534 class InstX8632UnaryopXmm : public InstX8632 { |
510 public: | 535 public: |
511 static InstX8632UnaryopXmm *create(Cfg *Func, Variable *Dest, Operand *Src) { | 536 static InstX8632UnaryopXmm *create(Cfg *Func, Variable *Dest, Operand *Src) { |
512 return new (Func->allocate<InstX8632UnaryopXmm>()) | 537 return new (Func->allocate<InstX8632UnaryopXmm>()) |
513 InstX8632UnaryopXmm(Func, Dest, Src); | 538 InstX8632UnaryopXmm(Func, Dest, Src); |
514 } | 539 } |
515 virtual void emit(const Cfg *Func) const { | 540 virtual void emit(const Cfg *Func) const { |
516 Ostream &Str = Func->getContext()->getStrEmit(); | 541 Ostream &Str = Func->getContext()->getStrEmit(); |
(...skipping 20 matching lines...) Expand all Loading... |
537 private: | 562 private: |
538 InstX8632UnaryopXmm(Cfg *Func, Variable *Dest, Operand *Src) | 563 InstX8632UnaryopXmm(Cfg *Func, Variable *Dest, Operand *Src) |
539 : InstX8632(Func, K, 1, Dest) { | 564 : InstX8632(Func, K, 1, Dest) { |
540 addSource(Src); | 565 addSource(Src); |
541 } | 566 } |
542 InstX8632UnaryopXmm(const InstX8632UnaryopXmm &) LLVM_DELETED_FUNCTION; | 567 InstX8632UnaryopXmm(const InstX8632UnaryopXmm &) LLVM_DELETED_FUNCTION; |
543 InstX8632UnaryopXmm & | 568 InstX8632UnaryopXmm & |
544 operator=(const InstX8632UnaryopXmm &) LLVM_DELETED_FUNCTION; | 569 operator=(const InstX8632UnaryopXmm &) LLVM_DELETED_FUNCTION; |
545 virtual ~InstX8632UnaryopXmm() {} | 570 virtual ~InstX8632UnaryopXmm() {} |
546 static const char *Opcode; | 571 static const char *Opcode; |
547 static const x86::AssemblerX86::TypedXmmEmitters Emitter; | 572 static const x86::AssemblerX86::XmmEmitterTwoOps Emitter; |
548 }; | 573 }; |
549 | 574 |
550 // See the definition of emitTwoAddress() for a description of | 575 // See the definition of emitTwoAddress() for a description of |
551 // ShiftHack. | 576 // ShiftHack. |
552 void emitTwoAddress(const char *Opcode, const Inst *Inst, const Cfg *Func, | 577 void emitTwoAddress(const char *Opcode, const Inst *Inst, const Cfg *Func, |
553 bool ShiftHack = false); | 578 bool ShiftHack = false); |
554 | 579 |
555 template <InstX8632::InstKindX8632 K, bool ShiftHack = false> | 580 template <InstX8632::InstKindX8632 K, bool ShiftHack = false> |
556 class InstX8632Binop : public InstX8632 { | 581 class InstX8632Binop : public InstX8632 { |
557 public: | 582 public: |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
613 private: | 638 private: |
614 InstX8632BinopXmm(Cfg *Func, Variable *Dest, Operand *Source) | 639 InstX8632BinopXmm(Cfg *Func, Variable *Dest, Operand *Source) |
615 : InstX8632(Func, K, 2, Dest) { | 640 : InstX8632(Func, K, 2, Dest) { |
616 addSource(Dest); | 641 addSource(Dest); |
617 addSource(Source); | 642 addSource(Source); |
618 } | 643 } |
619 InstX8632BinopXmm(const InstX8632BinopXmm &) LLVM_DELETED_FUNCTION; | 644 InstX8632BinopXmm(const InstX8632BinopXmm &) LLVM_DELETED_FUNCTION; |
620 InstX8632BinopXmm &operator=(const InstX8632BinopXmm &) LLVM_DELETED_FUNCTION; | 645 InstX8632BinopXmm &operator=(const InstX8632BinopXmm &) LLVM_DELETED_FUNCTION; |
621 virtual ~InstX8632BinopXmm() {} | 646 virtual ~InstX8632BinopXmm() {} |
622 static const char *Opcode; | 647 static const char *Opcode; |
623 static const x86::AssemblerX86::TypedXmmEmitters Emitter; | 648 static const x86::AssemblerX86::XmmEmitterTwoOps Emitter; |
624 }; | 649 }; |
625 | 650 |
626 template <InstX8632::InstKindX8632 K> class InstX8632Ternop : public InstX8632 { | 651 template <InstX8632::InstKindX8632 K> class InstX8632Ternop : public InstX8632 { |
627 public: | 652 public: |
628 // Create a ternary-op instruction like div or idiv. | 653 // Create a ternary-op instruction like div or idiv. |
629 static InstX8632Ternop *create(Cfg *Func, Variable *Dest, Operand *Source1, | 654 static InstX8632Ternop *create(Cfg *Func, Variable *Dest, Operand *Source1, |
630 Operand *Source2) { | 655 Operand *Source2) { |
631 return new (Func->allocate<InstX8632Ternop>()) | 656 return new (Func->allocate<InstX8632Ternop>()) |
632 InstX8632Ternop(Func, Dest, Source1, Source2); | 657 InstX8632Ternop(Func, Dest, Source1, Source2); |
633 } | 658 } |
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
734 : InstX8632(Func, K, 1, Dest) { | 759 : InstX8632(Func, K, 1, Dest) { |
735 addSource(Source); | 760 addSource(Source); |
736 } | 761 } |
737 InstX8632Movlike(const InstX8632Movlike &) LLVM_DELETED_FUNCTION; | 762 InstX8632Movlike(const InstX8632Movlike &) LLVM_DELETED_FUNCTION; |
738 InstX8632Movlike &operator=(const InstX8632Movlike &) LLVM_DELETED_FUNCTION; | 763 InstX8632Movlike &operator=(const InstX8632Movlike &) LLVM_DELETED_FUNCTION; |
739 virtual ~InstX8632Movlike() {} | 764 virtual ~InstX8632Movlike() {} |
740 | 765 |
741 static const char *Opcode; | 766 static const char *Opcode; |
742 }; | 767 }; |
743 | 768 |
744 typedef InstX8632Inplaceop<InstX8632::Bswap> InstX8632Bswap; | 769 typedef InstX8632InplaceopGPR<InstX8632::Bswap> InstX8632Bswap; |
745 typedef InstX8632Inplaceop<InstX8632::Neg> InstX8632Neg; | 770 typedef InstX8632InplaceopGPR<InstX8632::Neg> InstX8632Neg; |
746 typedef InstX8632Unaryop<InstX8632::Bsf> InstX8632Bsf; | 771 typedef InstX8632UnaryopGPR<InstX8632::Bsf> InstX8632Bsf; |
747 typedef InstX8632Unaryop<InstX8632::Bsr> InstX8632Bsr; | 772 typedef InstX8632UnaryopGPR<InstX8632::Bsr> InstX8632Bsr; |
748 typedef InstX8632Unaryop<InstX8632::Lea> InstX8632Lea; | 773 typedef InstX8632UnaryopGPR<InstX8632::Lea> InstX8632Lea; |
749 typedef InstX8632Unaryop<InstX8632::Movd> InstX8632Movd; | 774 // Cbwdq instruction - wrapper for cbw, cwd, and cdq |
| 775 typedef InstX8632UnaryopGPR<InstX8632::Cbwdq> InstX8632Cbwdq; |
| 776 typedef InstX8632UnaryopXmm<InstX8632::Movd> InstX8632Movd; |
750 typedef InstX8632UnaryopXmm<InstX8632::Sqrtss> InstX8632Sqrtss; | 777 typedef InstX8632UnaryopXmm<InstX8632::Sqrtss> InstX8632Sqrtss; |
751 // Cbwdq instruction - wrapper for cbw, cwd, and cdq | |
752 typedef InstX8632Unaryop<InstX8632::Cbwdq> InstX8632Cbwdq; | |
753 // Move/assignment instruction - wrapper for mov/movss/movsd. | 778 // Move/assignment instruction - wrapper for mov/movss/movsd. |
754 typedef InstX8632Movlike<InstX8632::Mov> InstX8632Mov; | 779 typedef InstX8632Movlike<InstX8632::Mov> InstX8632Mov; |
755 // Move packed - copy 128 bit values between XMM registers, or mem128 | 780 // Move packed - copy 128 bit values between XMM registers, or mem128 |
756 // and XMM registers. | 781 // and XMM registers. |
757 typedef InstX8632Movlike<InstX8632::Movp> InstX8632Movp; | 782 typedef InstX8632Movlike<InstX8632::Movp> InstX8632Movp; |
758 // Movq - copy between XMM registers, or mem64 and XMM registers. | 783 // Movq - copy between XMM registers, or mem64 and XMM registers. |
759 typedef InstX8632Movlike<InstX8632::Movq> InstX8632Movq; | 784 typedef InstX8632Movlike<InstX8632::Movq> InstX8632Movq; |
760 typedef InstX8632Binop<InstX8632::Add> InstX8632Add; | 785 typedef InstX8632Binop<InstX8632::Add> InstX8632Add; |
761 typedef InstX8632BinopXmm<InstX8632::Addps, true> InstX8632Addps; | 786 typedef InstX8632BinopXmm<InstX8632::Addps, true> InstX8632Addps; |
762 typedef InstX8632Binop<InstX8632::Adc> InstX8632Adc; | 787 typedef InstX8632Binop<InstX8632::Adc> InstX8632Adc; |
(...skipping 614 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1377 template <> void InstX8632Pinsr::emit(const Cfg *Func) const; | 1402 template <> void InstX8632Pinsr::emit(const Cfg *Func) const; |
1378 template <> void InstX8632Pmull::emit(const Cfg *Func) const; | 1403 template <> void InstX8632Pmull::emit(const Cfg *Func) const; |
1379 template <> void InstX8632Pmuludq::emit(const Cfg *Func) const; | 1404 template <> void InstX8632Pmuludq::emit(const Cfg *Func) const; |
1380 template <> void InstX8632Psll::emit(const Cfg *Func) const; | 1405 template <> void InstX8632Psll::emit(const Cfg *Func) const; |
1381 template <> void InstX8632Psra::emit(const Cfg *Func) const; | 1406 template <> void InstX8632Psra::emit(const Cfg *Func) const; |
1382 template <> void InstX8632Psub::emit(const Cfg *Func) const; | 1407 template <> void InstX8632Psub::emit(const Cfg *Func) const; |
1383 template <> void InstX8632Sqrtss::emit(const Cfg *Func) const; | 1408 template <> void InstX8632Sqrtss::emit(const Cfg *Func) const; |
1384 template <> void InstX8632Subss::emit(const Cfg *Func) const; | 1409 template <> void InstX8632Subss::emit(const Cfg *Func) const; |
1385 | 1410 |
1386 template <> void InstX8632Cbwdq::emitIAS(const Cfg *Func) const; | 1411 template <> void InstX8632Cbwdq::emitIAS(const Cfg *Func) const; |
| 1412 template <> void InstX8632Movd::emitIAS(const Cfg *Func) const; |
1387 | 1413 |
1388 } // end of namespace Ice | 1414 } // end of namespace Ice |
1389 | 1415 |
1390 #endif // SUBZERO_SRC_ICEINSTX8632_H | 1416 #endif // SUBZERO_SRC_ICEINSTX8632_H |
OLD | NEW |