| 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 415 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1368 assert(llvm::isa<Variable>(Src0)); | 1370 assert(llvm::isa<Variable>(Src0)); |
| 1369 assert(llvm::cast<Variable>(Src0)->getRegNum() == | 1371 assert(llvm::cast<Variable>(Src0)->getRegNum() == |
| 1370 InstX86Base<Machine>::Traits::RegisterSet::Reg_eax); | 1372 InstX86Base<Machine>::Traits::RegisterSet::Reg_eax); |
| 1371 switch (Src0->getType()) { | 1373 switch (Src0->getType()) { |
| 1372 default: | 1374 default: |
| 1373 llvm_unreachable("unexpected source type!"); | 1375 llvm_unreachable("unexpected source type!"); |
| 1374 break; | 1376 break; |
| 1375 case IceType_i8: | 1377 case IceType_i8: |
| 1376 assert(this->getDest()->getRegNum() == | 1378 assert(this->getDest()->getRegNum() == |
| 1377 InstX86Base<Machine>::Traits::RegisterSet::Reg_eax); | 1379 InstX86Base<Machine>::Traits::RegisterSet::Reg_eax); |
| 1378 Str << "\tcbtw"; | 1380 Str << "\t" |
| 1381 << "cbtw"; |
| 1379 break; | 1382 break; |
| 1380 case IceType_i16: | 1383 case IceType_i16: |
| 1381 assert(this->getDest()->getRegNum() == | 1384 assert(this->getDest()->getRegNum() == |
| 1382 InstX86Base<Machine>::Traits::RegisterSet::Reg_edx); | 1385 InstX86Base<Machine>::Traits::RegisterSet::Reg_edx); |
| 1383 Str << "\tcwtd"; | 1386 Str << "\t" |
| 1387 << "cwtd"; |
| 1384 break; | 1388 break; |
| 1385 case IceType_i32: | 1389 case IceType_i32: |
| 1386 assert(this->getDest()->getRegNum() == | 1390 assert(this->getDest()->getRegNum() == |
| 1387 InstX86Base<Machine>::Traits::RegisterSet::Reg_edx); | 1391 InstX86Base<Machine>::Traits::RegisterSet::Reg_edx); |
| 1388 Str << "\tcltd"; | 1392 Str << "\t" |
| 1393 << "cltd"; |
| 1394 break; |
| 1395 case IceType_i64: |
| 1396 assert(this->getDest()->getRegNum() == |
| 1397 InstX86Base<Machine>::Traits::RegisterSet::Reg_edx); |
| 1398 Str << "\t" |
| 1399 << "cdto"; |
| 1389 break; | 1400 break; |
| 1390 } | 1401 } |
| 1391 } | 1402 } |
| 1392 | 1403 |
| 1393 template <class Machine> | 1404 template <class Machine> |
| 1394 void InstX86Cbwdq<Machine>::emitIAS(const Cfg *Func) const { | 1405 void InstX86Cbwdq<Machine>::emitIAS(const Cfg *Func) const { |
| 1395 typename InstX86Base<Machine>::Traits::Assembler *Asm = | 1406 typename InstX86Base<Machine>::Traits::Assembler *Asm = |
| 1396 Func->getAssembler<typename InstX86Base<Machine>::Traits::Assembler>(); | 1407 Func->getAssembler<typename InstX86Base<Machine>::Traits::Assembler>(); |
| 1397 assert(this->getSrcSize() == 1); | 1408 assert(this->getSrcSize() == 1); |
| 1398 Operand *Src0 = this->getSrc(0); | 1409 Operand *Src0 = this->getSrc(0); |
| (...skipping 12 matching lines...) Expand all Loading... |
| 1411 case IceType_i16: | 1422 case IceType_i16: |
| 1412 assert(this->getDest()->getRegNum() == | 1423 assert(this->getDest()->getRegNum() == |
| 1413 InstX86Base<Machine>::Traits::RegisterSet::Reg_edx); | 1424 InstX86Base<Machine>::Traits::RegisterSet::Reg_edx); |
| 1414 Asm->cwd(); | 1425 Asm->cwd(); |
| 1415 break; | 1426 break; |
| 1416 case IceType_i32: | 1427 case IceType_i32: |
| 1417 assert(this->getDest()->getRegNum() == | 1428 assert(this->getDest()->getRegNum() == |
| 1418 InstX86Base<Machine>::Traits::RegisterSet::Reg_edx); | 1429 InstX86Base<Machine>::Traits::RegisterSet::Reg_edx); |
| 1419 Asm->cdq(); | 1430 Asm->cdq(); |
| 1420 break; | 1431 break; |
| 1432 case IceType_i64: |
| 1433 assert(this->getDest()->getRegNum() == |
| 1434 InstX86Base<Machine>::Traits::RegisterSet::Reg_edx); |
| 1435 Asm->cqo(); |
| 1436 break; |
| 1421 } | 1437 } |
| 1422 } | 1438 } |
| 1423 | 1439 |
| 1424 template <class Machine> void InstX86Mul<Machine>::emit(const Cfg *Func) const { | 1440 template <class Machine> void InstX86Mul<Machine>::emit(const Cfg *Func) const { |
| 1425 if (!BuildDefs::dump()) | 1441 if (!BuildDefs::dump()) |
| 1426 return; | 1442 return; |
| 1427 Ostream &Str = Func->getContext()->getStrEmit(); | 1443 Ostream &Str = Func->getContext()->getStrEmit(); |
| 1428 assert(this->getSrcSize() == 2); | 1444 assert(this->getSrcSize() == 2); |
| 1429 assert(llvm::isa<Variable>(this->getSrc(0))); | 1445 assert(llvm::isa<Variable>(this->getSrc(0))); |
| 1430 assert(llvm::cast<Variable>(this->getSrc(0))->getRegNum() == | 1446 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); | 1589 Dest->emit(Func); |
| 1574 } | 1590 } |
| 1575 | 1591 |
| 1576 template <class Machine> | 1592 template <class Machine> |
| 1577 void InstX86Cmov<Machine>::emitIAS(const Cfg *Func) const { | 1593 void InstX86Cmov<Machine>::emitIAS(const Cfg *Func) const { |
| 1578 assert(Condition != InstX86Base<Machine>::Traits::Cond::Br_None); | 1594 assert(Condition != InstX86Base<Machine>::Traits::Cond::Br_None); |
| 1579 assert(this->getDest()->hasReg()); | 1595 assert(this->getDest()->hasReg()); |
| 1580 assert(this->getSrcSize() == 2); | 1596 assert(this->getSrcSize() == 2); |
| 1581 Operand *Src = this->getSrc(1); | 1597 Operand *Src = this->getSrc(1); |
| 1582 Type SrcTy = Src->getType(); | 1598 Type SrcTy = Src->getType(); |
| 1583 assert(SrcTy == IceType_i16 || SrcTy == IceType_i32); | 1599 assert(SrcTy == IceType_i16 || SrcTy == IceType_i32 || |
| 1600 (InstX86Base<Machine>::Traits::Is64Bit)); |
| 1584 typename InstX86Base<Machine>::Traits::Assembler *Asm = | 1601 typename InstX86Base<Machine>::Traits::Assembler *Asm = |
| 1585 Func->getAssembler<typename InstX86Base<Machine>::Traits::Assembler>(); | 1602 Func->getAssembler<typename InstX86Base<Machine>::Traits::Assembler>(); |
| 1586 if (const auto *SrcVar = llvm::dyn_cast<Variable>(Src)) { | 1603 if (const auto *SrcVar = llvm::dyn_cast<Variable>(Src)) { |
| 1587 if (SrcVar->hasReg()) { | 1604 if (SrcVar->hasReg()) { |
| 1588 Asm->cmov(SrcTy, Condition, | 1605 Asm->cmov(SrcTy, Condition, |
| 1589 InstX86Base<Machine>::Traits::RegisterSet::getEncodedGPR( | 1606 InstX86Base<Machine>::Traits::RegisterSet::getEncodedGPR( |
| 1590 this->getDest()->getRegNum()), | 1607 this->getDest()->getRegNum()), |
| 1591 InstX86Base<Machine>::Traits::RegisterSet::getEncodedGPR( | 1608 InstX86Base<Machine>::Traits::RegisterSet::getEncodedGPR( |
| 1592 SrcVar->getRegNum())); | 1609 SrcVar->getRegNum())); |
| 1593 } else { | 1610 } else { |
| (...skipping 201 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1795 template <class Machine> | 1812 template <class Machine> |
| 1796 void InstX86Cvt<Machine>::emitIAS(const Cfg *Func) const { | 1813 void InstX86Cvt<Machine>::emitIAS(const Cfg *Func) const { |
| 1797 assert(this->getSrcSize() == 1); | 1814 assert(this->getSrcSize() == 1); |
| 1798 const Variable *Dest = this->getDest(); | 1815 const Variable *Dest = this->getDest(); |
| 1799 const Operand *Src = this->getSrc(0); | 1816 const Operand *Src = this->getSrc(0); |
| 1800 Type DestTy = Dest->getType(); | 1817 Type DestTy = Dest->getType(); |
| 1801 Type SrcTy = Src->getType(); | 1818 Type SrcTy = Src->getType(); |
| 1802 switch (Variant) { | 1819 switch (Variant) { |
| 1803 case Si2ss: { | 1820 case Si2ss: { |
| 1804 assert(isScalarIntegerType(SrcTy)); | 1821 assert(isScalarIntegerType(SrcTy)); |
| 1805 assert(typeWidthInBytes(SrcTy) <= 4); | 1822 if (!InstX86Base<Machine>::Traits::Is64Bit) { |
| 1823 assert(typeWidthInBytes(SrcTy) <= 4); |
| 1824 } else { |
| 1825 assert(SrcTy == IceType_i32 || SrcTy == IceType_i64); |
| 1826 } |
| 1806 assert(isScalarFloatingType(DestTy)); | 1827 assert(isScalarFloatingType(DestTy)); |
| 1807 static const typename InstX86Base<Machine>::Traits::Assembler:: | 1828 static const typename InstX86Base<Machine>::Traits::Assembler:: |
| 1808 template CastEmitterRegOp< | 1829 template CastEmitterRegOp< |
| 1809 typename InstX86Base<Machine>::Traits::RegisterSet::XmmRegister, | 1830 typename InstX86Base<Machine>::Traits::RegisterSet::XmmRegister, |
| 1810 typename InstX86Base<Machine>::Traits::RegisterSet::GPRRegister> | 1831 typename InstX86Base<Machine>::Traits::RegisterSet::GPRRegister> |
| 1811 Emitter = {&InstX86Base<Machine>::Traits::Assembler::cvtsi2ss, | 1832 Emitter = {&InstX86Base<Machine>::Traits::Assembler::cvtsi2ss, |
| 1812 &InstX86Base<Machine>::Traits::Assembler::cvtsi2ss}; | 1833 &InstX86Base<Machine>::Traits::Assembler::cvtsi2ss}; |
| 1813 emitIASCastRegOp< | 1834 emitIASCastRegOp< |
| 1814 Machine, | 1835 Machine, |
| 1815 typename InstX86Base<Machine>::Traits::RegisterSet::XmmRegister, | 1836 typename InstX86Base<Machine>::Traits::RegisterSet::XmmRegister, |
| 1816 typename InstX86Base<Machine>::Traits::RegisterSet::GPRRegister, | 1837 typename InstX86Base<Machine>::Traits::RegisterSet::GPRRegister, |
| 1817 InstX86Base<Machine>::Traits::RegisterSet::getEncodedXmm, | 1838 InstX86Base<Machine>::Traits::RegisterSet::getEncodedXmm, |
| 1818 InstX86Base<Machine>::Traits::RegisterSet::getEncodedGPR>( | 1839 InstX86Base<Machine>::Traits::RegisterSet::getEncodedGPR>( |
| 1819 Func, DestTy, Dest, Src, Emitter); | 1840 Func, DestTy, Dest, SrcTy, Src, Emitter); |
| 1820 return; | 1841 return; |
| 1821 } | 1842 } |
| 1822 case Tss2si: { | 1843 case Tss2si: { |
| 1823 assert(isScalarFloatingType(SrcTy)); | 1844 assert(isScalarFloatingType(SrcTy)); |
| 1824 assert(isScalarIntegerType(DestTy)); | 1845 assert(isScalarIntegerType(DestTy)); |
| 1825 assert(typeWidthInBytes(DestTy) <= 4); | 1846 if (!InstX86Base<Machine>::Traits::Is64Bit) { |
| 1847 assert(typeWidthInBytes(DestTy) <= 4); |
| 1848 } else { |
| 1849 assert(DestTy == IceType_i32 || DestTy == IceType_i64); |
| 1850 } |
| 1826 static const typename InstX86Base<Machine>::Traits::Assembler:: | 1851 static const typename InstX86Base<Machine>::Traits::Assembler:: |
| 1827 template CastEmitterRegOp< | 1852 template CastEmitterRegOp< |
| 1828 typename InstX86Base<Machine>::Traits::RegisterSet::GPRRegister, | 1853 typename InstX86Base<Machine>::Traits::RegisterSet::GPRRegister, |
| 1829 typename InstX86Base<Machine>::Traits::RegisterSet::XmmRegister> | 1854 typename InstX86Base<Machine>::Traits::RegisterSet::XmmRegister> |
| 1830 Emitter = {&InstX86Base<Machine>::Traits::Assembler::cvttss2si, | 1855 Emitter = {&InstX86Base<Machine>::Traits::Assembler::cvttss2si, |
| 1831 &InstX86Base<Machine>::Traits::Assembler::cvttss2si}; | 1856 &InstX86Base<Machine>::Traits::Assembler::cvttss2si}; |
| 1832 emitIASCastRegOp< | 1857 emitIASCastRegOp< |
| 1833 Machine, | 1858 Machine, |
| 1834 typename InstX86Base<Machine>::Traits::RegisterSet::GPRRegister, | 1859 typename InstX86Base<Machine>::Traits::RegisterSet::GPRRegister, |
| 1835 typename InstX86Base<Machine>::Traits::RegisterSet::XmmRegister, | 1860 typename InstX86Base<Machine>::Traits::RegisterSet::XmmRegister, |
| 1836 InstX86Base<Machine>::Traits::RegisterSet::getEncodedGPR, | 1861 InstX86Base<Machine>::Traits::RegisterSet::getEncodedGPR, |
| 1837 InstX86Base<Machine>::Traits::RegisterSet::getEncodedXmm>( | 1862 InstX86Base<Machine>::Traits::RegisterSet::getEncodedXmm>( |
| 1838 Func, SrcTy, Dest, Src, Emitter); | 1863 Func, DestTy, Dest, SrcTy, Src, Emitter); |
| 1839 return; | 1864 return; |
| 1840 } | 1865 } |
| 1841 case Float2float: { | 1866 case Float2float: { |
| 1842 assert(isScalarFloatingType(SrcTy)); | 1867 assert(isScalarFloatingType(SrcTy)); |
| 1843 assert(isScalarFloatingType(DestTy)); | 1868 assert(isScalarFloatingType(DestTy)); |
| 1844 assert(DestTy != SrcTy); | 1869 assert(DestTy != SrcTy); |
| 1845 static const typename InstX86Base< | 1870 static const typename InstX86Base< |
| 1846 Machine>::Traits::Assembler::XmmEmitterRegOp Emitter = { | 1871 Machine>::Traits::Assembler::XmmEmitterRegOp Emitter = { |
| 1847 &InstX86Base<Machine>::Traits::Assembler::cvtfloat2float, | 1872 &InstX86Base<Machine>::Traits::Assembler::cvtfloat2float, |
| 1848 &InstX86Base<Machine>::Traits::Assembler::cvtfloat2float}; | 1873 &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 | 2250 // lea on x86-32 doesn't accept mem128 operands, so cast VSrc0 to an |
| 2226 // acceptable type. | 2251 // acceptable type. |
| 2227 Src0Var->asType(isVectorType(Ty) ? IceType_i32 : Ty)->emit(Func); | 2252 Src0Var->asType(isVectorType(Ty) ? IceType_i32 : Ty)->emit(Func); |
| 2228 } else { | 2253 } else { |
| 2229 Src0->emit(Func); | 2254 Src0->emit(Func); |
| 2230 } | 2255 } |
| 2231 Str << ", "; | 2256 Str << ", "; |
| 2232 this->getDest()->emit(Func); | 2257 this->getDest()->emit(Func); |
| 2233 } | 2258 } |
| 2234 | 2259 |
| 2260 inline bool isIntegerConstant(const Operand *Op) { |
| 2261 return llvm::isa<ConstantInteger32>(Op) || llvm::isa<ConstantInteger64>(Op); |
| 2262 } |
| 2263 |
| 2235 template <class Machine> void InstX86Mov<Machine>::emit(const Cfg *Func) const { | 2264 template <class Machine> void InstX86Mov<Machine>::emit(const Cfg *Func) const { |
| 2236 if (!BuildDefs::dump()) | 2265 if (!BuildDefs::dump()) |
| 2237 return; | 2266 return; |
| 2238 Ostream &Str = Func->getContext()->getStrEmit(); | 2267 Ostream &Str = Func->getContext()->getStrEmit(); |
| 2239 assert(this->getSrcSize() == 1); | 2268 assert(this->getSrcSize() == 1); |
| 2240 Operand *Src = this->getSrc(0); | 2269 Operand *Src = this->getSrc(0); |
| 2241 Type SrcTy = Src->getType(); | 2270 Type SrcTy = Src->getType(); |
| 2242 Type DestTy = this->getDest()->getType(); | 2271 Type DestTy = this->getDest()->getType(); |
| 2243 Str << "\tmov" | 2272 if (InstX86Base<Machine>::Traits::Is64Bit && DestTy == IceType_i64 && |
| 2244 << (!isScalarFloatingType(DestTy) | 2273 isIntegerConstant(Src)) { |
| 2245 ? this->getWidthString(SrcTy) | 2274 Str << "\tmovabs\t"; |
| 2246 : InstX86Base<Machine>::Traits::TypeAttributes[DestTy].SdSsString) | 2275 } else { |
| 2247 << "\t"; | 2276 Str << "\tmov" |
| 2277 << (!isScalarFloatingType(DestTy) |
| 2278 ? this->getWidthString(SrcTy) |
| 2279 : InstX86Base<Machine>::Traits::TypeAttributes[DestTy] |
| 2280 .SdSsString) << "\t"; |
| 2281 } |
| 2248 // For an integer truncation operation, src is wider than dest. | 2282 // For an integer truncation operation, src is wider than dest. |
| 2249 // Ideally, we use a mov instruction whose data width matches the | 2283 // 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 | 2284 // 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 | 2285 // 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 | 2286 // safe, we instead widen the dest to match src. This works even |
| 2253 // for stack-allocated dest variables because typeWidthOnStack() | 2287 // for stack-allocated dest variables because typeWidthOnStack() |
| 2254 // pads to a 4-byte boundary even if only a lower portion is used. | 2288 // 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 | 2289 // TODO: This assert disallows usages such as copying a floating point |
| 2256 // value between a vector and a scalar (which movss is used for). | 2290 // value between a vector and a scalar (which movss is used for). |
| 2257 // Clean this up. | 2291 // Clean this up. |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2301 Func->getTarget()->typeWidthInBytesOnStack(this->getDest()->getType()) == | 2335 Func->getTarget()->typeWidthInBytesOnStack(this->getDest()->getType()) == |
| 2302 Func->getTarget()->typeWidthInBytesOnStack(Src->getType())); | 2336 Func->getTarget()->typeWidthInBytesOnStack(Src->getType())); |
| 2303 if (Dest->hasReg()) { | 2337 if (Dest->hasReg()) { |
| 2304 if (isScalarFloatingType(DestTy)) { | 2338 if (isScalarFloatingType(DestTy)) { |
| 2305 emitIASRegOpTyXMM<Machine>(Func, DestTy, Dest, Src, XmmRegEmitter); | 2339 emitIASRegOpTyXMM<Machine>(Func, DestTy, Dest, Src, XmmRegEmitter); |
| 2306 return; | 2340 return; |
| 2307 } else { | 2341 } else { |
| 2308 assert(isScalarIntegerType(DestTy)); | 2342 assert(isScalarIntegerType(DestTy)); |
| 2309 // Widen DestTy for truncation (see above note). We should only do this | 2343 // Widen DestTy for truncation (see above note). We should only do this |
| 2310 // when both Src and Dest are integer types. | 2344 // when both Src and Dest are integer types. |
| 2345 if (InstX86Base<Machine>::Traits::Is64Bit && DestTy == IceType_i64 && |
| 2346 isIntegerConstant(Src)) { |
| 2347 uint64_t Value = -1; |
| 2348 if (const auto *C64 = llvm::dyn_cast<ConstantInteger64>(Src)) { |
| 2349 Value = C64->getValue(); |
| 2350 } else { |
| 2351 Value = llvm::cast<ConstantInteger32>(Src)->getValue(); |
| 2352 } |
| 2353 Func->getAssembler<typename InstX86Base<Machine>::Traits::Assembler>() |
| 2354 ->movabs(InstX86Base<Machine>::Traits::RegisterSet::getEncodedGPR( |
| 2355 Dest->getRegNum()), |
| 2356 Value); |
| 2357 return; |
| 2358 } |
| 2311 if (isScalarIntegerType(SrcTy)) { | 2359 if (isScalarIntegerType(SrcTy)) { |
| 2312 DestTy = SrcTy; | 2360 DestTy = SrcTy; |
| 2313 } | 2361 } |
| 2314 emitIASRegOpTyGPR<Machine>(Func, DestTy, Dest, Src, GPRRegEmitter); | 2362 emitIASRegOpTyGPR<Machine>(Func, DestTy, Dest, Src, GPRRegEmitter); |
| 2315 return; | 2363 return; |
| 2316 } | 2364 } |
| 2317 } else { | 2365 } else { |
| 2318 // Dest must be Stack and Src *could* be a register. Use Src's type | 2366 // Dest must be Stack and Src *could* be a register. Use Src's type |
| 2319 // to decide on the emitters. | 2367 // to decide on the emitters. |
| 2320 typename InstX86Base<Machine>::Traits::Address StackAddr( | 2368 typename InstX86Base<Machine>::Traits::Address StackAddr( |
| (...skipping 23 matching lines...) Expand all Loading... |
| 2344 | 2392 |
| 2345 template <class Machine> | 2393 template <class Machine> |
| 2346 void InstX86Movd<Machine>::emitIAS(const Cfg *Func) const { | 2394 void InstX86Movd<Machine>::emitIAS(const Cfg *Func) const { |
| 2347 typename InstX86Base<Machine>::Traits::Assembler *Asm = | 2395 typename InstX86Base<Machine>::Traits::Assembler *Asm = |
| 2348 Func->getAssembler<typename InstX86Base<Machine>::Traits::Assembler>(); | 2396 Func->getAssembler<typename InstX86Base<Machine>::Traits::Assembler>(); |
| 2349 assert(this->getSrcSize() == 1); | 2397 assert(this->getSrcSize() == 1); |
| 2350 const Variable *Dest = this->getDest(); | 2398 const Variable *Dest = this->getDest(); |
| 2351 const auto SrcVar = llvm::cast<Variable>(this->getSrc(0)); | 2399 const auto SrcVar = llvm::cast<Variable>(this->getSrc(0)); |
| 2352 // For insert/extract element (one of Src/Dest is an Xmm vector and | 2400 // For insert/extract element (one of Src/Dest is an Xmm vector and |
| 2353 // the other is an int type). | 2401 // the other is an int type). |
| 2354 if (SrcVar->getType() == IceType_i32) { | 2402 if (SrcVar->getType() == IceType_i32 || |
| 2355 assert(isVectorType(Dest->getType())); | 2403 (InstX86Base<Machine>::Traits::Is64Bit && |
| 2404 SrcVar->getType() == IceType_i64)) { |
| 2405 assert(isVectorType(Dest->getType()) || |
| 2406 (isScalarFloatingType(Dest->getType()) && |
| 2407 typeWidthInBytes(SrcVar->getType()) == |
| 2408 typeWidthInBytes(Dest->getType()))); |
| 2356 assert(Dest->hasReg()); | 2409 assert(Dest->hasReg()); |
| 2357 typename InstX86Base<Machine>::Traits::RegisterSet::XmmRegister DestReg = | 2410 typename InstX86Base<Machine>::Traits::RegisterSet::XmmRegister DestReg = |
| 2358 InstX86Base<Machine>::Traits::RegisterSet::getEncodedXmm( | 2411 InstX86Base<Machine>::Traits::RegisterSet::getEncodedXmm( |
| 2359 Dest->getRegNum()); | 2412 Dest->getRegNum()); |
| 2360 if (SrcVar->hasReg()) { | 2413 if (SrcVar->hasReg()) { |
| 2361 Asm->movd(DestReg, | 2414 Asm->movd(SrcVar->getType(), DestReg, |
| 2362 InstX86Base<Machine>::Traits::RegisterSet::getEncodedGPR( | 2415 InstX86Base<Machine>::Traits::RegisterSet::getEncodedGPR( |
| 2363 SrcVar->getRegNum())); | 2416 SrcVar->getRegNum())); |
| 2364 } else { | 2417 } else { |
| 2365 typename InstX86Base<Machine>::Traits::Address StackAddr( | 2418 typename InstX86Base<Machine>::Traits::Address StackAddr( |
| 2366 static_cast<typename InstX86Base<Machine>::Traits::TargetLowering *>( | 2419 static_cast<typename InstX86Base<Machine>::Traits::TargetLowering *>( |
| 2367 Func->getTarget()) | 2420 Func->getTarget()) |
| 2368 ->stackVarToAsmOperand(SrcVar)); | 2421 ->stackVarToAsmOperand(SrcVar)); |
| 2369 Asm->movd(DestReg, StackAddr); | 2422 Asm->movd(SrcVar->getType(), DestReg, StackAddr); |
| 2370 } | 2423 } |
| 2371 } else { | 2424 } else { |
| 2372 assert(isVectorType(SrcVar->getType())); | 2425 assert(isVectorType(SrcVar->getType()) || |
| 2426 (isScalarFloatingType(SrcVar->getType()) && |
| 2427 typeWidthInBytes(SrcVar->getType()) == |
| 2428 typeWidthInBytes(Dest->getType()))); |
| 2373 assert(SrcVar->hasReg()); | 2429 assert(SrcVar->hasReg()); |
| 2374 assert(Dest->getType() == IceType_i32); | 2430 assert(Dest->getType() == IceType_i32 || |
| 2431 (InstX86Base<Machine>::Traits::Is64Bit && |
| 2432 Dest->getType() == IceType_i64)); |
| 2375 typename InstX86Base<Machine>::Traits::RegisterSet::XmmRegister SrcReg = | 2433 typename InstX86Base<Machine>::Traits::RegisterSet::XmmRegister SrcReg = |
| 2376 InstX86Base<Machine>::Traits::RegisterSet::getEncodedXmm( | 2434 InstX86Base<Machine>::Traits::RegisterSet::getEncodedXmm( |
| 2377 SrcVar->getRegNum()); | 2435 SrcVar->getRegNum()); |
| 2378 if (Dest->hasReg()) { | 2436 if (Dest->hasReg()) { |
| 2379 Asm->movd(InstX86Base<Machine>::Traits::RegisterSet::getEncodedGPR( | 2437 Asm->movd(Dest->getType(), |
| 2438 InstX86Base<Machine>::Traits::RegisterSet::getEncodedGPR( |
| 2380 Dest->getRegNum()), | 2439 Dest->getRegNum()), |
| 2381 SrcReg); | 2440 SrcReg); |
| 2382 } else { | 2441 } else { |
| 2383 typename InstX86Base<Machine>::Traits::Address StackAddr( | 2442 typename InstX86Base<Machine>::Traits::Address StackAddr( |
| 2384 static_cast<typename InstX86Base<Machine>::Traits::TargetLowering *>( | 2443 static_cast<typename InstX86Base<Machine>::Traits::TargetLowering *>( |
| 2385 Func->getTarget()) | 2444 Func->getTarget()) |
| 2386 ->stackVarToAsmOperand(Dest)); | 2445 ->stackVarToAsmOperand(Dest)); |
| 2387 Asm->movd(StackAddr, SrcReg); | 2446 Asm->movd(Dest->getType(), StackAddr, SrcReg); |
| 2388 } | 2447 } |
| 2389 } | 2448 } |
| 2390 } | 2449 } |
| 2391 | 2450 |
| 2392 template <class Machine> | 2451 template <class Machine> |
| 2393 void InstX86Movp<Machine>::emit(const Cfg *Func) const { | 2452 void InstX86Movp<Machine>::emit(const Cfg *Func) const { |
| 2394 if (!BuildDefs::dump()) | 2453 if (!BuildDefs::dump()) |
| 2395 return; | 2454 return; |
| 2396 // TODO(wala,stichnot): movups works with all vector operands, but | 2455 // TODO(wala,stichnot): movups works with all vector operands, but |
| 2397 // there exist other instructions (movaps, movdqa, movdqu) that may | 2456 // 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(); | 3213 Type Ty = this->getSrc(0)->getType(); |
| 3155 Str << "xchg." << Ty << " "; | 3214 Str << "xchg." << Ty << " "; |
| 3156 this->dumpSources(Func); | 3215 this->dumpSources(Func); |
| 3157 } | 3216 } |
| 3158 | 3217 |
| 3159 } // end of namespace X86Internal | 3218 } // end of namespace X86Internal |
| 3160 | 3219 |
| 3161 } // end of namespace Ice | 3220 } // end of namespace Ice |
| 3162 | 3221 |
| 3163 #endif // SUBZERO_SRC_ICEINSTX86BASEIMPL_H | 3222 #endif // SUBZERO_SRC_ICEINSTX86BASEIMPL_H |
| OLD | NEW |