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

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: Fixes tests & make format 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
« no previous file with comments | « src/IceInstX86Base.h ('k') | src/IceTargetLoweringX8632.cpp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 415 matching lines...) Expand 10 before | Expand all | Expand 10 after
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
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
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « src/IceInstX86Base.h ('k') | src/IceTargetLoweringX8632.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698