Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(85)

Side by Side Diff: src/IceInstX86BaseImpl.h

Issue 1273153002: Subzero. Native 64-bit int arithmetic on x86-64. (Closed) Base URL: https://chromium.googlesource.com/native_client/pnacl-subzero.git@master
Patch Set: Removes the x8664-specific xtest target. Created 5 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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
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
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
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
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
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
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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698