Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 //===- subzero/src/IceInstX86BaseImpl.h - Generic X86 instructions -*- C++ -*=// | 1 //===- subzero/src/IceInstX86BaseImpl.h - Generic 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 /// \file | 10 /// \file |
| (...skipping 699 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 710 ->stackVarToAsmOperand(SrcVar); | 710 ->stackVarToAsmOperand(SrcVar); |
| 711 (Asm->*(Emitter.GPRAddr))(Ty, VarReg, SrcStackAddr); | 711 (Asm->*(Emitter.GPRAddr))(Ty, VarReg, SrcStackAddr); |
| 712 } | 712 } |
| 713 } else if (const auto Mem = llvm::dyn_cast< | 713 } else if (const auto Mem = llvm::dyn_cast< |
| 714 typename InstX86Base<Machine>::Traits::X86OperandMem>(Src)) { | 714 typename InstX86Base<Machine>::Traits::X86OperandMem>(Src)) { |
| 715 Mem->emitSegmentOverride(Asm); | 715 Mem->emitSegmentOverride(Asm); |
| 716 (Asm->*(Emitter.GPRAddr))(Ty, VarReg, Mem->toAsmAddress(Asm)); | 716 (Asm->*(Emitter.GPRAddr))(Ty, VarReg, Mem->toAsmAddress(Asm)); |
| 717 } else if (const auto Imm = llvm::dyn_cast<ConstantInteger32>(Src)) { | 717 } else if (const auto Imm = llvm::dyn_cast<ConstantInteger32>(Src)) { |
| 718 (Asm->*(Emitter.GPRImm))(Ty, VarReg, Immediate(Imm->getValue())); | 718 (Asm->*(Emitter.GPRImm))(Ty, VarReg, Immediate(Imm->getValue())); |
| 719 } else if (const auto Reloc = llvm::dyn_cast<ConstantRelocatable>(Src)) { | 719 } else if (const auto Reloc = llvm::dyn_cast<ConstantRelocatable>(Src)) { |
| 720 AssemblerFixup *Fixup = Asm->createFixup(llvm::ELF::R_386_32, Reloc); | 720 AssemblerFixup *Fixup = |
| 721 Asm->createFixup(InstX86Base<Machine>::Traits::RelFixup, Reloc); | |
| 721 (Asm->*(Emitter.GPRImm))(Ty, VarReg, Immediate(Reloc->getOffset(), Fixup)); | 722 (Asm->*(Emitter.GPRImm))(Ty, VarReg, Immediate(Reloc->getOffset(), Fixup)); |
| 722 } else if (const auto Split = llvm::dyn_cast< | 723 } else if (const auto Split = llvm::dyn_cast< |
| 723 typename InstX86Base<Machine>::Traits::VariableSplit>(Src)) { | 724 typename InstX86Base<Machine>::Traits::VariableSplit>(Src)) { |
| 724 (Asm->*(Emitter.GPRAddr))(Ty, VarReg, Split->toAsmAddress(Func)); | 725 (Asm->*(Emitter.GPRAddr))(Ty, VarReg, Split->toAsmAddress(Func)); |
| 725 } else { | 726 } else { |
| 726 llvm_unreachable("Unexpected operand type"); | 727 llvm_unreachable("Unexpected operand type"); |
| 727 } | 728 } |
| 728 } | 729 } |
| 729 | 730 |
| 730 template <class Machine> | 731 template <class Machine> |
| 731 void emitIASAddrOpTyGPR( | 732 void emitIASAddrOpTyGPR( |
| 732 const Cfg *Func, Type Ty, | 733 const Cfg *Func, Type Ty, |
| 733 const typename InstX86Base<Machine>::Traits::Address &Addr, | 734 const typename InstX86Base<Machine>::Traits::Address &Addr, |
| 734 const Operand *Src, | 735 const Operand *Src, |
| 735 const typename InstX86Base<Machine>::Traits::Assembler::GPREmitterAddrOp | 736 const typename InstX86Base<Machine>::Traits::Assembler::GPREmitterAddrOp |
| 736 &Emitter) { | 737 &Emitter) { |
| 737 typename InstX86Base<Machine>::Traits::Assembler *Asm = | 738 typename InstX86Base<Machine>::Traits::Assembler *Asm = |
| 738 Func->getAssembler<typename InstX86Base<Machine>::Traits::Assembler>(); | 739 Func->getAssembler<typename InstX86Base<Machine>::Traits::Assembler>(); |
| 739 // Src can only be Reg or Immediate. | 740 // Src can only be Reg or Immediate. |
| 740 if (const auto SrcVar = llvm::dyn_cast<Variable>(Src)) { | 741 if (const auto SrcVar = llvm::dyn_cast<Variable>(Src)) { |
| 741 assert(SrcVar->hasReg()); | 742 assert(SrcVar->hasReg()); |
| 742 typename InstX86Base<Machine>::Traits::RegisterSet::GPRRegister SrcReg = | 743 typename InstX86Base<Machine>::Traits::RegisterSet::GPRRegister SrcReg = |
| 743 InstX86Base<Machine>::Traits::RegisterSet::getEncodedByteRegOrGPR( | 744 InstX86Base<Machine>::Traits::RegisterSet::getEncodedByteRegOrGPR( |
| 744 Ty, SrcVar->getRegNum()); | 745 Ty, SrcVar->getRegNum()); |
| 745 (Asm->*(Emitter.AddrGPR))(Ty, Addr, SrcReg); | 746 (Asm->*(Emitter.AddrGPR))(Ty, Addr, SrcReg); |
| 746 } else if (const auto Imm = llvm::dyn_cast<ConstantInteger32>(Src)) { | 747 } else if (const auto Imm = llvm::dyn_cast<ConstantInteger32>(Src)) { |
| 747 (Asm->*(Emitter.AddrImm))(Ty, Addr, Immediate(Imm->getValue())); | 748 (Asm->*(Emitter.AddrImm))(Ty, Addr, Immediate(Imm->getValue())); |
| 748 } else if (const auto Reloc = llvm::dyn_cast<ConstantRelocatable>(Src)) { | 749 } else if (const auto Reloc = llvm::dyn_cast<ConstantRelocatable>(Src)) { |
| 749 AssemblerFixup *Fixup = Asm->createFixup(llvm::ELF::R_386_32, Reloc); | 750 AssemblerFixup *Fixup = |
| 751 Asm->createFixup(InstX86Base<Machine>::Traits::RelFixup, Reloc); | |
| 750 (Asm->*(Emitter.AddrImm))(Ty, Addr, Immediate(Reloc->getOffset(), Fixup)); | 752 (Asm->*(Emitter.AddrImm))(Ty, Addr, Immediate(Reloc->getOffset(), Fixup)); |
| 751 } else { | 753 } else { |
| 752 llvm_unreachable("Unexpected operand type"); | 754 llvm_unreachable("Unexpected operand type"); |
| 753 } | 755 } |
| 754 } | 756 } |
| 755 | 757 |
| 756 template <class Machine> | 758 template <class Machine> |
| 757 void emitIASAsAddrOpTyGPR( | 759 void emitIASAsAddrOpTyGPR( |
| 758 const Cfg *Func, Type Ty, const Operand *Op0, const Operand *Op1, | 760 const Cfg *Func, Type Ty, const Operand *Op0, const Operand *Op1, |
| 759 const typename InstX86Base<Machine>::Traits::Assembler::GPREmitterAddrOp | 761 const typename InstX86Base<Machine>::Traits::Assembler::GPREmitterAddrOp |
| (...skipping 150 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 910 (Asm->*(Emitter.XmmAddr))( | 912 (Asm->*(Emitter.XmmAddr))( |
| 911 Ty, VarReg, | 913 Ty, VarReg, |
| 912 InstX86Base<Machine>::Traits::Address::ofConstPool(Asm, Imm)); | 914 InstX86Base<Machine>::Traits::Address::ofConstPool(Asm, Imm)); |
| 913 } else { | 915 } else { |
| 914 llvm_unreachable("Unexpected operand type"); | 916 llvm_unreachable("Unexpected operand type"); |
| 915 } | 917 } |
| 916 } | 918 } |
| 917 | 919 |
| 918 template <class Machine, typename DReg_t, typename SReg_t, | 920 template <class Machine, typename DReg_t, typename SReg_t, |
| 919 DReg_t (*destEnc)(int32_t), SReg_t (*srcEnc)(int32_t)> | 921 DReg_t (*destEnc)(int32_t), SReg_t (*srcEnc)(int32_t)> |
| 920 void emitIASCastRegOp(const Cfg *Func, Type DispatchTy, const Variable *Dest, | 922 void emitIASCastRegOp(const Cfg *Func, Type DestTy, const Variable *Dest, |
| 921 const Operand *Src, | 923 Type SrcTy, const Operand *Src, |
| 922 const typename InstX86Base<Machine>::Traits::Assembler:: | 924 const typename InstX86Base<Machine>::Traits::Assembler:: |
| 923 template CastEmitterRegOp<DReg_t, SReg_t> &Emitter) { | 925 template CastEmitterRegOp<DReg_t, SReg_t> &Emitter) { |
| 924 typename InstX86Base<Machine>::Traits::Assembler *Asm = | 926 typename InstX86Base<Machine>::Traits::Assembler *Asm = |
| 925 Func->getAssembler<typename InstX86Base<Machine>::Traits::Assembler>(); | 927 Func->getAssembler<typename InstX86Base<Machine>::Traits::Assembler>(); |
| 926 assert(Dest->hasReg()); | 928 assert(Dest->hasReg()); |
| 927 DReg_t DestReg = destEnc(Dest->getRegNum()); | 929 DReg_t DestReg = destEnc(Dest->getRegNum()); |
| 928 if (const auto SrcVar = llvm::dyn_cast<Variable>(Src)) { | 930 if (const auto SrcVar = llvm::dyn_cast<Variable>(Src)) { |
| 929 if (SrcVar->hasReg()) { | 931 if (SrcVar->hasReg()) { |
| 930 SReg_t SrcReg = srcEnc(SrcVar->getRegNum()); | 932 SReg_t SrcReg = srcEnc(SrcVar->getRegNum()); |
| 931 (Asm->*(Emitter.RegReg))(DispatchTy, DestReg, SrcReg); | 933 (Asm->*(Emitter.RegReg))(DestTy, DestReg, SrcTy, SrcReg); |
| 932 } else { | 934 } else { |
| 933 typename InstX86Base<Machine>::Traits::Address SrcStackAddr = | 935 typename InstX86Base<Machine>::Traits::Address SrcStackAddr = |
| 934 static_cast<typename InstX86Base<Machine>::Traits::TargetLowering *>( | 936 static_cast<typename InstX86Base<Machine>::Traits::TargetLowering *>( |
| 935 Func->getTarget()) | 937 Func->getTarget()) |
| 936 ->stackVarToAsmOperand(SrcVar); | 938 ->stackVarToAsmOperand(SrcVar); |
| 937 (Asm->*(Emitter.RegAddr))(DispatchTy, DestReg, SrcStackAddr); | 939 (Asm->*(Emitter.RegAddr))(DestTy, DestReg, SrcTy, SrcStackAddr); |
| 938 } | 940 } |
| 939 } else if (const auto Mem = llvm::dyn_cast< | 941 } else if (const auto Mem = llvm::dyn_cast< |
| 940 typename InstX86Base<Machine>::Traits::X86OperandMem>(Src)) { | 942 typename InstX86Base<Machine>::Traits::X86OperandMem>(Src)) { |
| 941 Mem->emitSegmentOverride(Asm); | 943 Mem->emitSegmentOverride(Asm); |
| 942 (Asm->*(Emitter.RegAddr))(DispatchTy, DestReg, Mem->toAsmAddress(Asm)); | 944 (Asm->*(Emitter.RegAddr))(DestTy, DestReg, SrcTy, Mem->toAsmAddress(Asm)); |
| 943 } else { | 945 } else { |
| 944 llvm_unreachable("Unexpected operand type"); | 946 llvm_unreachable("Unexpected operand type"); |
| 945 } | 947 } |
| 946 } | 948 } |
| 947 | 949 |
| 948 template <class Machine, typename DReg_t, typename SReg_t, | 950 template <class Machine, typename DReg_t, typename SReg_t, |
| 949 DReg_t (*destEnc)(int32_t), SReg_t (*srcEnc)(int32_t)> | 951 DReg_t (*destEnc)(int32_t), SReg_t (*srcEnc)(int32_t)> |
| 950 void emitIASThreeOpImmOps( | 952 void emitIASThreeOpImmOps( |
| 951 const Cfg *Func, Type DispatchTy, const Variable *Dest, const Operand *Src0, | 953 const Cfg *Func, Type DispatchTy, const Variable *Dest, const Operand *Src0, |
| 952 const Operand *Src1, | 954 const Operand *Src1, |
| (...skipping 427 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1380 case IceType_i16: | 1382 case IceType_i16: |
| 1381 assert(this->getDest()->getRegNum() == | 1383 assert(this->getDest()->getRegNum() == |
| 1382 InstX86Base<Machine>::Traits::RegisterSet::Reg_edx); | 1384 InstX86Base<Machine>::Traits::RegisterSet::Reg_edx); |
| 1383 Str << "\tcwtd"; | 1385 Str << "\tcwtd"; |
| 1384 break; | 1386 break; |
| 1385 case IceType_i32: | 1387 case IceType_i32: |
| 1386 assert(this->getDest()->getRegNum() == | 1388 assert(this->getDest()->getRegNum() == |
| 1387 InstX86Base<Machine>::Traits::RegisterSet::Reg_edx); | 1389 InstX86Base<Machine>::Traits::RegisterSet::Reg_edx); |
| 1388 Str << "\tcltd"; | 1390 Str << "\tcltd"; |
| 1389 break; | 1391 break; |
| 1392 case IceType_i64: | |
| 1393 assert(this->getDest()->getRegNum() == | |
| 1394 InstX86Base<Machine>::Traits::RegisterSet::Reg_edx); | |
| 1395 Str << "\tcdto"; | |
| 1396 break; | |
| 1390 } | 1397 } |
| 1391 } | 1398 } |
| 1392 | 1399 |
| 1393 template <class Machine> | 1400 template <class Machine> |
| 1394 void InstX86Cbwdq<Machine>::emitIAS(const Cfg *Func) const { | 1401 void InstX86Cbwdq<Machine>::emitIAS(const Cfg *Func) const { |
| 1395 typename InstX86Base<Machine>::Traits::Assembler *Asm = | 1402 typename InstX86Base<Machine>::Traits::Assembler *Asm = |
| 1396 Func->getAssembler<typename InstX86Base<Machine>::Traits::Assembler>(); | 1403 Func->getAssembler<typename InstX86Base<Machine>::Traits::Assembler>(); |
| 1397 assert(this->getSrcSize() == 1); | 1404 assert(this->getSrcSize() == 1); |
| 1398 Operand *Src0 = this->getSrc(0); | 1405 Operand *Src0 = this->getSrc(0); |
| 1399 assert(llvm::isa<Variable>(Src0)); | 1406 assert(llvm::isa<Variable>(Src0)); |
| (...skipping 11 matching lines...) Expand all Loading... | |
| 1411 case IceType_i16: | 1418 case IceType_i16: |
| 1412 assert(this->getDest()->getRegNum() == | 1419 assert(this->getDest()->getRegNum() == |
| 1413 InstX86Base<Machine>::Traits::RegisterSet::Reg_edx); | 1420 InstX86Base<Machine>::Traits::RegisterSet::Reg_edx); |
| 1414 Asm->cwd(); | 1421 Asm->cwd(); |
| 1415 break; | 1422 break; |
| 1416 case IceType_i32: | 1423 case IceType_i32: |
| 1417 assert(this->getDest()->getRegNum() == | 1424 assert(this->getDest()->getRegNum() == |
| 1418 InstX86Base<Machine>::Traits::RegisterSet::Reg_edx); | 1425 InstX86Base<Machine>::Traits::RegisterSet::Reg_edx); |
| 1419 Asm->cdq(); | 1426 Asm->cdq(); |
| 1420 break; | 1427 break; |
| 1428 case IceType_i64: | |
| 1429 assert(this->getDest()->getRegNum() == | |
| 1430 InstX86Base<Machine>::Traits::RegisterSet::Reg_edx); | |
| 1431 Asm->cqo(); | |
| 1432 break; | |
| 1421 } | 1433 } |
| 1422 } | 1434 } |
| 1423 | 1435 |
| 1424 template <class Machine> void InstX86Mul<Machine>::emit(const Cfg *Func) const { | 1436 template <class Machine> void InstX86Mul<Machine>::emit(const Cfg *Func) const { |
| 1425 if (!BuildDefs::dump()) | 1437 if (!BuildDefs::dump()) |
| 1426 return; | 1438 return; |
| 1427 Ostream &Str = Func->getContext()->getStrEmit(); | 1439 Ostream &Str = Func->getContext()->getStrEmit(); |
| 1428 assert(this->getSrcSize() == 2); | 1440 assert(this->getSrcSize() == 2); |
| 1429 assert(llvm::isa<Variable>(this->getSrc(0))); | 1441 assert(llvm::isa<Variable>(this->getSrc(0))); |
| 1430 assert(llvm::cast<Variable>(this->getSrc(0))->getRegNum() == | 1442 assert(llvm::cast<Variable>(this->getSrc(0))->getRegNum() == |
| (...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1573 Dest->emit(Func); | 1585 Dest->emit(Func); |
| 1574 } | 1586 } |
| 1575 | 1587 |
| 1576 template <class Machine> | 1588 template <class Machine> |
| 1577 void InstX86Cmov<Machine>::emitIAS(const Cfg *Func) const { | 1589 void InstX86Cmov<Machine>::emitIAS(const Cfg *Func) const { |
| 1578 assert(Condition != InstX86Base<Machine>::Traits::Cond::Br_None); | 1590 assert(Condition != InstX86Base<Machine>::Traits::Cond::Br_None); |
| 1579 assert(this->getDest()->hasReg()); | 1591 assert(this->getDest()->hasReg()); |
| 1580 assert(this->getSrcSize() == 2); | 1592 assert(this->getSrcSize() == 2); |
| 1581 Operand *Src = this->getSrc(1); | 1593 Operand *Src = this->getSrc(1); |
| 1582 Type SrcTy = Src->getType(); | 1594 Type SrcTy = Src->getType(); |
| 1583 assert(SrcTy == IceType_i16 || SrcTy == IceType_i32); | 1595 assert(SrcTy == IceType_i16 || SrcTy == IceType_i32 || |
| 1596 (InstX86Base<Machine>::Traits::Is64Bit)); | |
| 1584 typename InstX86Base<Machine>::Traits::Assembler *Asm = | 1597 typename InstX86Base<Machine>::Traits::Assembler *Asm = |
| 1585 Func->getAssembler<typename InstX86Base<Machine>::Traits::Assembler>(); | 1598 Func->getAssembler<typename InstX86Base<Machine>::Traits::Assembler>(); |
| 1586 if (const auto *SrcVar = llvm::dyn_cast<Variable>(Src)) { | 1599 if (const auto *SrcVar = llvm::dyn_cast<Variable>(Src)) { |
| 1587 if (SrcVar->hasReg()) { | 1600 if (SrcVar->hasReg()) { |
| 1588 Asm->cmov(SrcTy, Condition, | 1601 Asm->cmov(SrcTy, Condition, |
| 1589 InstX86Base<Machine>::Traits::RegisterSet::getEncodedGPR( | 1602 InstX86Base<Machine>::Traits::RegisterSet::getEncodedGPR( |
| 1590 this->getDest()->getRegNum()), | 1603 this->getDest()->getRegNum()), |
| 1591 InstX86Base<Machine>::Traits::RegisterSet::getEncodedGPR( | 1604 InstX86Base<Machine>::Traits::RegisterSet::getEncodedGPR( |
| 1592 SrcVar->getRegNum())); | 1605 SrcVar->getRegNum())); |
| 1593 } else { | 1606 } else { |
| (...skipping 201 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1795 template <class Machine> | 1808 template <class Machine> |
| 1796 void InstX86Cvt<Machine>::emitIAS(const Cfg *Func) const { | 1809 void InstX86Cvt<Machine>::emitIAS(const Cfg *Func) const { |
| 1797 assert(this->getSrcSize() == 1); | 1810 assert(this->getSrcSize() == 1); |
| 1798 const Variable *Dest = this->getDest(); | 1811 const Variable *Dest = this->getDest(); |
| 1799 const Operand *Src = this->getSrc(0); | 1812 const Operand *Src = this->getSrc(0); |
| 1800 Type DestTy = Dest->getType(); | 1813 Type DestTy = Dest->getType(); |
| 1801 Type SrcTy = Src->getType(); | 1814 Type SrcTy = Src->getType(); |
| 1802 switch (Variant) { | 1815 switch (Variant) { |
| 1803 case Si2ss: { | 1816 case Si2ss: { |
| 1804 assert(isScalarIntegerType(SrcTy)); | 1817 assert(isScalarIntegerType(SrcTy)); |
| 1805 assert(typeWidthInBytes(SrcTy) <= 4); | 1818 if (!InstX86Base<Machine>::Traits::Is64Bit) { |
| 1819 assert(typeWidthInBytes(SrcTy) <= 4); | |
| 1820 } else { | |
| 1821 assert(SrcTy == IceType_i32 || SrcTy == IceType_i64); | |
| 1822 } | |
| 1806 assert(isScalarFloatingType(DestTy)); | 1823 assert(isScalarFloatingType(DestTy)); |
| 1807 static const typename InstX86Base<Machine>::Traits::Assembler:: | 1824 static const typename InstX86Base<Machine>::Traits::Assembler:: |
| 1808 template CastEmitterRegOp< | 1825 template CastEmitterRegOp< |
| 1809 typename InstX86Base<Machine>::Traits::RegisterSet::XmmRegister, | 1826 typename InstX86Base<Machine>::Traits::RegisterSet::XmmRegister, |
| 1810 typename InstX86Base<Machine>::Traits::RegisterSet::GPRRegister> | 1827 typename InstX86Base<Machine>::Traits::RegisterSet::GPRRegister> |
| 1811 Emitter = {&InstX86Base<Machine>::Traits::Assembler::cvtsi2ss, | 1828 Emitter = {&InstX86Base<Machine>::Traits::Assembler::cvtsi2ss, |
| 1812 &InstX86Base<Machine>::Traits::Assembler::cvtsi2ss}; | 1829 &InstX86Base<Machine>::Traits::Assembler::cvtsi2ss}; |
| 1813 emitIASCastRegOp< | 1830 emitIASCastRegOp< |
| 1814 Machine, | 1831 Machine, |
| 1815 typename InstX86Base<Machine>::Traits::RegisterSet::XmmRegister, | 1832 typename InstX86Base<Machine>::Traits::RegisterSet::XmmRegister, |
| 1816 typename InstX86Base<Machine>::Traits::RegisterSet::GPRRegister, | 1833 typename InstX86Base<Machine>::Traits::RegisterSet::GPRRegister, |
| 1817 InstX86Base<Machine>::Traits::RegisterSet::getEncodedXmm, | 1834 InstX86Base<Machine>::Traits::RegisterSet::getEncodedXmm, |
| 1818 InstX86Base<Machine>::Traits::RegisterSet::getEncodedGPR>( | 1835 InstX86Base<Machine>::Traits::RegisterSet::getEncodedGPR>( |
| 1819 Func, DestTy, Dest, Src, Emitter); | 1836 Func, DestTy, Dest, SrcTy, Src, Emitter); |
| 1820 return; | 1837 return; |
| 1821 } | 1838 } |
| 1822 case Tss2si: { | 1839 case Tss2si: { |
| 1823 assert(isScalarFloatingType(SrcTy)); | 1840 assert(isScalarFloatingType(SrcTy)); |
| 1824 assert(isScalarIntegerType(DestTy)); | 1841 assert(isScalarIntegerType(DestTy)); |
| 1825 assert(typeWidthInBytes(DestTy) <= 4); | 1842 if (!InstX86Base<Machine>::Traits::Is64Bit) { |
| 1843 assert(typeWidthInBytes(DestTy) <= 4); | |
| 1844 } else { | |
| 1845 assert(DestTy == IceType_i32 || DestTy == IceType_i64); | |
| 1846 } | |
| 1826 static const typename InstX86Base<Machine>::Traits::Assembler:: | 1847 static const typename InstX86Base<Machine>::Traits::Assembler:: |
| 1827 template CastEmitterRegOp< | 1848 template CastEmitterRegOp< |
| 1828 typename InstX86Base<Machine>::Traits::RegisterSet::GPRRegister, | 1849 typename InstX86Base<Machine>::Traits::RegisterSet::GPRRegister, |
| 1829 typename InstX86Base<Machine>::Traits::RegisterSet::XmmRegister> | 1850 typename InstX86Base<Machine>::Traits::RegisterSet::XmmRegister> |
| 1830 Emitter = {&InstX86Base<Machine>::Traits::Assembler::cvttss2si, | 1851 Emitter = {&InstX86Base<Machine>::Traits::Assembler::cvttss2si, |
| 1831 &InstX86Base<Machine>::Traits::Assembler::cvttss2si}; | 1852 &InstX86Base<Machine>::Traits::Assembler::cvttss2si}; |
| 1832 emitIASCastRegOp< | 1853 emitIASCastRegOp< |
| 1833 Machine, | 1854 Machine, |
| 1834 typename InstX86Base<Machine>::Traits::RegisterSet::GPRRegister, | 1855 typename InstX86Base<Machine>::Traits::RegisterSet::GPRRegister, |
| 1835 typename InstX86Base<Machine>::Traits::RegisterSet::XmmRegister, | 1856 typename InstX86Base<Machine>::Traits::RegisterSet::XmmRegister, |
| 1836 InstX86Base<Machine>::Traits::RegisterSet::getEncodedGPR, | 1857 InstX86Base<Machine>::Traits::RegisterSet::getEncodedGPR, |
| 1837 InstX86Base<Machine>::Traits::RegisterSet::getEncodedXmm>( | 1858 InstX86Base<Machine>::Traits::RegisterSet::getEncodedXmm>( |
| 1838 Func, SrcTy, Dest, Src, Emitter); | 1859 Func, DestTy, Dest, SrcTy, Src, Emitter); |
| 1839 return; | 1860 return; |
| 1840 } | 1861 } |
| 1841 case Float2float: { | 1862 case Float2float: { |
| 1842 assert(isScalarFloatingType(SrcTy)); | 1863 assert(isScalarFloatingType(SrcTy)); |
| 1843 assert(isScalarFloatingType(DestTy)); | 1864 assert(isScalarFloatingType(DestTy)); |
| 1844 assert(DestTy != SrcTy); | 1865 assert(DestTy != SrcTy); |
| 1845 static const typename InstX86Base< | 1866 static const typename InstX86Base< |
| 1846 Machine>::Traits::Assembler::XmmEmitterRegOp Emitter = { | 1867 Machine>::Traits::Assembler::XmmEmitterRegOp Emitter = { |
| 1847 &InstX86Base<Machine>::Traits::Assembler::cvtfloat2float, | 1868 &InstX86Base<Machine>::Traits::Assembler::cvtfloat2float, |
| 1848 &InstX86Base<Machine>::Traits::Assembler::cvtfloat2float}; | 1869 &InstX86Base<Machine>::Traits::Assembler::cvtfloat2float}; |
| (...skipping 376 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2225 // lea on x86-32 doesn't accept mem128 operands, so cast VSrc0 to an | 2246 // lea on x86-32 doesn't accept mem128 operands, so cast VSrc0 to an |
| 2226 // acceptable type. | 2247 // acceptable type. |
| 2227 Src0Var->asType(isVectorType(Ty) ? IceType_i32 : Ty)->emit(Func); | 2248 Src0Var->asType(isVectorType(Ty) ? IceType_i32 : Ty)->emit(Func); |
| 2228 } else { | 2249 } else { |
| 2229 Src0->emit(Func); | 2250 Src0->emit(Func); |
| 2230 } | 2251 } |
| 2231 Str << ", "; | 2252 Str << ", "; |
| 2232 this->getDest()->emit(Func); | 2253 this->getDest()->emit(Func); |
| 2233 } | 2254 } |
| 2234 | 2255 |
| 2256 inline bool isIntegerConstant(const Operand *Op) { | |
| 2257 return llvm::dyn_cast<ConstantInteger32>(Op) != nullptr || | |
|
Jim Stichnoth
2015/08/10 16:08:04
Use isa<> instead of dyn_cast<> .
John
2015/08/10 20:41:17
Done.
| |
| 2258 llvm::dyn_cast<ConstantInteger64>(Op) != nullptr; | |
| 2259 } | |
| 2260 | |
| 2235 template <class Machine> void InstX86Mov<Machine>::emit(const Cfg *Func) const { | 2261 template <class Machine> void InstX86Mov<Machine>::emit(const Cfg *Func) const { |
| 2236 if (!BuildDefs::dump()) | 2262 if (!BuildDefs::dump()) |
| 2237 return; | 2263 return; |
| 2238 Ostream &Str = Func->getContext()->getStrEmit(); | 2264 Ostream &Str = Func->getContext()->getStrEmit(); |
| 2239 assert(this->getSrcSize() == 1); | 2265 assert(this->getSrcSize() == 1); |
| 2240 Operand *Src = this->getSrc(0); | 2266 Operand *Src = this->getSrc(0); |
| 2241 Type SrcTy = Src->getType(); | 2267 Type SrcTy = Src->getType(); |
| 2242 Type DestTy = this->getDest()->getType(); | 2268 Type DestTy = this->getDest()->getType(); |
| 2243 Str << "\tmov" | 2269 if (InstX86Base<Machine>::Traits::Is64Bit && DestTy == IceType_i64 && |
| 2244 << (!isScalarFloatingType(DestTy) | 2270 isIntegerConstant(Src)) { |
| 2245 ? this->getWidthString(SrcTy) | 2271 Str << "\tmovabs\t"; |
| 2246 : InstX86Base<Machine>::Traits::TypeAttributes[DestTy].SdSsString) | 2272 } else { |
| 2247 << "\t"; | 2273 Str << "\tmov" |
| 2274 << (!isScalarFloatingType(DestTy) | |
| 2275 ? this->getWidthString(SrcTy) | |
| 2276 : InstX86Base<Machine>::Traits::TypeAttributes[DestTy] | |
| 2277 .SdSsString) << "\t"; | |
| 2278 } | |
| 2248 // For an integer truncation operation, src is wider than dest. | 2279 // For an integer truncation operation, src is wider than dest. |
| 2249 // Ideally, we use a mov instruction whose data width matches the | 2280 // Ideally, we use a mov instruction whose data width matches the |
| 2250 // narrower dest. This is a problem if e.g. src is a register like | 2281 // narrower dest. This is a problem if e.g. src is a register like |
| 2251 // esi or si where there is no 8-bit version of the register. To be | 2282 // esi or si where there is no 8-bit version of the register. To be |
| 2252 // safe, we instead widen the dest to match src. This works even | 2283 // safe, we instead widen the dest to match src. This works even |
| 2253 // for stack-allocated dest variables because typeWidthOnStack() | 2284 // for stack-allocated dest variables because typeWidthOnStack() |
| 2254 // pads to a 4-byte boundary even if only a lower portion is used. | 2285 // pads to a 4-byte boundary even if only a lower portion is used. |
| 2255 // TODO: This assert disallows usages such as copying a floating point | 2286 // TODO: This assert disallows usages such as copying a floating point |
| 2256 // value between a vector and a scalar (which movss is used for). | 2287 // value between a vector and a scalar (which movss is used for). |
| 2257 // Clean this up. | 2288 // Clean this up. |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2301 Func->getTarget()->typeWidthInBytesOnStack(this->getDest()->getType()) == | 2332 Func->getTarget()->typeWidthInBytesOnStack(this->getDest()->getType()) == |
| 2302 Func->getTarget()->typeWidthInBytesOnStack(Src->getType())); | 2333 Func->getTarget()->typeWidthInBytesOnStack(Src->getType())); |
| 2303 if (Dest->hasReg()) { | 2334 if (Dest->hasReg()) { |
| 2304 if (isScalarFloatingType(DestTy)) { | 2335 if (isScalarFloatingType(DestTy)) { |
| 2305 emitIASRegOpTyXMM<Machine>(Func, DestTy, Dest, Src, XmmRegEmitter); | 2336 emitIASRegOpTyXMM<Machine>(Func, DestTy, Dest, Src, XmmRegEmitter); |
| 2306 return; | 2337 return; |
| 2307 } else { | 2338 } else { |
| 2308 assert(isScalarIntegerType(DestTy)); | 2339 assert(isScalarIntegerType(DestTy)); |
| 2309 // Widen DestTy for truncation (see above note). We should only do this | 2340 // Widen DestTy for truncation (see above note). We should only do this |
| 2310 // when both Src and Dest are integer types. | 2341 // when both Src and Dest are integer types. |
| 2342 if (InstX86Base<Machine>::Traits::Is64Bit && DestTy == IceType_i64 && | |
| 2343 isIntegerConstant(Src)) { | |
| 2344 uint64_t value = -1; | |
| 2345 if (const auto *C64 = llvm::dyn_cast<ConstantInteger64>(Src)) { | |
| 2346 value = C64->getValue(); | |
| 2347 } else { | |
| 2348 const auto *C32 = llvm::dyn_cast<ConstantInteger32>(Src); | |
|
Jim Stichnoth
2015/08/10 16:08:04
Can probably use llvm::cast<> which would do the a
John
2015/08/10 20:41:17
Done.
| |
| 2349 assert(C32 != nullptr); | |
| 2350 value = C32->getValue(); | |
| 2351 } | |
| 2352 Func->getAssembler<typename InstX86Base<Machine>::Traits::Assembler>() | |
| 2353 ->movabs(InstX86Base<Machine>::Traits::RegisterSet::getEncodedGPR( | |
| 2354 Dest->getRegNum()), | |
| 2355 value); | |
| 2356 return; | |
| 2357 } | |
| 2311 if (isScalarIntegerType(SrcTy)) { | 2358 if (isScalarIntegerType(SrcTy)) { |
| 2312 DestTy = SrcTy; | 2359 DestTy = SrcTy; |
| 2313 } | 2360 } |
| 2314 emitIASRegOpTyGPR<Machine>(Func, DestTy, Dest, Src, GPRRegEmitter); | 2361 emitIASRegOpTyGPR<Machine>(Func, DestTy, Dest, Src, GPRRegEmitter); |
| 2315 return; | 2362 return; |
| 2316 } | 2363 } |
| 2317 } else { | 2364 } else { |
| 2318 // Dest must be Stack and Src *could* be a register. Use Src's type | 2365 // Dest must be Stack and Src *could* be a register. Use Src's type |
| 2319 // to decide on the emitters. | 2366 // to decide on the emitters. |
| 2320 typename InstX86Base<Machine>::Traits::Address StackAddr( | 2367 typename InstX86Base<Machine>::Traits::Address StackAddr( |
| (...skipping 23 matching lines...) Expand all Loading... | |
| 2344 | 2391 |
| 2345 template <class Machine> | 2392 template <class Machine> |
| 2346 void InstX86Movd<Machine>::emitIAS(const Cfg *Func) const { | 2393 void InstX86Movd<Machine>::emitIAS(const Cfg *Func) const { |
| 2347 typename InstX86Base<Machine>::Traits::Assembler *Asm = | 2394 typename InstX86Base<Machine>::Traits::Assembler *Asm = |
| 2348 Func->getAssembler<typename InstX86Base<Machine>::Traits::Assembler>(); | 2395 Func->getAssembler<typename InstX86Base<Machine>::Traits::Assembler>(); |
| 2349 assert(this->getSrcSize() == 1); | 2396 assert(this->getSrcSize() == 1); |
| 2350 const Variable *Dest = this->getDest(); | 2397 const Variable *Dest = this->getDest(); |
| 2351 const auto SrcVar = llvm::cast<Variable>(this->getSrc(0)); | 2398 const auto SrcVar = llvm::cast<Variable>(this->getSrc(0)); |
| 2352 // For insert/extract element (one of Src/Dest is an Xmm vector and | 2399 // For insert/extract element (one of Src/Dest is an Xmm vector and |
| 2353 // the other is an int type). | 2400 // the other is an int type). |
| 2354 if (SrcVar->getType() == IceType_i32) { | 2401 if (SrcVar->getType() == IceType_i32 || |
| 2355 assert(isVectorType(Dest->getType())); | 2402 (InstX86Base<Machine>::Traits::Is64Bit && |
| 2403 SrcVar->getType() == IceType_i64)) { | |
| 2404 assert(isVectorType(Dest->getType()) || | |
| 2405 (isScalarFloatingType(Dest->getType()) && | |
| 2406 typeWidthInBytes(SrcVar->getType()) == | |
| 2407 typeWidthInBytes(Dest->getType()))); | |
| 2356 assert(Dest->hasReg()); | 2408 assert(Dest->hasReg()); |
| 2357 typename InstX86Base<Machine>::Traits::RegisterSet::XmmRegister DestReg = | 2409 typename InstX86Base<Machine>::Traits::RegisterSet::XmmRegister DestReg = |
| 2358 InstX86Base<Machine>::Traits::RegisterSet::getEncodedXmm( | 2410 InstX86Base<Machine>::Traits::RegisterSet::getEncodedXmm( |
| 2359 Dest->getRegNum()); | 2411 Dest->getRegNum()); |
| 2360 if (SrcVar->hasReg()) { | 2412 if (SrcVar->hasReg()) { |
| 2361 Asm->movd(DestReg, | 2413 Asm->movd(SrcVar->getType(), DestReg, |
| 2362 InstX86Base<Machine>::Traits::RegisterSet::getEncodedGPR( | 2414 InstX86Base<Machine>::Traits::RegisterSet::getEncodedGPR( |
| 2363 SrcVar->getRegNum())); | 2415 SrcVar->getRegNum())); |
| 2364 } else { | 2416 } else { |
| 2365 typename InstX86Base<Machine>::Traits::Address StackAddr( | 2417 typename InstX86Base<Machine>::Traits::Address StackAddr( |
| 2366 static_cast<typename InstX86Base<Machine>::Traits::TargetLowering *>( | 2418 static_cast<typename InstX86Base<Machine>::Traits::TargetLowering *>( |
| 2367 Func->getTarget()) | 2419 Func->getTarget()) |
| 2368 ->stackVarToAsmOperand(SrcVar)); | 2420 ->stackVarToAsmOperand(SrcVar)); |
| 2369 Asm->movd(DestReg, StackAddr); | 2421 Asm->movd(SrcVar->getType(), DestReg, StackAddr); |
| 2370 } | 2422 } |
| 2371 } else { | 2423 } else { |
| 2372 assert(isVectorType(SrcVar->getType())); | 2424 assert(isVectorType(SrcVar->getType()) || |
| 2425 (isScalarFloatingType(SrcVar->getType()) && | |
| 2426 typeWidthInBytes(SrcVar->getType()) == | |
| 2427 typeWidthInBytes(Dest->getType()))); | |
| 2373 assert(SrcVar->hasReg()); | 2428 assert(SrcVar->hasReg()); |
| 2374 assert(Dest->getType() == IceType_i32); | 2429 assert(Dest->getType() == IceType_i32 || |
| 2430 (InstX86Base<Machine>::Traits::Is64Bit && | |
| 2431 Dest->getType() == IceType_i64)); | |
| 2375 typename InstX86Base<Machine>::Traits::RegisterSet::XmmRegister SrcReg = | 2432 typename InstX86Base<Machine>::Traits::RegisterSet::XmmRegister SrcReg = |
| 2376 InstX86Base<Machine>::Traits::RegisterSet::getEncodedXmm( | 2433 InstX86Base<Machine>::Traits::RegisterSet::getEncodedXmm( |
| 2377 SrcVar->getRegNum()); | 2434 SrcVar->getRegNum()); |
| 2378 if (Dest->hasReg()) { | 2435 if (Dest->hasReg()) { |
| 2379 Asm->movd(InstX86Base<Machine>::Traits::RegisterSet::getEncodedGPR( | 2436 Asm->movd(Dest->getType(), |
| 2437 InstX86Base<Machine>::Traits::RegisterSet::getEncodedGPR( | |
| 2380 Dest->getRegNum()), | 2438 Dest->getRegNum()), |
| 2381 SrcReg); | 2439 SrcReg); |
| 2382 } else { | 2440 } else { |
| 2383 typename InstX86Base<Machine>::Traits::Address StackAddr( | 2441 typename InstX86Base<Machine>::Traits::Address StackAddr( |
| 2384 static_cast<typename InstX86Base<Machine>::Traits::TargetLowering *>( | 2442 static_cast<typename InstX86Base<Machine>::Traits::TargetLowering *>( |
| 2385 Func->getTarget()) | 2443 Func->getTarget()) |
| 2386 ->stackVarToAsmOperand(Dest)); | 2444 ->stackVarToAsmOperand(Dest)); |
| 2387 Asm->movd(StackAddr, SrcReg); | 2445 Asm->movd(Dest->getType(), StackAddr, SrcReg); |
| 2388 } | 2446 } |
| 2389 } | 2447 } |
| 2390 } | 2448 } |
| 2391 | 2449 |
| 2392 template <class Machine> | 2450 template <class Machine> |
| 2393 void InstX86Movp<Machine>::emit(const Cfg *Func) const { | 2451 void InstX86Movp<Machine>::emit(const Cfg *Func) const { |
| 2394 if (!BuildDefs::dump()) | 2452 if (!BuildDefs::dump()) |
| 2395 return; | 2453 return; |
| 2396 // TODO(wala,stichnot): movups works with all vector operands, but | 2454 // TODO(wala,stichnot): movups works with all vector operands, but |
| 2397 // there exist other instructions (movaps, movdqa, movdqu) that may | 2455 // there exist other instructions (movaps, movdqa, movdqu) that may |
| (...skipping 756 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3154 Type Ty = this->getSrc(0)->getType(); | 3212 Type Ty = this->getSrc(0)->getType(); |
| 3155 Str << "xchg." << Ty << " "; | 3213 Str << "xchg." << Ty << " "; |
| 3156 this->dumpSources(Func); | 3214 this->dumpSources(Func); |
| 3157 } | 3215 } |
| 3158 | 3216 |
| 3159 } // end of namespace X86Internal | 3217 } // end of namespace X86Internal |
| 3160 | 3218 |
| 3161 } // end of namespace Ice | 3219 } // end of namespace Ice |
| 3162 | 3220 |
| 3163 #endif // SUBZERO_SRC_ICEINSTX86BASEIMPL_H | 3221 #endif // SUBZERO_SRC_ICEINSTX86BASEIMPL_H |
| OLD | NEW |