| OLD | NEW |
| 1 //===- subzero/src/IceInstX8632.cpp - X86-32 instruction implementation ---===// | 1 //===- subzero/src/IceInstX8632.cpp - X86-32 instruction implementation ---===// |
| 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 implements the InstX8632 and OperandX8632 classes, | 10 // This file implements the InstX8632 and OperandX8632 classes, |
| (...skipping 249 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 260 : InstX8632(Func, InstX8632::Mfence, 0, NULL) { | 260 : InstX8632(Func, InstX8632::Mfence, 0, NULL) { |
| 261 HasSideEffects = true; | 261 HasSideEffects = true; |
| 262 } | 262 } |
| 263 | 263 |
| 264 InstX8632Store::InstX8632Store(Cfg *Func, Operand *Value, OperandX8632 *Mem) | 264 InstX8632Store::InstX8632Store(Cfg *Func, Operand *Value, OperandX8632 *Mem) |
| 265 : InstX8632(Func, InstX8632::Store, 2, NULL) { | 265 : InstX8632(Func, InstX8632::Store, 2, NULL) { |
| 266 addSource(Value); | 266 addSource(Value); |
| 267 addSource(Mem); | 267 addSource(Mem); |
| 268 } | 268 } |
| 269 | 269 |
| 270 InstX8632StoreP::InstX8632StoreP(Cfg *Func, Operand *Value, OperandX8632 *Mem) | 270 InstX8632StoreP::InstX8632StoreP(Cfg *Func, Variable *Value, |
| 271 OperandX8632Mem *Mem) |
| 271 : InstX8632(Func, InstX8632::StoreP, 2, NULL) { | 272 : InstX8632(Func, InstX8632::StoreP, 2, NULL) { |
| 272 addSource(Value); | 273 addSource(Value); |
| 273 addSource(Mem); | 274 addSource(Mem); |
| 274 } | 275 } |
| 275 | 276 |
| 276 InstX8632StoreQ::InstX8632StoreQ(Cfg *Func, Operand *Value, OperandX8632 *Mem) | 277 InstX8632StoreQ::InstX8632StoreQ(Cfg *Func, Variable *Value, |
| 278 OperandX8632Mem *Mem) |
| 277 : InstX8632(Func, InstX8632::StoreQ, 2, NULL) { | 279 : InstX8632(Func, InstX8632::StoreQ, 2, NULL) { |
| 278 addSource(Value); | 280 addSource(Value); |
| 279 addSource(Mem); | 281 addSource(Mem); |
| 280 } | 282 } |
| 281 | 283 |
| 282 InstX8632Movsx::InstX8632Movsx(Cfg *Func, Variable *Dest, Operand *Source) | 284 InstX8632Movsx::InstX8632Movsx(Cfg *Func, Variable *Dest, Operand *Source) |
| 283 : InstX8632(Func, InstX8632::Movsx, 1, Dest) { | 285 : InstX8632(Func, InstX8632::Movsx, 1, Dest) { |
| 284 addSource(Source); | 286 addSource(Source); |
| 285 } | 287 } |
| 286 | 288 |
| (...skipping 242 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 529 } else if (const ConstantInteger32 *Imm = | 531 } else if (const ConstantInteger32 *Imm = |
| 530 llvm::dyn_cast<ConstantInteger32>(Src)) { | 532 llvm::dyn_cast<ConstantInteger32>(Src)) { |
| 531 (Asm->*(Emitter.GPRImm))(Ty, VarReg, x86::Immediate(Imm->getValue())); | 533 (Asm->*(Emitter.GPRImm))(Ty, VarReg, x86::Immediate(Imm->getValue())); |
| 532 } else { | 534 } else { |
| 533 llvm_unreachable("Unexpected operand type"); | 535 llvm_unreachable("Unexpected operand type"); |
| 534 } | 536 } |
| 535 Ostream &Str = Func->getContext()->getStrEmit(); | 537 Ostream &Str = Func->getContext()->getStrEmit(); |
| 536 emitIASBytes(Str, Asm, StartPosition); | 538 emitIASBytes(Str, Asm, StartPosition); |
| 537 } | 539 } |
| 538 | 540 |
| 541 void emitIASAddrOpTyGPR(const Cfg *Func, Type Ty, const x86::Address &Addr, |
| 542 const Operand *Src, |
| 543 const x86::AssemblerX86::GPREmitterAddrOp &Emitter) { |
| 544 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); |
| 545 intptr_t StartPosition = Asm->GetPosition(); |
| 546 // Src can only be Reg or Immediate. |
| 547 if (const Variable *SrcVar = llvm::dyn_cast<Variable>(Src)) { |
| 548 assert(SrcVar->hasReg()); |
| 549 RegX8632::GPRRegister SrcReg = |
| 550 RegX8632::getEncodedByteRegOrGPR(Ty, SrcVar->getRegNum()); |
| 551 (Asm->*(Emitter.AddrGPR))(Ty, Addr, SrcReg); |
| 552 } else if (const ConstantInteger32 *Imm = |
| 553 llvm::dyn_cast<ConstantInteger32>(Src)) { |
| 554 (Asm->*(Emitter.AddrImm))(Ty, Addr, x86::Immediate(Imm->getValue())); |
| 555 } else { |
| 556 llvm_unreachable("Unexpected operand type"); |
| 557 } |
| 558 Ostream &Str = Func->getContext()->getStrEmit(); |
| 559 emitIASBytes(Str, Asm, StartPosition); |
| 560 } |
| 561 |
| 539 void emitIASGPRShift(const Cfg *Func, Type Ty, const Variable *Var, | 562 void emitIASGPRShift(const Cfg *Func, Type Ty, const Variable *Var, |
| 540 const Operand *Src, | 563 const Operand *Src, |
| 541 const x86::AssemblerX86::GPREmitterShiftOp &Emitter) { | 564 const x86::AssemblerX86::GPREmitterShiftOp &Emitter) { |
| 542 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); | 565 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); |
| 543 intptr_t StartPosition = Asm->GetPosition(); | 566 intptr_t StartPosition = Asm->GetPosition(); |
| 544 // Technically, the Dest Var can be mem as well, but we only use Reg. | 567 // Technically, the Dest Var can be mem as well, but we only use Reg. |
| 545 // We can extend this to check Dest if we decide to use that form. | 568 // We can extend this to check Dest if we decide to use that form. |
| 546 assert(Var->hasReg()); | 569 assert(Var->hasReg()); |
| 547 // We cheat a little and use GPRRegister even for byte operations. | 570 // We cheat a little and use GPRRegister even for byte operations. |
| 548 RegX8632::GPRRegister VarReg = | 571 RegX8632::GPRRegister VarReg = |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 588 } else if (const ConstantInteger32 *Imm = | 611 } else if (const ConstantInteger32 *Imm = |
| 589 llvm::dyn_cast<ConstantInteger32>(Src)) { | 612 llvm::dyn_cast<ConstantInteger32>(Src)) { |
| 590 (Asm->*(Emitter.XmmImm))(Ty, VarReg, x86::Immediate(Imm->getValue())); | 613 (Asm->*(Emitter.XmmImm))(Ty, VarReg, x86::Immediate(Imm->getValue())); |
| 591 } else { | 614 } else { |
| 592 llvm_unreachable("Unexpected operand type"); | 615 llvm_unreachable("Unexpected operand type"); |
| 593 } | 616 } |
| 594 Ostream &Str = Func->getContext()->getStrEmit(); | 617 Ostream &Str = Func->getContext()->getStrEmit(); |
| 595 emitIASBytes(Str, Asm, StartPosition); | 618 emitIASBytes(Str, Asm, StartPosition); |
| 596 } | 619 } |
| 597 | 620 |
| 598 void | 621 void emitIASRegOpTyXMM(const Cfg *Func, Type Ty, const Variable *Var, |
| 599 emitIASVarOperandTyXMM(const Cfg *Func, Type Ty, const Variable *Var, | |
| 600 const Operand *Src, | 622 const Operand *Src, |
| 601 const x86::AssemblerX86::XmmEmitterTwoOps &Emitter) { | 623 const x86::AssemblerX86::XmmEmitterRegOp &Emitter) { |
| 602 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); | 624 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); |
| 603 intptr_t StartPosition = Asm->GetPosition(); | 625 intptr_t StartPosition = Asm->GetPosition(); |
| 604 assert(Var->hasReg()); | 626 assert(Var->hasReg()); |
| 605 RegX8632::XmmRegister VarReg = RegX8632::getEncodedXmm(Var->getRegNum()); | 627 RegX8632::XmmRegister VarReg = RegX8632::getEncodedXmm(Var->getRegNum()); |
| 606 if (const Variable *SrcVar = llvm::dyn_cast<Variable>(Src)) { | 628 if (const Variable *SrcVar = llvm::dyn_cast<Variable>(Src)) { |
| 607 if (SrcVar->hasReg()) { | 629 if (SrcVar->hasReg()) { |
| 608 RegX8632::XmmRegister SrcReg = | 630 RegX8632::XmmRegister SrcReg = |
| 609 RegX8632::getEncodedXmm(SrcVar->getRegNum()); | 631 RegX8632::getEncodedXmm(SrcVar->getRegNum()); |
| 610 (Asm->*(Emitter.XmmXmm))(Ty, VarReg, SrcReg); | 632 (Asm->*(Emitter.XmmXmm))(Ty, VarReg, SrcReg); |
| 611 } else { | 633 } else { |
| 612 x86::Address SrcStackAddr = static_cast<TargetX8632 *>(Func->getTarget()) | 634 x86::Address SrcStackAddr = static_cast<TargetX8632 *>(Func->getTarget()) |
| 613 ->stackVarToAsmOperand(SrcVar); | 635 ->stackVarToAsmOperand(SrcVar); |
| 614 (Asm->*(Emitter.XmmAddr))(Ty, VarReg, SrcStackAddr); | 636 (Asm->*(Emitter.XmmAddr))(Ty, VarReg, SrcStackAddr); |
| 615 } | 637 } |
| 616 } else if (const OperandX8632Mem *Mem = | 638 } else if (const OperandX8632Mem *Mem = |
| 617 llvm::dyn_cast<OperandX8632Mem>(Src)) { | 639 llvm::dyn_cast<OperandX8632Mem>(Src)) { |
| 618 x86::Address SrcAddr = Mem->toAsmAddress(Asm); | 640 x86::Address SrcAddr = Mem->toAsmAddress(Asm); |
| 619 (Asm->*(Emitter.XmmAddr))(Ty, VarReg, SrcAddr); | 641 (Asm->*(Emitter.XmmAddr))(Ty, VarReg, SrcAddr); |
| 620 } else if (const Constant *Imm = llvm::dyn_cast<Constant>(Src)) { | 642 } else if (const Constant *Imm = llvm::dyn_cast<Constant>(Src)) { |
| 621 (Asm->*(Emitter.XmmAddr))( | 643 (Asm->*(Emitter.XmmAddr))( |
| 622 Ty, VarReg, x86::Address::ofConstPool(Func->getContext(), Asm, Imm)); | 644 Ty, VarReg, x86::Address::ofConstPool(Func->getContext(), Asm, Imm)); |
| 623 } else { | 645 } else { |
| 624 llvm_unreachable("Unexpected operand type"); | 646 llvm_unreachable("Unexpected operand type"); |
| 625 } | 647 } |
| 626 Ostream &Str = Func->getContext()->getStrEmit(); | 648 Ostream &Str = Func->getContext()->getStrEmit(); |
| 627 emitIASBytes(Str, Asm, StartPosition); | 649 emitIASBytes(Str, Asm, StartPosition); |
| 628 } | 650 } |
| 629 | 651 |
| 652 void emitIASMovlikeXMM(const Cfg *Func, const Variable *Dest, |
| 653 const Operand *Src, |
| 654 const x86::AssemblerX86::XmmEmitterMovOps Emitter) { |
| 655 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); |
| 656 intptr_t StartPosition = Asm->GetPosition(); |
| 657 if (Dest->hasReg()) { |
| 658 RegX8632::XmmRegister DestReg = RegX8632::getEncodedXmm(Dest->getRegNum()); |
| 659 if (const Variable *SrcVar = llvm::dyn_cast<Variable>(Src)) { |
| 660 if (SrcVar->hasReg()) { |
| 661 (Asm->*(Emitter.XmmXmm))(DestReg, |
| 662 RegX8632::getEncodedXmm(SrcVar->getRegNum())); |
| 663 } else { |
| 664 x86::Address StackAddr(static_cast<TargetX8632 *>(Func->getTarget()) |
| 665 ->stackVarToAsmOperand(SrcVar)); |
| 666 (Asm->*(Emitter.XmmAddr))(DestReg, StackAddr); |
| 667 } |
| 668 } else if (const OperandX8632Mem *SrcMem = |
| 669 llvm::dyn_cast<OperandX8632Mem>(Src)) { |
| 670 (Asm->*(Emitter.XmmAddr))(DestReg, SrcMem->toAsmAddress(Asm)); |
| 671 } else { |
| 672 llvm_unreachable("Unexpected operand type"); |
| 673 } |
| 674 } else { |
| 675 x86::Address StackAddr(static_cast<TargetX8632 *>(Func->getTarget()) |
| 676 ->stackVarToAsmOperand(Dest)); |
| 677 // Src must be a register in this case. |
| 678 const Variable *SrcVar = llvm::cast<Variable>(Src); |
| 679 assert(SrcVar->hasReg()); |
| 680 (Asm->*(Emitter.AddrXmm))(StackAddr, |
| 681 RegX8632::getEncodedXmm(SrcVar->getRegNum())); |
| 682 } |
| 683 Ostream &Str = Func->getContext()->getStrEmit(); |
| 684 emitIASBytes(Str, Asm, StartPosition); |
| 685 } |
| 686 |
| 630 bool checkForRedundantAssign(const Variable *Dest, const Operand *Source) { | 687 bool checkForRedundantAssign(const Variable *Dest, const Operand *Source) { |
| 631 const Variable *Src = llvm::dyn_cast<const Variable>(Source); | 688 const Variable *Src = llvm::dyn_cast<const Variable>(Source); |
| 632 if (Src == NULL) | 689 if (Src == NULL) |
| 633 return false; | 690 return false; |
| 634 if (Dest->hasReg() && Dest->getRegNum() == Src->getRegNum()) { | 691 if (Dest->hasReg() && Dest->getRegNum() == Src->getRegNum()) { |
| 635 // TODO: On x86-64, instructions like "mov eax, eax" are used to | 692 // TODO: On x86-64, instructions like "mov eax, eax" are used to |
| 636 // clear the upper 32 bits of rax. We need to recognize and | 693 // clear the upper 32 bits of rax. We need to recognize and |
| 637 // preserve these. | 694 // preserve these. |
| 638 return true; | 695 return true; |
| 639 } | 696 } |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 685 template <> const char *InstX8632Idiv::Opcode = "idiv"; | 742 template <> const char *InstX8632Idiv::Opcode = "idiv"; |
| 686 template <> const char *InstX8632Divss::Opcode = "divss"; | 743 template <> const char *InstX8632Divss::Opcode = "divss"; |
| 687 template <> const char *InstX8632Rol::Opcode = "rol"; | 744 template <> const char *InstX8632Rol::Opcode = "rol"; |
| 688 template <> const char *InstX8632Shl::Opcode = "shl"; | 745 template <> const char *InstX8632Shl::Opcode = "shl"; |
| 689 template <> const char *InstX8632Psll::Opcode = "psll"; | 746 template <> const char *InstX8632Psll::Opcode = "psll"; |
| 690 template <> const char *InstX8632Shr::Opcode = "shr"; | 747 template <> const char *InstX8632Shr::Opcode = "shr"; |
| 691 template <> const char *InstX8632Sar::Opcode = "sar"; | 748 template <> const char *InstX8632Sar::Opcode = "sar"; |
| 692 template <> const char *InstX8632Psra::Opcode = "psra"; | 749 template <> const char *InstX8632Psra::Opcode = "psra"; |
| 693 template <> const char *InstX8632Pcmpeq::Opcode = "pcmpeq"; | 750 template <> const char *InstX8632Pcmpeq::Opcode = "pcmpeq"; |
| 694 template <> const char *InstX8632Pcmpgt::Opcode = "pcmpgt"; | 751 template <> const char *InstX8632Pcmpgt::Opcode = "pcmpgt"; |
| 695 template <> const char *InstX8632Movss::Opcode = "movss"; | 752 template <> const char *InstX8632MovssRegs::Opcode = "movss"; |
| 696 // Ternary ops | 753 // Ternary ops |
| 697 template <> const char *InstX8632Insertps::Opcode = "insertps"; | 754 template <> const char *InstX8632Insertps::Opcode = "insertps"; |
| 698 template <> const char *InstX8632Shufps::Opcode = "shufps"; | 755 template <> const char *InstX8632Shufps::Opcode = "shufps"; |
| 699 template <> const char *InstX8632Pinsr::Opcode = "pinsr"; | 756 template <> const char *InstX8632Pinsr::Opcode = "pinsr"; |
| 700 template <> const char *InstX8632Blendvps::Opcode = "blendvps"; | 757 template <> const char *InstX8632Blendvps::Opcode = "blendvps"; |
| 701 template <> const char *InstX8632Pblendvb::Opcode = "pblendvb"; | 758 template <> const char *InstX8632Pblendvb::Opcode = "pblendvb"; |
| 702 // Three address ops | 759 // Three address ops |
| 703 template <> const char *InstX8632Pextr::Opcode = "pextr"; | 760 template <> const char *InstX8632Pextr::Opcode = "pextr"; |
| 704 template <> const char *InstX8632Pshufd::Opcode = "pshufd"; | 761 template <> const char *InstX8632Pshufd::Opcode = "pshufd"; |
| 705 | 762 |
| (...skipping 11 matching lines...) Expand all Loading... |
| 717 &x86::AssemblerX86::bsf, &x86::AssemblerX86::bsf, NULL}; | 774 &x86::AssemblerX86::bsf, &x86::AssemblerX86::bsf, NULL}; |
| 718 template <> | 775 template <> |
| 719 const x86::AssemblerX86::GPREmitterRegOp InstX8632Bsr::Emitter = { | 776 const x86::AssemblerX86::GPREmitterRegOp InstX8632Bsr::Emitter = { |
| 720 &x86::AssemblerX86::bsr, &x86::AssemblerX86::bsr, NULL}; | 777 &x86::AssemblerX86::bsr, &x86::AssemblerX86::bsr, NULL}; |
| 721 template <> | 778 template <> |
| 722 const x86::AssemblerX86::GPREmitterRegOp InstX8632Lea::Emitter = { | 779 const x86::AssemblerX86::GPREmitterRegOp InstX8632Lea::Emitter = { |
| 723 /* reg/reg and reg/imm are illegal */ NULL, &x86::AssemblerX86::lea, NULL}; | 780 /* reg/reg and reg/imm are illegal */ NULL, &x86::AssemblerX86::lea, NULL}; |
| 724 | 781 |
| 725 // Unary XMM ops | 782 // Unary XMM ops |
| 726 template <> | 783 template <> |
| 727 const x86::AssemblerX86::XmmEmitterTwoOps InstX8632Sqrtss::Emitter = { | 784 const x86::AssemblerX86::XmmEmitterRegOp InstX8632Sqrtss::Emitter = { |
| 728 &x86::AssemblerX86::sqrtss, &x86::AssemblerX86::sqrtss, NULL}; | 785 &x86::AssemblerX86::sqrtss, &x86::AssemblerX86::sqrtss}; |
| 729 | 786 |
| 730 // Binary GPR ops | 787 // Binary GPR ops |
| 731 template <> | 788 template <> |
| 732 const x86::AssemblerX86::GPREmitterRegOp InstX8632Add::Emitter = { | 789 const x86::AssemblerX86::GPREmitterRegOp InstX8632Add::Emitter = { |
| 733 &x86::AssemblerX86::add, &x86::AssemblerX86::add, &x86::AssemblerX86::add}; | 790 &x86::AssemblerX86::add, &x86::AssemblerX86::add, &x86::AssemblerX86::add}; |
| 734 template <> | 791 template <> |
| 735 const x86::AssemblerX86::GPREmitterRegOp InstX8632Adc::Emitter = { | 792 const x86::AssemblerX86::GPREmitterRegOp InstX8632Adc::Emitter = { |
| 736 &x86::AssemblerX86::adc, &x86::AssemblerX86::adc, &x86::AssemblerX86::adc}; | 793 &x86::AssemblerX86::adc, &x86::AssemblerX86::adc, &x86::AssemblerX86::adc}; |
| 737 template <> | 794 template <> |
| 738 const x86::AssemblerX86::GPREmitterRegOp InstX8632And::Emitter = { | 795 const x86::AssemblerX86::GPREmitterRegOp InstX8632And::Emitter = { |
| (...skipping 20 matching lines...) Expand all Loading... |
| 759 &x86::AssemblerX86::sar, &x86::AssemblerX86::sar}; | 816 &x86::AssemblerX86::sar, &x86::AssemblerX86::sar}; |
| 760 template <> | 817 template <> |
| 761 const x86::AssemblerX86::GPREmitterShiftOp InstX8632Shl::Emitter = { | 818 const x86::AssemblerX86::GPREmitterShiftOp InstX8632Shl::Emitter = { |
| 762 &x86::AssemblerX86::shl, &x86::AssemblerX86::shl}; | 819 &x86::AssemblerX86::shl, &x86::AssemblerX86::shl}; |
| 763 template <> | 820 template <> |
| 764 const x86::AssemblerX86::GPREmitterShiftOp InstX8632Shr::Emitter = { | 821 const x86::AssemblerX86::GPREmitterShiftOp InstX8632Shr::Emitter = { |
| 765 &x86::AssemblerX86::shr, &x86::AssemblerX86::shr}; | 822 &x86::AssemblerX86::shr, &x86::AssemblerX86::shr}; |
| 766 | 823 |
| 767 // Binary XMM ops | 824 // Binary XMM ops |
| 768 template <> | 825 template <> |
| 769 const x86::AssemblerX86::XmmEmitterTwoOps InstX8632Addss::Emitter = { | 826 const x86::AssemblerX86::XmmEmitterRegOp InstX8632Addss::Emitter = { |
| 770 &x86::AssemblerX86::addss, &x86::AssemblerX86::addss, NULL}; | 827 &x86::AssemblerX86::addss, &x86::AssemblerX86::addss}; |
| 771 template <> | 828 template <> |
| 772 const x86::AssemblerX86::XmmEmitterTwoOps InstX8632Addps::Emitter = { | 829 const x86::AssemblerX86::XmmEmitterRegOp InstX8632Addps::Emitter = { |
| 773 &x86::AssemblerX86::addps, &x86::AssemblerX86::addps, NULL}; | 830 &x86::AssemblerX86::addps, &x86::AssemblerX86::addps}; |
| 774 template <> | 831 template <> |
| 775 const x86::AssemblerX86::XmmEmitterTwoOps InstX8632Divss::Emitter = { | 832 const x86::AssemblerX86::XmmEmitterRegOp InstX8632Divss::Emitter = { |
| 776 &x86::AssemblerX86::divss, &x86::AssemblerX86::divss, NULL}; | 833 &x86::AssemblerX86::divss, &x86::AssemblerX86::divss}; |
| 777 template <> | 834 template <> |
| 778 const x86::AssemblerX86::XmmEmitterTwoOps InstX8632Divps::Emitter = { | 835 const x86::AssemblerX86::XmmEmitterRegOp InstX8632Divps::Emitter = { |
| 779 &x86::AssemblerX86::divps, &x86::AssemblerX86::divps, NULL}; | 836 &x86::AssemblerX86::divps, &x86::AssemblerX86::divps}; |
| 780 template <> | 837 template <> |
| 781 const x86::AssemblerX86::XmmEmitterTwoOps InstX8632Mulss::Emitter = { | 838 const x86::AssemblerX86::XmmEmitterRegOp InstX8632Mulss::Emitter = { |
| 782 &x86::AssemblerX86::mulss, &x86::AssemblerX86::mulss, NULL}; | 839 &x86::AssemblerX86::mulss, &x86::AssemblerX86::mulss}; |
| 783 template <> | 840 template <> |
| 784 const x86::AssemblerX86::XmmEmitterTwoOps InstX8632Mulps::Emitter = { | 841 const x86::AssemblerX86::XmmEmitterRegOp InstX8632Mulps::Emitter = { |
| 785 &x86::AssemblerX86::mulps, &x86::AssemblerX86::mulps, NULL}; | 842 &x86::AssemblerX86::mulps, &x86::AssemblerX86::mulps}; |
| 786 template <> | 843 template <> |
| 787 const x86::AssemblerX86::XmmEmitterTwoOps InstX8632Padd::Emitter = { | 844 const x86::AssemblerX86::XmmEmitterRegOp InstX8632Padd::Emitter = { |
| 788 &x86::AssemblerX86::padd, &x86::AssemblerX86::padd, NULL}; | 845 &x86::AssemblerX86::padd, &x86::AssemblerX86::padd}; |
| 789 template <> | 846 template <> |
| 790 const x86::AssemblerX86::XmmEmitterTwoOps InstX8632Pand::Emitter = { | 847 const x86::AssemblerX86::XmmEmitterRegOp InstX8632Pand::Emitter = { |
| 791 &x86::AssemblerX86::pand, &x86::AssemblerX86::pand, NULL}; | 848 &x86::AssemblerX86::pand, &x86::AssemblerX86::pand}; |
| 792 template <> | 849 template <> |
| 793 const x86::AssemblerX86::XmmEmitterTwoOps InstX8632Pandn::Emitter = { | 850 const x86::AssemblerX86::XmmEmitterRegOp InstX8632Pandn::Emitter = { |
| 794 &x86::AssemblerX86::pandn, &x86::AssemblerX86::pandn, NULL}; | 851 &x86::AssemblerX86::pandn, &x86::AssemblerX86::pandn}; |
| 795 template <> | 852 template <> |
| 796 const x86::AssemblerX86::XmmEmitterTwoOps InstX8632Pcmpeq::Emitter = { | 853 const x86::AssemblerX86::XmmEmitterRegOp InstX8632Pcmpeq::Emitter = { |
| 797 &x86::AssemblerX86::pcmpeq, &x86::AssemblerX86::pcmpeq, NULL}; | 854 &x86::AssemblerX86::pcmpeq, &x86::AssemblerX86::pcmpeq}; |
| 798 template <> | 855 template <> |
| 799 const x86::AssemblerX86::XmmEmitterTwoOps InstX8632Pcmpgt::Emitter = { | 856 const x86::AssemblerX86::XmmEmitterRegOp InstX8632Pcmpgt::Emitter = { |
| 800 &x86::AssemblerX86::pcmpgt, &x86::AssemblerX86::pcmpgt, NULL}; | 857 &x86::AssemblerX86::pcmpgt, &x86::AssemblerX86::pcmpgt}; |
| 801 template <> | 858 template <> |
| 802 const x86::AssemblerX86::XmmEmitterTwoOps InstX8632Pmull::Emitter = { | 859 const x86::AssemblerX86::XmmEmitterRegOp InstX8632Pmull::Emitter = { |
| 803 &x86::AssemblerX86::pmull, &x86::AssemblerX86::pmull, NULL}; | 860 &x86::AssemblerX86::pmull, &x86::AssemblerX86::pmull}; |
| 804 template <> | 861 template <> |
| 805 const x86::AssemblerX86::XmmEmitterTwoOps InstX8632Pmuludq::Emitter = { | 862 const x86::AssemblerX86::XmmEmitterRegOp InstX8632Pmuludq::Emitter = { |
| 806 &x86::AssemblerX86::pmuludq, &x86::AssemblerX86::pmuludq, NULL}; | 863 &x86::AssemblerX86::pmuludq, &x86::AssemblerX86::pmuludq}; |
| 807 template <> | 864 template <> |
| 808 const x86::AssemblerX86::XmmEmitterTwoOps InstX8632Por::Emitter = { | 865 const x86::AssemblerX86::XmmEmitterRegOp InstX8632Por::Emitter = { |
| 809 &x86::AssemblerX86::por, &x86::AssemblerX86::por, NULL}; | 866 &x86::AssemblerX86::por, &x86::AssemblerX86::por}; |
| 810 template <> | 867 template <> |
| 811 const x86::AssemblerX86::XmmEmitterTwoOps InstX8632Psub::Emitter = { | 868 const x86::AssemblerX86::XmmEmitterRegOp InstX8632Psub::Emitter = { |
| 812 &x86::AssemblerX86::psub, &x86::AssemblerX86::psub, NULL}; | 869 &x86::AssemblerX86::psub, &x86::AssemblerX86::psub}; |
| 813 template <> | 870 template <> |
| 814 const x86::AssemblerX86::XmmEmitterTwoOps InstX8632Pxor::Emitter = { | 871 const x86::AssemblerX86::XmmEmitterRegOp InstX8632Pxor::Emitter = { |
| 815 &x86::AssemblerX86::pxor, &x86::AssemblerX86::pxor, NULL}; | 872 &x86::AssemblerX86::pxor, &x86::AssemblerX86::pxor}; |
| 816 template <> | 873 template <> |
| 817 const x86::AssemblerX86::XmmEmitterTwoOps InstX8632Subss::Emitter = { | 874 const x86::AssemblerX86::XmmEmitterRegOp InstX8632Subss::Emitter = { |
| 818 &x86::AssemblerX86::subss, &x86::AssemblerX86::subss, NULL}; | 875 &x86::AssemblerX86::subss, &x86::AssemblerX86::subss}; |
| 819 template <> | 876 template <> |
| 820 const x86::AssemblerX86::XmmEmitterTwoOps InstX8632Subps::Emitter = { | 877 const x86::AssemblerX86::XmmEmitterRegOp InstX8632Subps::Emitter = { |
| 821 &x86::AssemblerX86::subps, &x86::AssemblerX86::subps, NULL}; | 878 &x86::AssemblerX86::subps, &x86::AssemblerX86::subps}; |
| 822 | 879 |
| 823 // Binary XMM Shift ops | 880 // Binary XMM Shift ops |
| 824 template <> | 881 template <> |
| 825 const x86::AssemblerX86::XmmEmitterShiftOp InstX8632Psll::Emitter = { | 882 const x86::AssemblerX86::XmmEmitterShiftOp InstX8632Psll::Emitter = { |
| 826 &x86::AssemblerX86::psll, &x86::AssemblerX86::psll, | 883 &x86::AssemblerX86::psll, &x86::AssemblerX86::psll, |
| 827 &x86::AssemblerX86::psll}; | 884 &x86::AssemblerX86::psll}; |
| 828 template <> | 885 template <> |
| 829 const x86::AssemblerX86::XmmEmitterShiftOp InstX8632Psra::Emitter = { | 886 const x86::AssemblerX86::XmmEmitterShiftOp InstX8632Psra::Emitter = { |
| 830 &x86::AssemblerX86::psra, &x86::AssemblerX86::psra, | 887 &x86::AssemblerX86::psra, &x86::AssemblerX86::psra, |
| 831 &x86::AssemblerX86::psra}; | 888 &x86::AssemblerX86::psra}; |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 879 bool InstructionSetIsValid = | 936 bool InstructionSetIsValid = |
| 880 Ty == IceType_v8i16 || | 937 Ty == IceType_v8i16 || |
| 881 static_cast<TargetX8632 *>(Func->getTarget())->getInstructionSet() >= | 938 static_cast<TargetX8632 *>(Func->getTarget())->getInstructionSet() >= |
| 882 TargetX8632::SSE4_1; | 939 TargetX8632::SSE4_1; |
| 883 (void)TypesAreValid; | 940 (void)TypesAreValid; |
| 884 (void)InstructionSetIsValid; | 941 (void)InstructionSetIsValid; |
| 885 assert(TypesAreValid); | 942 assert(TypesAreValid); |
| 886 assert(InstructionSetIsValid); | 943 assert(InstructionSetIsValid); |
| 887 assert(getSrcSize() == 2); | 944 assert(getSrcSize() == 2); |
| 888 Type ElementTy = typeElementType(Ty); | 945 Type ElementTy = typeElementType(Ty); |
| 889 emitIASVarOperandTyXMM(Func, ElementTy, getDest(), getSrc(1), Emitter); | 946 emitIASRegOpTyXMM(Func, ElementTy, getDest(), getSrc(1), Emitter); |
| 890 } | 947 } |
| 891 | 948 |
| 892 template <> void InstX8632Subss::emit(const Cfg *Func) const { | 949 template <> void InstX8632Subss::emit(const Cfg *Func) const { |
| 893 char buf[30]; | 950 char buf[30]; |
| 894 snprintf(buf, llvm::array_lengthof(buf), "sub%s", | 951 snprintf(buf, llvm::array_lengthof(buf), "sub%s", |
| 895 TypeX8632Attributes[getDest()->getType()].SdSsString); | 952 TypeX8632Attributes[getDest()->getType()].SdSsString); |
| 896 emitTwoAddress(buf, this, Func); | 953 emitTwoAddress(buf, this, Func); |
| 897 } | 954 } |
| 898 | 955 |
| 899 template <> void InstX8632Psub::emit(const Cfg *Func) const { | 956 template <> void InstX8632Psub::emit(const Cfg *Func) const { |
| (...skipping 457 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1357 void InstX8632Icmp::emit(const Cfg *Func) const { | 1414 void InstX8632Icmp::emit(const Cfg *Func) const { |
| 1358 Ostream &Str = Func->getContext()->getStrEmit(); | 1415 Ostream &Str = Func->getContext()->getStrEmit(); |
| 1359 assert(getSrcSize() == 2); | 1416 assert(getSrcSize() == 2); |
| 1360 Str << "\tcmp\t"; | 1417 Str << "\tcmp\t"; |
| 1361 getSrc(0)->emit(Func); | 1418 getSrc(0)->emit(Func); |
| 1362 Str << ", "; | 1419 Str << ", "; |
| 1363 getSrc(1)->emit(Func); | 1420 getSrc(1)->emit(Func); |
| 1364 Str << "\n"; | 1421 Str << "\n"; |
| 1365 } | 1422 } |
| 1366 | 1423 |
| 1424 void InstX8632Icmp::emitIAS(const Cfg *Func) const { |
| 1425 assert(getSrcSize() == 2); |
| 1426 const Operand *Src0 = getSrc(0); |
| 1427 const Operand *Src1 = getSrc(1); |
| 1428 Type Ty = Src0->getType(); |
| 1429 static const x86::AssemblerX86::GPREmitterRegOp RegEmitter = { |
| 1430 &x86::AssemblerX86::cmp, &x86::AssemblerX86::cmp, |
| 1431 &x86::AssemblerX86::cmp}; |
| 1432 static const x86::AssemblerX86::GPREmitterAddrOp AddrEmitter = { |
| 1433 &x86::AssemblerX86::cmp, &x86::AssemblerX86::cmp}; |
| 1434 if (const Variable *SrcVar0 = llvm::dyn_cast<Variable>(Src0)) { |
| 1435 if (SrcVar0->hasReg()) { |
| 1436 emitIASRegOpTyGPR(Func, Ty, SrcVar0, Src1, RegEmitter); |
| 1437 } else { |
| 1438 x86::Address StackAddr(static_cast<TargetX8632 *>(Func->getTarget()) |
| 1439 ->stackVarToAsmOperand(SrcVar0)); |
| 1440 emitIASAddrOpTyGPR(Func, Ty, StackAddr, Src1, AddrEmitter); |
| 1441 } |
| 1442 } else if (const OperandX8632Mem *SrcMem0 = |
| 1443 llvm::dyn_cast<OperandX8632Mem>(Src0)) { |
| 1444 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); |
| 1445 emitIASAddrOpTyGPR(Func, Ty, SrcMem0->toAsmAddress(Asm), Src1, AddrEmitter); |
| 1446 } |
| 1447 } |
| 1448 |
| 1367 void InstX8632Icmp::dump(const Cfg *Func) const { | 1449 void InstX8632Icmp::dump(const Cfg *Func) const { |
| 1368 Ostream &Str = Func->getContext()->getStrDump(); | 1450 Ostream &Str = Func->getContext()->getStrDump(); |
| 1369 Str << "cmp." << getSrc(0)->getType() << " "; | 1451 Str << "cmp." << getSrc(0)->getType() << " "; |
| 1370 dumpSources(Func); | 1452 dumpSources(Func); |
| 1371 } | 1453 } |
| 1372 | 1454 |
| 1373 void InstX8632Ucomiss::emit(const Cfg *Func) const { | 1455 void InstX8632Ucomiss::emit(const Cfg *Func) const { |
| 1374 Ostream &Str = Func->getContext()->getStrEmit(); | 1456 Ostream &Str = Func->getContext()->getStrEmit(); |
| 1375 assert(getSrcSize() == 2); | 1457 assert(getSrcSize() == 2); |
| 1376 Str << "\tucomi" << TypeX8632Attributes[getSrc(0)->getType()].SdSsString | 1458 Str << "\tucomi" << TypeX8632Attributes[getSrc(0)->getType()].SdSsString |
| 1377 << "\t"; | 1459 << "\t"; |
| 1378 getSrc(0)->emit(Func); | 1460 getSrc(0)->emit(Func); |
| 1379 Str << ", "; | 1461 Str << ", "; |
| 1380 getSrc(1)->emit(Func); | 1462 getSrc(1)->emit(Func); |
| 1381 Str << "\n"; | 1463 Str << "\n"; |
| 1382 } | 1464 } |
| 1383 | 1465 |
| 1384 void InstX8632Ucomiss::emitIAS(const Cfg *Func) const { | 1466 void InstX8632Ucomiss::emitIAS(const Cfg *Func) const { |
| 1385 assert(getSrcSize() == 2); | 1467 assert(getSrcSize() == 2); |
| 1386 // Currently src0 is always a variable by convention, to avoid having | 1468 // Currently src0 is always a variable by convention, to avoid having |
| 1387 // two memory operands. | 1469 // two memory operands. |
| 1388 assert(llvm::isa<Variable>(getSrc(0))); | 1470 assert(llvm::isa<Variable>(getSrc(0))); |
| 1389 const Variable *Src0 = llvm::cast<Variable>(getSrc(0)); | 1471 const Variable *Src0 = llvm::cast<Variable>(getSrc(0)); |
| 1390 Type Ty = Src0->getType(); | 1472 Type Ty = Src0->getType(); |
| 1391 const static x86::AssemblerX86::XmmEmitterTwoOps Emitter = { | 1473 const static x86::AssemblerX86::XmmEmitterRegOp Emitter = { |
| 1392 &x86::AssemblerX86::ucomiss, &x86::AssemblerX86::ucomiss, NULL}; | 1474 &x86::AssemblerX86::ucomiss, &x86::AssemblerX86::ucomiss}; |
| 1393 emitIASVarOperandTyXMM(Func, Ty, Src0, getSrc(1), Emitter); | 1475 emitIASRegOpTyXMM(Func, Ty, Src0, getSrc(1), Emitter); |
| 1394 } | 1476 } |
| 1395 | 1477 |
| 1396 void InstX8632Ucomiss::dump(const Cfg *Func) const { | 1478 void InstX8632Ucomiss::dump(const Cfg *Func) const { |
| 1397 Ostream &Str = Func->getContext()->getStrDump(); | 1479 Ostream &Str = Func->getContext()->getStrDump(); |
| 1398 Str << "ucomiss." << getSrc(0)->getType() << " "; | 1480 Str << "ucomiss." << getSrc(0)->getType() << " "; |
| 1399 dumpSources(Func); | 1481 dumpSources(Func); |
| 1400 } | 1482 } |
| 1401 | 1483 |
| 1402 void InstX8632UD2::emit(const Cfg *Func) const { | 1484 void InstX8632UD2::emit(const Cfg *Func) const { |
| 1403 Ostream &Str = Func->getContext()->getStrEmit(); | 1485 Ostream &Str = Func->getContext()->getStrEmit(); |
| 1404 assert(getSrcSize() == 0); | 1486 assert(getSrcSize() == 0); |
| 1405 Str << "\tud2\n"; | 1487 Str << "\tud2\n"; |
| 1406 } | 1488 } |
| 1407 | 1489 |
| 1490 void InstX8632UD2::emitIAS(const Cfg *Func) const { |
| 1491 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); |
| 1492 intptr_t StartPosition = Asm->GetPosition(); |
| 1493 Asm->ud2(); |
| 1494 Ostream &Str = Func->getContext()->getStrEmit(); |
| 1495 emitIASBytes(Str, Asm, StartPosition); |
| 1496 } |
| 1497 |
| 1408 void InstX8632UD2::dump(const Cfg *Func) const { | 1498 void InstX8632UD2::dump(const Cfg *Func) const { |
| 1409 Ostream &Str = Func->getContext()->getStrDump(); | 1499 Ostream &Str = Func->getContext()->getStrDump(); |
| 1410 Str << "ud2\n"; | 1500 Str << "ud2\n"; |
| 1411 } | 1501 } |
| 1412 | 1502 |
| 1413 void InstX8632Test::emit(const Cfg *Func) const { | 1503 void InstX8632Test::emit(const Cfg *Func) const { |
| 1414 Ostream &Str = Func->getContext()->getStrEmit(); | 1504 Ostream &Str = Func->getContext()->getStrEmit(); |
| 1415 assert(getSrcSize() == 2); | 1505 assert(getSrcSize() == 2); |
| 1416 Str << "\ttest\t"; | 1506 Str << "\ttest\t"; |
| 1417 getSrc(0)->emit(Func); | 1507 getSrc(0)->emit(Func); |
| 1418 Str << ", "; | 1508 Str << ", "; |
| 1419 getSrc(1)->emit(Func); | 1509 getSrc(1)->emit(Func); |
| 1420 Str << "\n"; | 1510 Str << "\n"; |
| 1421 } | 1511 } |
| 1422 | 1512 |
| 1513 void InstX8632Test::emitIAS(const Cfg *Func) const { |
| 1514 assert(getSrcSize() == 2); |
| 1515 const Operand *Src0 = getSrc(0); |
| 1516 const Operand *Src1 = getSrc(1); |
| 1517 Type Ty = Src0->getType(); |
| 1518 // The Reg/Addr form of test is not encodeable. |
| 1519 static const x86::AssemblerX86::GPREmitterRegOp RegEmitter = { |
| 1520 &x86::AssemblerX86::test, NULL, &x86::AssemblerX86::test}; |
| 1521 static const x86::AssemblerX86::GPREmitterAddrOp AddrEmitter = { |
| 1522 &x86::AssemblerX86::test, &x86::AssemblerX86::test}; |
| 1523 if (const Variable *SrcVar0 = llvm::dyn_cast<Variable>(Src0)) { |
| 1524 if (SrcVar0->hasReg()) { |
| 1525 emitIASRegOpTyGPR(Func, Ty, SrcVar0, Src1, RegEmitter); |
| 1526 } else { |
| 1527 llvm_unreachable("Nothing actually generates this so it's untested"); |
| 1528 x86::Address StackAddr(static_cast<TargetX8632 *>(Func->getTarget()) |
| 1529 ->stackVarToAsmOperand(SrcVar0)); |
| 1530 emitIASAddrOpTyGPR(Func, Ty, StackAddr, Src1, AddrEmitter); |
| 1531 } |
| 1532 } else if (const OperandX8632Mem *SrcMem0 = |
| 1533 llvm::dyn_cast<OperandX8632Mem>(Src0)) { |
| 1534 llvm_unreachable("Nothing actually generates this so it's untested"); |
| 1535 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); |
| 1536 emitIASAddrOpTyGPR(Func, Ty, SrcMem0->toAsmAddress(Asm), Src1, AddrEmitter); |
| 1537 } |
| 1538 } |
| 1539 |
| 1423 void InstX8632Test::dump(const Cfg *Func) const { | 1540 void InstX8632Test::dump(const Cfg *Func) const { |
| 1424 Ostream &Str = Func->getContext()->getStrDump(); | 1541 Ostream &Str = Func->getContext()->getStrDump(); |
| 1425 Str << "test." << getSrc(0)->getType() << " "; | 1542 Str << "test." << getSrc(0)->getType() << " "; |
| 1426 dumpSources(Func); | 1543 dumpSources(Func); |
| 1427 } | 1544 } |
| 1428 | 1545 |
| 1429 void InstX8632Mfence::emit(const Cfg *Func) const { | 1546 void InstX8632Mfence::emit(const Cfg *Func) const { |
| 1430 Ostream &Str = Func->getContext()->getStrEmit(); | 1547 Ostream &Str = Func->getContext()->getStrEmit(); |
| 1431 assert(getSrcSize() == 0); | 1548 assert(getSrcSize() == 0); |
| 1432 Str << "\tmfence\n"; | 1549 Str << "\tmfence\n"; |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1467 void InstX8632StoreP::emit(const Cfg *Func) const { | 1584 void InstX8632StoreP::emit(const Cfg *Func) const { |
| 1468 Ostream &Str = Func->getContext()->getStrEmit(); | 1585 Ostream &Str = Func->getContext()->getStrEmit(); |
| 1469 assert(getSrcSize() == 2); | 1586 assert(getSrcSize() == 2); |
| 1470 Str << "\tmovups\t"; | 1587 Str << "\tmovups\t"; |
| 1471 getSrc(1)->emit(Func); | 1588 getSrc(1)->emit(Func); |
| 1472 Str << ", "; | 1589 Str << ", "; |
| 1473 getSrc(0)->emit(Func); | 1590 getSrc(0)->emit(Func); |
| 1474 Str << "\n"; | 1591 Str << "\n"; |
| 1475 } | 1592 } |
| 1476 | 1593 |
| 1594 void InstX8632StoreP::emitIAS(const Cfg *Func) const { |
| 1595 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); |
| 1596 intptr_t StartPosition = Asm->GetPosition(); |
| 1597 assert(getSrcSize() == 2); |
| 1598 const Variable *Src = llvm::cast<Variable>(getSrc(0)); |
| 1599 const OperandX8632Mem *DestMem = llvm::cast<OperandX8632Mem>(getSrc(1)); |
| 1600 assert(Src->hasReg()); |
| 1601 Asm->movups(DestMem->toAsmAddress(Asm), |
| 1602 RegX8632::getEncodedXmm(Src->getRegNum())); |
| 1603 Ostream &Str = Func->getContext()->getStrEmit(); |
| 1604 emitIASBytes(Str, Asm, StartPosition); |
| 1605 } |
| 1606 |
| 1477 void InstX8632StoreP::dump(const Cfg *Func) const { | 1607 void InstX8632StoreP::dump(const Cfg *Func) const { |
| 1478 Ostream &Str = Func->getContext()->getStrDump(); | 1608 Ostream &Str = Func->getContext()->getStrDump(); |
| 1479 Str << "storep." << getSrc(0)->getType() << " "; | 1609 Str << "storep." << getSrc(0)->getType() << " "; |
| 1480 getSrc(1)->dump(Func); | 1610 getSrc(1)->dump(Func); |
| 1481 Str << ", "; | 1611 Str << ", "; |
| 1482 getSrc(0)->dump(Func); | 1612 getSrc(0)->dump(Func); |
| 1483 } | 1613 } |
| 1484 | 1614 |
| 1485 void InstX8632StoreQ::emit(const Cfg *Func) const { | 1615 void InstX8632StoreQ::emit(const Cfg *Func) const { |
| 1486 Ostream &Str = Func->getContext()->getStrEmit(); | 1616 Ostream &Str = Func->getContext()->getStrEmit(); |
| 1487 assert(getSrcSize() == 2); | 1617 assert(getSrcSize() == 2); |
| 1488 assert(getSrc(1)->getType() == IceType_i64 || | 1618 assert(getSrc(1)->getType() == IceType_i64 || |
| 1489 getSrc(1)->getType() == IceType_f64); | 1619 getSrc(1)->getType() == IceType_f64); |
| 1490 Str << "\tmovq\t"; | 1620 Str << "\tmovq\t"; |
| 1491 getSrc(1)->emit(Func); | 1621 getSrc(1)->emit(Func); |
| 1492 Str << ", "; | 1622 Str << ", "; |
| 1493 getSrc(0)->emit(Func); | 1623 getSrc(0)->emit(Func); |
| 1494 Str << "\n"; | 1624 Str << "\n"; |
| 1495 } | 1625 } |
| 1496 | 1626 |
| 1627 void InstX8632StoreQ::emitIAS(const Cfg *Func) const { |
| 1628 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); |
| 1629 intptr_t StartPosition = Asm->GetPosition(); |
| 1630 assert(getSrcSize() == 2); |
| 1631 const Variable *Src = llvm::cast<Variable>(getSrc(0)); |
| 1632 const OperandX8632Mem *DestMem = llvm::cast<OperandX8632Mem>(getSrc(1)); |
| 1633 assert(Src->hasReg()); |
| 1634 Asm->movq(DestMem->toAsmAddress(Asm), |
| 1635 RegX8632::getEncodedXmm(Src->getRegNum())); |
| 1636 Ostream &Str = Func->getContext()->getStrEmit(); |
| 1637 emitIASBytes(Str, Asm, StartPosition); |
| 1638 } |
| 1639 |
| 1497 void InstX8632StoreQ::dump(const Cfg *Func) const { | 1640 void InstX8632StoreQ::dump(const Cfg *Func) const { |
| 1498 Ostream &Str = Func->getContext()->getStrDump(); | 1641 Ostream &Str = Func->getContext()->getStrDump(); |
| 1499 Str << "storeq." << getSrc(0)->getType() << " "; | 1642 Str << "storeq." << getSrc(0)->getType() << " "; |
| 1500 getSrc(1)->dump(Func); | 1643 getSrc(1)->dump(Func); |
| 1501 Str << ", "; | 1644 Str << ", "; |
| 1502 getSrc(0)->dump(Func); | 1645 getSrc(0)->dump(Func); |
| 1503 } | 1646 } |
| 1504 | 1647 |
| 1505 template <> void InstX8632Lea::emit(const Cfg *Func) const { | 1648 template <> void InstX8632Lea::emit(const Cfg *Func) const { |
| 1506 Ostream &Str = Func->getContext()->getStrEmit(); | 1649 Ostream &Str = Func->getContext()->getStrEmit(); |
| (...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1614 // operands. | 1757 // operands. |
| 1615 Ostream &Str = Func->getContext()->getStrEmit(); | 1758 Ostream &Str = Func->getContext()->getStrEmit(); |
| 1616 assert(getSrcSize() == 1); | 1759 assert(getSrcSize() == 1); |
| 1617 Str << "\tmovups\t"; | 1760 Str << "\tmovups\t"; |
| 1618 getDest()->emit(Func); | 1761 getDest()->emit(Func); |
| 1619 Str << ", "; | 1762 Str << ", "; |
| 1620 getSrc(0)->emit(Func); | 1763 getSrc(0)->emit(Func); |
| 1621 Str << "\n"; | 1764 Str << "\n"; |
| 1622 } | 1765 } |
| 1623 | 1766 |
| 1767 template <> void InstX8632Movp::emitIAS(const Cfg *Func) const { |
| 1768 assert(getSrcSize() == 1); |
| 1769 assert(isVectorType(getDest()->getType())); |
| 1770 const Variable *Dest = getDest(); |
| 1771 const Operand *Src = getSrc(0); |
| 1772 const static x86::AssemblerX86::XmmEmitterMovOps Emitter = { |
| 1773 &x86::AssemblerX86::movups, &x86::AssemblerX86::movups, |
| 1774 &x86::AssemblerX86::movups}; |
| 1775 emitIASMovlikeXMM(Func, Dest, Src, Emitter); |
| 1776 } |
| 1777 |
| 1624 template <> void InstX8632Movq::emit(const Cfg *Func) const { | 1778 template <> void InstX8632Movq::emit(const Cfg *Func) const { |
| 1625 Ostream &Str = Func->getContext()->getStrEmit(); | 1779 Ostream &Str = Func->getContext()->getStrEmit(); |
| 1626 assert(getSrcSize() == 1); | 1780 assert(getSrcSize() == 1); |
| 1627 assert(getDest()->getType() == IceType_i64 || | 1781 assert(getDest()->getType() == IceType_i64 || |
| 1628 getDest()->getType() == IceType_f64); | 1782 getDest()->getType() == IceType_f64); |
| 1629 Str << "\tmovq\t"; | 1783 Str << "\tmovq\t"; |
| 1630 getDest()->emit(Func); | 1784 getDest()->emit(Func); |
| 1631 Str << ", "; | 1785 Str << ", "; |
| 1632 getSrc(0)->emit(Func); | 1786 getSrc(0)->emit(Func); |
| 1633 Str << "\n"; | 1787 Str << "\n"; |
| 1634 } | 1788 } |
| 1635 | 1789 |
| 1790 template <> void InstX8632Movq::emitIAS(const Cfg *Func) const { |
| 1791 assert(getSrcSize() == 1); |
| 1792 assert(getDest()->getType() == IceType_i64 || |
| 1793 getDest()->getType() == IceType_f64); |
| 1794 const Variable *Dest = getDest(); |
| 1795 const Operand *Src = getSrc(0); |
| 1796 const static x86::AssemblerX86::XmmEmitterMovOps Emitter = { |
| 1797 &x86::AssemblerX86::movq, &x86::AssemblerX86::movq, |
| 1798 &x86::AssemblerX86::movq}; |
| 1799 emitIASMovlikeXMM(Func, Dest, Src, Emitter); |
| 1800 } |
| 1801 |
| 1802 template <> void InstX8632MovssRegs::emitIAS(const Cfg *Func) const { |
| 1803 // This is Binop variant is only intended to be used for reg-reg moves |
| 1804 // where part of the Dest register is untouched. |
| 1805 assert(getSrcSize() == 2); |
| 1806 const Variable *Dest = getDest(); |
| 1807 assert(Dest == getSrc(0)); |
| 1808 const Variable *Src = llvm::cast<Variable>(getSrc(1)); |
| 1809 assert(Dest->hasReg() && Src->hasReg()); |
| 1810 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); |
| 1811 intptr_t StartPosition = Asm->GetPosition(); |
| 1812 Asm->movss(RegX8632::getEncodedXmm(Dest->getRegNum()), |
| 1813 RegX8632::getEncodedXmm(Src->getRegNum())); |
| 1814 Ostream &Str = Func->getContext()->getStrEmit(); |
| 1815 emitIASBytes(Str, Asm, StartPosition); |
| 1816 } |
| 1817 |
| 1636 void InstX8632Movsx::emit(const Cfg *Func) const { | 1818 void InstX8632Movsx::emit(const Cfg *Func) const { |
| 1637 Ostream &Str = Func->getContext()->getStrEmit(); | 1819 Ostream &Str = Func->getContext()->getStrEmit(); |
| 1638 assert(getSrcSize() == 1); | 1820 assert(getSrcSize() == 1); |
| 1639 Str << "\tmovsx\t"; | 1821 Str << "\tmovsx\t"; |
| 1640 getDest()->emit(Func); | 1822 getDest()->emit(Func); |
| 1641 Str << ", "; | 1823 Str << ", "; |
| 1642 getSrc(0)->emit(Func); | 1824 getSrc(0)->emit(Func); |
| 1643 Str << "\n"; | 1825 Str << "\n"; |
| 1644 } | 1826 } |
| 1645 | 1827 |
| (...skipping 538 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2184 } | 2366 } |
| 2185 Str << "("; | 2367 Str << "("; |
| 2186 if (Func) | 2368 if (Func) |
| 2187 Var->dump(Func); | 2369 Var->dump(Func); |
| 2188 else | 2370 else |
| 2189 Var->dump(Str); | 2371 Var->dump(Str); |
| 2190 Str << ")"; | 2372 Str << ")"; |
| 2191 } | 2373 } |
| 2192 | 2374 |
| 2193 } // end of namespace Ice | 2375 } // end of namespace Ice |
| OLD | NEW |