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

Side by Side Diff: src/IceTargetLoweringX86BaseImpl.h

Issue 1665423002: Subzero: Cleanup Inst==>Instr. (Closed) Base URL: https://chromium.googlesource.com/native_client/pnacl-subzero.git@master
Patch Set: Created 4 years, 10 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/IceTargetLoweringX86Base.h ('k') | src/PNaClTranslator.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/IceTargetLoweringX86BaseImpl.h - x86 lowering -*- C++ -*-==// 1 //===- subzero/src/IceTargetLoweringX86BaseImpl.h - x86 lowering -*- 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 1361 matching lines...) Expand 10 before | Expand all | Expand 10 after
1372 } 1372 }
1373 1373
1374 template <typename TraitsType> 1374 template <typename TraitsType>
1375 llvm::SmallBitVector 1375 llvm::SmallBitVector
1376 TargetX86Base<TraitsType>::getRegisterSet(RegSetMask Include, 1376 TargetX86Base<TraitsType>::getRegisterSet(RegSetMask Include,
1377 RegSetMask Exclude) const { 1377 RegSetMask Exclude) const {
1378 return Traits::getRegisterSet(Ctx->getFlags(), Include, Exclude); 1378 return Traits::getRegisterSet(Ctx->getFlags(), Include, Exclude);
1379 } 1379 }
1380 1380
1381 template <typename TraitsType> 1381 template <typename TraitsType>
1382 void TargetX86Base<TraitsType>::lowerAlloca(const InstAlloca *Inst) { 1382 void TargetX86Base<TraitsType>::lowerAlloca(const InstAlloca *Instr) {
1383 // Conservatively require the stack to be aligned. Some stack adjustment 1383 // Conservatively require the stack to be aligned. Some stack adjustment
1384 // operations implemented below assume that the stack is aligned before the 1384 // operations implemented below assume that the stack is aligned before the
1385 // alloca. All the alloca code ensures that the stack alignment is preserved 1385 // alloca. All the alloca code ensures that the stack alignment is preserved
1386 // after the alloca. The stack alignment restriction can be relaxed in some 1386 // after the alloca. The stack alignment restriction can be relaxed in some
1387 // cases. 1387 // cases.
1388 NeedsStackAlignment = true; 1388 NeedsStackAlignment = true;
1389 1389
1390 // For default align=0, set it to the real value 1, to avoid any 1390 // For default align=0, set it to the real value 1, to avoid any
1391 // bit-manipulation problems below. 1391 // bit-manipulation problems below.
1392 const uint32_t AlignmentParam = std::max(1u, Inst->getAlignInBytes()); 1392 const uint32_t AlignmentParam = std::max(1u, Instr->getAlignInBytes());
1393 1393
1394 // LLVM enforces power of 2 alignment. 1394 // LLVM enforces power of 2 alignment.
1395 assert(llvm::isPowerOf2_32(AlignmentParam)); 1395 assert(llvm::isPowerOf2_32(AlignmentParam));
1396 assert(llvm::isPowerOf2_32(Traits::X86_STACK_ALIGNMENT_BYTES)); 1396 assert(llvm::isPowerOf2_32(Traits::X86_STACK_ALIGNMENT_BYTES));
1397 1397
1398 const uint32_t Alignment = 1398 const uint32_t Alignment =
1399 std::max(AlignmentParam, Traits::X86_STACK_ALIGNMENT_BYTES); 1399 std::max(AlignmentParam, Traits::X86_STACK_ALIGNMENT_BYTES);
1400 const bool OverAligned = Alignment > Traits::X86_STACK_ALIGNMENT_BYTES; 1400 const bool OverAligned = Alignment > Traits::X86_STACK_ALIGNMENT_BYTES;
1401 const bool OptM1 = Ctx->getFlags().getOptLevel() == Opt_m1; 1401 const bool OptM1 = Ctx->getFlags().getOptLevel() == Opt_m1;
1402 const bool AllocaWithKnownOffset = Inst->getKnownFrameOffset(); 1402 const bool AllocaWithKnownOffset = Instr->getKnownFrameOffset();
1403 const bool UseFramePointer = 1403 const bool UseFramePointer =
1404 hasFramePointer() || OverAligned || !AllocaWithKnownOffset || OptM1; 1404 hasFramePointer() || OverAligned || !AllocaWithKnownOffset || OptM1;
1405 1405
1406 if (UseFramePointer) 1406 if (UseFramePointer)
1407 setHasFramePointer(); 1407 setHasFramePointer();
1408 1408
1409 Variable *esp = getPhysicalRegister(getStackReg(), Traits::WordType); 1409 Variable *esp = getPhysicalRegister(getStackReg(), Traits::WordType);
1410 if (OverAligned) { 1410 if (OverAligned) {
1411 _and(esp, Ctx->getConstantInt32(-Alignment)); 1411 _and(esp, Ctx->getConstantInt32(-Alignment));
1412 } 1412 }
1413 1413
1414 Variable *Dest = Inst->getDest(); 1414 Variable *Dest = Instr->getDest();
1415 Operand *TotalSize = legalize(Inst->getSizeInBytes()); 1415 Operand *TotalSize = legalize(Instr->getSizeInBytes());
1416 1416
1417 if (const auto *ConstantTotalSize = 1417 if (const auto *ConstantTotalSize =
1418 llvm::dyn_cast<ConstantInteger32>(TotalSize)) { 1418 llvm::dyn_cast<ConstantInteger32>(TotalSize)) {
1419 const uint32_t Value = 1419 const uint32_t Value =
1420 Utils::applyAlignment(ConstantTotalSize->getValue(), Alignment); 1420 Utils::applyAlignment(ConstantTotalSize->getValue(), Alignment);
1421 if (UseFramePointer) { 1421 if (UseFramePointer) {
1422 _sub_sp(Ctx->getConstantInt32(Value)); 1422 _sub_sp(Ctx->getConstantInt32(Value));
1423 } else { 1423 } else {
1424 // If we don't need a Frame Pointer, this alloca has a known offset to the 1424 // If we don't need a Frame Pointer, this alloca has a known offset to the
1425 // stack pointer. We don't need adjust the stack pointer, nor assign any 1425 // stack pointer. We don't need adjust the stack pointer, nor assign any
(...skipping 399 matching lines...) Expand 10 before | Expand all | Expand 10 after
1825 // L1: 1825 // L1:
1826 // a.lo = t2 1826 // a.lo = t2
1827 // a.hi = t3 1827 // a.hi = t3
1828 Context.insert(Label); 1828 Context.insert(Label);
1829 _mov(DestLo, T_2); 1829 _mov(DestLo, T_2);
1830 _mov(DestHi, T_3); 1830 _mov(DestHi, T_3);
1831 } 1831 }
1832 } 1832 }
1833 1833
1834 template <typename TraitsType> 1834 template <typename TraitsType>
1835 void TargetX86Base<TraitsType>::lowerArithmetic(const InstArithmetic *Inst) { 1835 void TargetX86Base<TraitsType>::lowerArithmetic(const InstArithmetic *Instr) {
1836 Variable *Dest = Inst->getDest(); 1836 Variable *Dest = Instr->getDest();
1837 if (Dest->isRematerializable()) { 1837 if (Dest->isRematerializable()) {
1838 Context.insert<InstFakeDef>(Dest); 1838 Context.insert<InstFakeDef>(Dest);
1839 return; 1839 return;
1840 } 1840 }
1841 Type Ty = Dest->getType(); 1841 Type Ty = Dest->getType();
1842 Operand *Src0 = legalize(Inst->getSrc(0)); 1842 Operand *Src0 = legalize(Instr->getSrc(0));
1843 Operand *Src1 = legalize(Inst->getSrc(1)); 1843 Operand *Src1 = legalize(Instr->getSrc(1));
1844 if (Inst->isCommutative()) { 1844 if (Instr->isCommutative()) {
1845 uint32_t SwapCount = 0; 1845 uint32_t SwapCount = 0;
1846 if (!llvm::isa<Variable>(Src0) && llvm::isa<Variable>(Src1)) { 1846 if (!llvm::isa<Variable>(Src0) && llvm::isa<Variable>(Src1)) {
1847 std::swap(Src0, Src1); 1847 std::swap(Src0, Src1);
1848 ++SwapCount; 1848 ++SwapCount;
1849 } 1849 }
1850 if (llvm::isa<Constant>(Src0) && !llvm::isa<Constant>(Src1)) { 1850 if (llvm::isa<Constant>(Src0) && !llvm::isa<Constant>(Src1)) {
1851 std::swap(Src0, Src1); 1851 std::swap(Src0, Src1);
1852 ++SwapCount; 1852 ++SwapCount;
1853 } 1853 }
1854 // Improve two-address code patterns by avoiding a copy to the dest 1854 // Improve two-address code patterns by avoiding a copy to the dest
1855 // register when one of the source operands ends its lifetime here. 1855 // register when one of the source operands ends its lifetime here.
1856 if (!Inst->isLastUse(Src0) && Inst->isLastUse(Src1)) { 1856 if (!Instr->isLastUse(Src0) && Instr->isLastUse(Src1)) {
1857 std::swap(Src0, Src1); 1857 std::swap(Src0, Src1);
1858 ++SwapCount; 1858 ++SwapCount;
1859 } 1859 }
1860 assert(SwapCount <= 1); 1860 assert(SwapCount <= 1);
1861 (void)SwapCount; 1861 (void)SwapCount;
1862 } 1862 }
1863 if (!Traits::Is64Bit && Ty == IceType_i64) { 1863 if (!Traits::Is64Bit && Ty == IceType_i64) {
1864 // These x86-32 helper-call-involved instructions are lowered in this 1864 // These x86-32 helper-call-involved instructions are lowered in this
1865 // separate switch. This is because loOperand() and hiOperand() may insert 1865 // separate switch. This is because loOperand() and hiOperand() may insert
1866 // redundant instructions for constant blinding and pooling. Such redundant 1866 // redundant instructions for constant blinding and pooling. Such redundant
1867 // instructions will fail liveness analysis under -Om1 setting. And, 1867 // instructions will fail liveness analysis under -Om1 setting. And,
1868 // actually these arguments do not need to be processed with loOperand() 1868 // actually these arguments do not need to be processed with loOperand()
1869 // and hiOperand() to be used. 1869 // and hiOperand() to be used.
1870 switch (Inst->getOp()) { 1870 switch (Instr->getOp()) {
1871 case InstArithmetic::Udiv: 1871 case InstArithmetic::Udiv:
1872 case InstArithmetic::Sdiv: 1872 case InstArithmetic::Sdiv:
1873 case InstArithmetic::Urem: 1873 case InstArithmetic::Urem:
1874 case InstArithmetic::Srem: 1874 case InstArithmetic::Srem:
1875 llvm::report_fatal_error("Helper call was expected"); 1875 llvm::report_fatal_error("Helper call was expected");
1876 return; 1876 return;
1877 default: 1877 default:
1878 break; 1878 break;
1879 } 1879 }
1880 1880
1881 auto *DestLo = llvm::cast<Variable>(loOperand(Dest)); 1881 auto *DestLo = llvm::cast<Variable>(loOperand(Dest));
1882 auto *DestHi = llvm::cast<Variable>(hiOperand(Dest)); 1882 auto *DestHi = llvm::cast<Variable>(hiOperand(Dest));
1883 Operand *Src0Lo = loOperand(Src0); 1883 Operand *Src0Lo = loOperand(Src0);
1884 Operand *Src0Hi = hiOperand(Src0); 1884 Operand *Src0Hi = hiOperand(Src0);
1885 Operand *Src1Lo = loOperand(Src1); 1885 Operand *Src1Lo = loOperand(Src1);
1886 Operand *Src1Hi = hiOperand(Src1); 1886 Operand *Src1Hi = hiOperand(Src1);
1887 Variable *T_Lo = nullptr, *T_Hi = nullptr; 1887 Variable *T_Lo = nullptr, *T_Hi = nullptr;
1888 switch (Inst->getOp()) { 1888 switch (Instr->getOp()) {
1889 case InstArithmetic::_num: 1889 case InstArithmetic::_num:
1890 llvm_unreachable("Unknown arithmetic operator"); 1890 llvm_unreachable("Unknown arithmetic operator");
1891 break; 1891 break;
1892 case InstArithmetic::Add: 1892 case InstArithmetic::Add:
1893 _mov(T_Lo, Src0Lo); 1893 _mov(T_Lo, Src0Lo);
1894 _add(T_Lo, Src1Lo); 1894 _add(T_Lo, Src1Lo);
1895 _mov(DestLo, T_Lo); 1895 _mov(DestLo, T_Lo);
1896 _mov(T_Hi, Src0Hi); 1896 _mov(T_Hi, Src0Hi);
1897 _adc(T_Hi, Src1Hi); 1897 _adc(T_Hi, Src1Hi);
1898 _mov(DestHi, T_Hi); 1898 _mov(DestHi, T_Hi);
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
1955 _mov(DestLo, T_4Lo); 1955 _mov(DestLo, T_4Lo);
1956 _add(T_4Hi, T_1); 1956 _add(T_4Hi, T_1);
1957 _mov(T_2, Src1Hi); 1957 _mov(T_2, Src1Hi);
1958 _imul(T_2, Src0Lo); 1958 _imul(T_2, Src0Lo);
1959 _add(T_4Hi, T_2); 1959 _add(T_4Hi, T_2);
1960 _mov(DestHi, T_4Hi); 1960 _mov(DestHi, T_4Hi);
1961 } break; 1961 } break;
1962 case InstArithmetic::Shl: 1962 case InstArithmetic::Shl:
1963 case InstArithmetic::Lshr: 1963 case InstArithmetic::Lshr:
1964 case InstArithmetic::Ashr: 1964 case InstArithmetic::Ashr:
1965 lowerShift64(Inst->getOp(), Src0Lo, Src0Hi, Src1Lo, DestLo, DestHi); 1965 lowerShift64(Instr->getOp(), Src0Lo, Src0Hi, Src1Lo, DestLo, DestHi);
1966 break; 1966 break;
1967 case InstArithmetic::Fadd: 1967 case InstArithmetic::Fadd:
1968 case InstArithmetic::Fsub: 1968 case InstArithmetic::Fsub:
1969 case InstArithmetic::Fmul: 1969 case InstArithmetic::Fmul:
1970 case InstArithmetic::Fdiv: 1970 case InstArithmetic::Fdiv:
1971 case InstArithmetic::Frem: 1971 case InstArithmetic::Frem:
1972 llvm_unreachable("FP instruction with i64 type"); 1972 llvm_unreachable("FP instruction with i64 type");
1973 break; 1973 break;
1974 case InstArithmetic::Udiv: 1974 case InstArithmetic::Udiv:
1975 case InstArithmetic::Sdiv: 1975 case InstArithmetic::Sdiv:
1976 case InstArithmetic::Urem: 1976 case InstArithmetic::Urem:
1977 case InstArithmetic::Srem: 1977 case InstArithmetic::Srem:
1978 llvm_unreachable("Call-helper-involved instruction for i64 type \ 1978 llvm_unreachable("Call-helper-involved instruction for i64 type \
1979 should have already been handled before"); 1979 should have already been handled before");
1980 break; 1980 break;
1981 } 1981 }
1982 return; 1982 return;
1983 } 1983 }
1984 if (isVectorType(Ty)) { 1984 if (isVectorType(Ty)) {
1985 // TODO: Trap on integer divide and integer modulo by zero. See: 1985 // TODO: Trap on integer divide and integer modulo by zero. See:
1986 // https://code.google.com/p/nativeclient/issues/detail?id=3899 1986 // https://code.google.com/p/nativeclient/issues/detail?id=3899
1987 if (llvm::isa<X86OperandMem>(Src1)) 1987 if (llvm::isa<X86OperandMem>(Src1))
1988 Src1 = legalizeToReg(Src1); 1988 Src1 = legalizeToReg(Src1);
1989 switch (Inst->getOp()) { 1989 switch (Instr->getOp()) {
1990 case InstArithmetic::_num: 1990 case InstArithmetic::_num:
1991 llvm_unreachable("Unknown arithmetic operator"); 1991 llvm_unreachable("Unknown arithmetic operator");
1992 break; 1992 break;
1993 case InstArithmetic::Add: { 1993 case InstArithmetic::Add: {
1994 Variable *T = makeReg(Ty); 1994 Variable *T = makeReg(Ty);
1995 _movp(T, Src0); 1995 _movp(T, Src0);
1996 _padd(T, Src1); 1996 _padd(T, Src1);
1997 _movp(Dest, T); 1997 _movp(Dest, T);
1998 } break; 1998 } break;
1999 case InstArithmetic::And: { 1999 case InstArithmetic::And: {
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after
2107 _movp(Dest, T); 2107 _movp(Dest, T);
2108 } break; 2108 } break;
2109 case InstArithmetic::Frem: 2109 case InstArithmetic::Frem:
2110 llvm::report_fatal_error("Scalarized operation was expected"); 2110 llvm::report_fatal_error("Scalarized operation was expected");
2111 break; 2111 break;
2112 } 2112 }
2113 return; 2113 return;
2114 } 2114 }
2115 Variable *T_edx = nullptr; 2115 Variable *T_edx = nullptr;
2116 Variable *T = nullptr; 2116 Variable *T = nullptr;
2117 switch (Inst->getOp()) { 2117 switch (Instr->getOp()) {
2118 case InstArithmetic::_num: 2118 case InstArithmetic::_num:
2119 llvm_unreachable("Unknown arithmetic operator"); 2119 llvm_unreachable("Unknown arithmetic operator");
2120 break; 2120 break;
2121 case InstArithmetic::Add: 2121 case InstArithmetic::Add:
2122 _mov(T, Src0); 2122 _mov(T, Src0);
2123 _add(T, Src1); 2123 _add(T, Src1);
2124 _mov(Dest, T); 2124 _mov(Dest, T);
2125 break; 2125 break;
2126 case InstArithmetic::And: 2126 case InstArithmetic::And:
2127 _mov(T, Src0); 2127 _mov(T, Src0);
(...skipping 269 matching lines...) Expand 10 before | Expand all | Expand 10 after
2397 _divss(T, Src1); 2397 _divss(T, Src1);
2398 _mov(Dest, T); 2398 _mov(Dest, T);
2399 break; 2399 break;
2400 case InstArithmetic::Frem: 2400 case InstArithmetic::Frem:
2401 llvm::report_fatal_error("Helper call was expected"); 2401 llvm::report_fatal_error("Helper call was expected");
2402 break; 2402 break;
2403 } 2403 }
2404 } 2404 }
2405 2405
2406 template <typename TraitsType> 2406 template <typename TraitsType>
2407 void TargetX86Base<TraitsType>::lowerAssign(const InstAssign *Inst) { 2407 void TargetX86Base<TraitsType>::lowerAssign(const InstAssign *Instr) {
2408 Variable *Dest = Inst->getDest(); 2408 Variable *Dest = Instr->getDest();
2409 if (Dest->isRematerializable()) { 2409 if (Dest->isRematerializable()) {
2410 Context.insert<InstFakeDef>(Dest); 2410 Context.insert<InstFakeDef>(Dest);
2411 return; 2411 return;
2412 } 2412 }
2413 Operand *Src = Inst->getSrc(0); 2413 Operand *Src = Instr->getSrc(0);
2414 assert(Dest->getType() == Src->getType()); 2414 assert(Dest->getType() == Src->getType());
2415 lowerMove(Dest, Src, false); 2415 lowerMove(Dest, Src, false);
2416 } 2416 }
2417 2417
2418 template <typename TraitsType> 2418 template <typename TraitsType>
2419 void TargetX86Base<TraitsType>::lowerBr(const InstBr *Br) { 2419 void TargetX86Base<TraitsType>::lowerBr(const InstBr *Br) {
2420 if (Br->isUnconditional()) { 2420 if (Br->isUnconditional()) {
2421 _br(Br->getTargetUnconditional()); 2421 _br(Br->getTargetUnconditional());
2422 return; 2422 return;
2423 } 2423 }
(...skipping 217 matching lines...) Expand 10 before | Expand all | Expand 10 after
2641 Variable *DestHi = Dest64On32->getHi(); 2641 Variable *DestHi = Dest64On32->getHi();
2642 _mov(DestLo, ReturnReg); 2642 _mov(DestLo, ReturnReg);
2643 _mov(DestHi, ReturnRegHi); 2643 _mov(DestHi, ReturnRegHi);
2644 } else { 2644 } else {
2645 _mov(Dest, ReturnReg); 2645 _mov(Dest, ReturnReg);
2646 } 2646 }
2647 } 2647 }
2648 } 2648 }
2649 2649
2650 template <typename TraitsType> 2650 template <typename TraitsType>
2651 void TargetX86Base<TraitsType>::lowerCast(const InstCast *Inst) { 2651 void TargetX86Base<TraitsType>::lowerCast(const InstCast *Instr) {
2652 // a = cast(b) ==> t=cast(b); a=t; (link t->b, link a->t, no overlap) 2652 // a = cast(b) ==> t=cast(b); a=t; (link t->b, link a->t, no overlap)
2653 InstCast::OpKind CastKind = Inst->getCastKind(); 2653 InstCast::OpKind CastKind = Instr->getCastKind();
2654 Variable *Dest = Inst->getDest(); 2654 Variable *Dest = Instr->getDest();
2655 Type DestTy = Dest->getType(); 2655 Type DestTy = Dest->getType();
2656 switch (CastKind) { 2656 switch (CastKind) {
2657 default: 2657 default:
2658 Func->setError("Cast type not supported"); 2658 Func->setError("Cast type not supported");
2659 return; 2659 return;
2660 case InstCast::Sext: { 2660 case InstCast::Sext: {
2661 // Src0RM is the source operand legalized to physical register or memory, 2661 // Src0RM is the source operand legalized to physical register or memory,
2662 // but not immediate, since the relevant x86 native instructions don't 2662 // but not immediate, since the relevant x86 native instructions don't
2663 // allow an immediate operand. If the operand is an immediate, we could 2663 // allow an immediate operand. If the operand is an immediate, we could
2664 // consider computing the strength-reduced result at translation time, but 2664 // consider computing the strength-reduced result at translation time, but
2665 // we're unlikely to see something like that in the bitcode that the 2665 // we're unlikely to see something like that in the bitcode that the
2666 // optimizer wouldn't have already taken care of. 2666 // optimizer wouldn't have already taken care of.
2667 Operand *Src0RM = legalize(Inst->getSrc(0), Legal_Reg | Legal_Mem); 2667 Operand *Src0RM = legalize(Instr->getSrc(0), Legal_Reg | Legal_Mem);
2668 if (isVectorType(DestTy)) { 2668 if (isVectorType(DestTy)) {
2669 if (DestTy == IceType_v16i8) { 2669 if (DestTy == IceType_v16i8) {
2670 // onemask = materialize(1,1,...); dst = (src & onemask) > 0 2670 // onemask = materialize(1,1,...); dst = (src & onemask) > 0
2671 Variable *OneMask = makeVectorOfOnes(DestTy); 2671 Variable *OneMask = makeVectorOfOnes(DestTy);
2672 Variable *T = makeReg(DestTy); 2672 Variable *T = makeReg(DestTy);
2673 _movp(T, Src0RM); 2673 _movp(T, Src0RM);
2674 _pand(T, OneMask); 2674 _pand(T, OneMask);
2675 Variable *Zeros = makeVectorOfZeros(DestTy); 2675 Variable *Zeros = makeVectorOfZeros(DestTy);
2676 _pcmpgt(T, Zeros); 2676 _pcmpgt(T, Zeros);
2677 _movp(Dest, T); 2677 _movp(Dest, T);
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
2729 _mov(Dest, T); 2729 _mov(Dest, T);
2730 } else { 2730 } else {
2731 // t1 = movsx src; dst = t1 2731 // t1 = movsx src; dst = t1
2732 Variable *T = makeReg(DestTy); 2732 Variable *T = makeReg(DestTy);
2733 _movsx(T, Src0RM); 2733 _movsx(T, Src0RM);
2734 _mov(Dest, T); 2734 _mov(Dest, T);
2735 } 2735 }
2736 break; 2736 break;
2737 } 2737 }
2738 case InstCast::Zext: { 2738 case InstCast::Zext: {
2739 Operand *Src0RM = legalize(Inst->getSrc(0), Legal_Reg | Legal_Mem); 2739 Operand *Src0RM = legalize(Instr->getSrc(0), Legal_Reg | Legal_Mem);
2740 if (isVectorType(DestTy)) { 2740 if (isVectorType(DestTy)) {
2741 // onemask = materialize(1,1,...); dest = onemask & src 2741 // onemask = materialize(1,1,...); dest = onemask & src
2742 Variable *OneMask = makeVectorOfOnes(DestTy); 2742 Variable *OneMask = makeVectorOfOnes(DestTy);
2743 Variable *T = makeReg(DestTy); 2743 Variable *T = makeReg(DestTy);
2744 _movp(T, Src0RM); 2744 _movp(T, Src0RM);
2745 _pand(T, OneMask); 2745 _pand(T, OneMask);
2746 _movp(Dest, T); 2746 _movp(Dest, T);
2747 } else if (!Traits::Is64Bit && DestTy == IceType_i64) { 2747 } else if (!Traits::Is64Bit && DestTy == IceType_i64) {
2748 // t1=movzx src; dst.lo=t1; dst.hi=0 2748 // t1=movzx src; dst.lo=t1; dst.hi=0
2749 Constant *Zero = Ctx->getConstantZero(IceType_i32); 2749 Constant *Zero = Ctx->getConstantZero(IceType_i32);
(...skipping 26 matching lines...) Expand all
2776 // t1 = movzx src; dst = t1 2776 // t1 = movzx src; dst = t1
2777 Variable *T = makeReg(DestTy); 2777 Variable *T = makeReg(DestTy);
2778 _movzx(T, Src0RM); 2778 _movzx(T, Src0RM);
2779 _mov(Dest, T); 2779 _mov(Dest, T);
2780 } 2780 }
2781 break; 2781 break;
2782 } 2782 }
2783 case InstCast::Trunc: { 2783 case InstCast::Trunc: {
2784 if (isVectorType(DestTy)) { 2784 if (isVectorType(DestTy)) {
2785 // onemask = materialize(1,1,...); dst = src & onemask 2785 // onemask = materialize(1,1,...); dst = src & onemask
2786 Operand *Src0RM = legalize(Inst->getSrc(0), Legal_Reg | Legal_Mem); 2786 Operand *Src0RM = legalize(Instr->getSrc(0), Legal_Reg | Legal_Mem);
2787 Type Src0Ty = Src0RM->getType(); 2787 Type Src0Ty = Src0RM->getType();
2788 Variable *OneMask = makeVectorOfOnes(Src0Ty); 2788 Variable *OneMask = makeVectorOfOnes(Src0Ty);
2789 Variable *T = makeReg(DestTy); 2789 Variable *T = makeReg(DestTy);
2790 _movp(T, Src0RM); 2790 _movp(T, Src0RM);
2791 _pand(T, OneMask); 2791 _pand(T, OneMask);
2792 _movp(Dest, T); 2792 _movp(Dest, T);
2793 } else if (DestTy == IceType_i1 || DestTy == IceType_i8) { 2793 } else if (DestTy == IceType_i1 || DestTy == IceType_i8) {
2794 // Make sure we truncate from and into valid registers. 2794 // Make sure we truncate from and into valid registers.
2795 Operand *Src0 = legalizeUndef(Inst->getSrc(0)); 2795 Operand *Src0 = legalizeUndef(Instr->getSrc(0));
2796 if (!Traits::Is64Bit && Src0->getType() == IceType_i64) 2796 if (!Traits::Is64Bit && Src0->getType() == IceType_i64)
2797 Src0 = loOperand(Src0); 2797 Src0 = loOperand(Src0);
2798 Operand *Src0RM = legalize(Src0, Legal_Reg | Legal_Mem); 2798 Operand *Src0RM = legalize(Src0, Legal_Reg | Legal_Mem);
2799 Variable *T = copyToReg8(Src0RM); 2799 Variable *T = copyToReg8(Src0RM);
2800 if (DestTy == IceType_i1) 2800 if (DestTy == IceType_i1)
2801 _and(T, Ctx->getConstantInt1(1)); 2801 _and(T, Ctx->getConstantInt1(1));
2802 _mov(Dest, T); 2802 _mov(Dest, T);
2803 } else { 2803 } else {
2804 Operand *Src0 = legalizeUndef(Inst->getSrc(0)); 2804 Operand *Src0 = legalizeUndef(Instr->getSrc(0));
2805 if (!Traits::Is64Bit && Src0->getType() == IceType_i64) 2805 if (!Traits::Is64Bit && Src0->getType() == IceType_i64)
2806 Src0 = loOperand(Src0); 2806 Src0 = loOperand(Src0);
2807 Operand *Src0RM = legalize(Src0, Legal_Reg | Legal_Mem); 2807 Operand *Src0RM = legalize(Src0, Legal_Reg | Legal_Mem);
2808 // t1 = trunc Src0RM; Dest = t1 2808 // t1 = trunc Src0RM; Dest = t1
2809 Variable *T = makeReg(DestTy); 2809 Variable *T = makeReg(DestTy);
2810 _mov(T, Src0RM); 2810 _mov(T, Src0RM);
2811 _mov(Dest, T); 2811 _mov(Dest, T);
2812 } 2812 }
2813 break; 2813 break;
2814 } 2814 }
2815 case InstCast::Fptrunc: 2815 case InstCast::Fptrunc:
2816 case InstCast::Fpext: { 2816 case InstCast::Fpext: {
2817 Operand *Src0RM = legalize(Inst->getSrc(0), Legal_Reg | Legal_Mem); 2817 Operand *Src0RM = legalize(Instr->getSrc(0), Legal_Reg | Legal_Mem);
2818 // t1 = cvt Src0RM; Dest = t1 2818 // t1 = cvt Src0RM; Dest = t1
2819 Variable *T = makeReg(DestTy); 2819 Variable *T = makeReg(DestTy);
2820 _cvt(T, Src0RM, Traits::Insts::Cvt::Float2float); 2820 _cvt(T, Src0RM, Traits::Insts::Cvt::Float2float);
2821 _mov(Dest, T); 2821 _mov(Dest, T);
2822 break; 2822 break;
2823 } 2823 }
2824 case InstCast::Fptosi: 2824 case InstCast::Fptosi:
2825 if (isVectorType(DestTy)) { 2825 if (isVectorType(DestTy)) {
2826 assert(DestTy == IceType_v4i32 && 2826 assert(DestTy == IceType_v4i32 &&
2827 Inst->getSrc(0)->getType() == IceType_v4f32); 2827 Instr->getSrc(0)->getType() == IceType_v4f32);
2828 Operand *Src0RM = legalize(Inst->getSrc(0), Legal_Reg | Legal_Mem); 2828 Operand *Src0RM = legalize(Instr->getSrc(0), Legal_Reg | Legal_Mem);
2829 if (llvm::isa<X86OperandMem>(Src0RM)) 2829 if (llvm::isa<X86OperandMem>(Src0RM))
2830 Src0RM = legalizeToReg(Src0RM); 2830 Src0RM = legalizeToReg(Src0RM);
2831 Variable *T = makeReg(DestTy); 2831 Variable *T = makeReg(DestTy);
2832 _cvt(T, Src0RM, Traits::Insts::Cvt::Tps2dq); 2832 _cvt(T, Src0RM, Traits::Insts::Cvt::Tps2dq);
2833 _movp(Dest, T); 2833 _movp(Dest, T);
2834 } else if (!Traits::Is64Bit && DestTy == IceType_i64) { 2834 } else if (!Traits::Is64Bit && DestTy == IceType_i64) {
2835 llvm::report_fatal_error("Helper call was expected"); 2835 llvm::report_fatal_error("Helper call was expected");
2836 } else { 2836 } else {
2837 Operand *Src0RM = legalize(Inst->getSrc(0), Legal_Reg | Legal_Mem); 2837 Operand *Src0RM = legalize(Instr->getSrc(0), Legal_Reg | Legal_Mem);
2838 // t1.i32 = cvt Src0RM; t2.dest_type = t1; Dest = t2.dest_type 2838 // t1.i32 = cvt Src0RM; t2.dest_type = t1; Dest = t2.dest_type
2839 Variable *T_1 = nullptr; 2839 Variable *T_1 = nullptr;
2840 if (Traits::Is64Bit && DestTy == IceType_i64) { 2840 if (Traits::Is64Bit && DestTy == IceType_i64) {
2841 T_1 = makeReg(IceType_i64); 2841 T_1 = makeReg(IceType_i64);
2842 } else { 2842 } else {
2843 assert(DestTy != IceType_i64); 2843 assert(DestTy != IceType_i64);
2844 T_1 = makeReg(IceType_i32); 2844 T_1 = makeReg(IceType_i32);
2845 } 2845 }
2846 // cvt() requires its integer argument to be a GPR. 2846 // cvt() requires its integer argument to be a GPR.
2847 Variable *T_2 = makeReg(DestTy); 2847 Variable *T_2 = makeReg(DestTy);
2848 if (isByteSizedType(DestTy)) { 2848 if (isByteSizedType(DestTy)) {
2849 assert(T_1->getType() == IceType_i32); 2849 assert(T_1->getType() == IceType_i32);
2850 T_1->setRegClass(RCX86_Is32To8); 2850 T_1->setRegClass(RCX86_Is32To8);
2851 T_2->setRegClass(RCX86_IsTrunc8Rcvr); 2851 T_2->setRegClass(RCX86_IsTrunc8Rcvr);
2852 } 2852 }
2853 _cvt(T_1, Src0RM, Traits::Insts::Cvt::Tss2si); 2853 _cvt(T_1, Src0RM, Traits::Insts::Cvt::Tss2si);
2854 _mov(T_2, T_1); // T_1 and T_2 may have different integer types 2854 _mov(T_2, T_1); // T_1 and T_2 may have different integer types
2855 if (DestTy == IceType_i1) 2855 if (DestTy == IceType_i1)
2856 _and(T_2, Ctx->getConstantInt1(1)); 2856 _and(T_2, Ctx->getConstantInt1(1));
2857 _mov(Dest, T_2); 2857 _mov(Dest, T_2);
2858 } 2858 }
2859 break; 2859 break;
2860 case InstCast::Fptoui: 2860 case InstCast::Fptoui:
2861 if (isVectorType(DestTy)) { 2861 if (isVectorType(DestTy)) {
2862 llvm::report_fatal_error("Helper call was expected"); 2862 llvm::report_fatal_error("Helper call was expected");
2863 } else if (DestTy == IceType_i64 || 2863 } else if (DestTy == IceType_i64 ||
2864 (!Traits::Is64Bit && DestTy == IceType_i32)) { 2864 (!Traits::Is64Bit && DestTy == IceType_i32)) {
2865 llvm::report_fatal_error("Helper call was expected"); 2865 llvm::report_fatal_error("Helper call was expected");
2866 } else { 2866 } else {
2867 Operand *Src0RM = legalize(Inst->getSrc(0), Legal_Reg | Legal_Mem); 2867 Operand *Src0RM = legalize(Instr->getSrc(0), Legal_Reg | Legal_Mem);
2868 // t1.i32 = cvt Src0RM; t2.dest_type = t1; Dest = t2.dest_type 2868 // t1.i32 = cvt Src0RM; t2.dest_type = t1; Dest = t2.dest_type
2869 assert(DestTy != IceType_i64); 2869 assert(DestTy != IceType_i64);
2870 Variable *T_1 = nullptr; 2870 Variable *T_1 = nullptr;
2871 if (Traits::Is64Bit && DestTy == IceType_i32) { 2871 if (Traits::Is64Bit && DestTy == IceType_i32) {
2872 T_1 = makeReg(IceType_i64); 2872 T_1 = makeReg(IceType_i64);
2873 } else { 2873 } else {
2874 assert(DestTy != IceType_i32); 2874 assert(DestTy != IceType_i32);
2875 T_1 = makeReg(IceType_i32); 2875 T_1 = makeReg(IceType_i32);
2876 } 2876 }
2877 Variable *T_2 = makeReg(DestTy); 2877 Variable *T_2 = makeReg(DestTy);
2878 if (isByteSizedType(DestTy)) { 2878 if (isByteSizedType(DestTy)) {
2879 assert(T_1->getType() == IceType_i32); 2879 assert(T_1->getType() == IceType_i32);
2880 T_1->setRegClass(RCX86_Is32To8); 2880 T_1->setRegClass(RCX86_Is32To8);
2881 T_2->setRegClass(RCX86_IsTrunc8Rcvr); 2881 T_2->setRegClass(RCX86_IsTrunc8Rcvr);
2882 } 2882 }
2883 _cvt(T_1, Src0RM, Traits::Insts::Cvt::Tss2si); 2883 _cvt(T_1, Src0RM, Traits::Insts::Cvt::Tss2si);
2884 _mov(T_2, T_1); // T_1 and T_2 may have different integer types 2884 _mov(T_2, T_1); // T_1 and T_2 may have different integer types
2885 if (DestTy == IceType_i1) 2885 if (DestTy == IceType_i1)
2886 _and(T_2, Ctx->getConstantInt1(1)); 2886 _and(T_2, Ctx->getConstantInt1(1));
2887 _mov(Dest, T_2); 2887 _mov(Dest, T_2);
2888 } 2888 }
2889 break; 2889 break;
2890 case InstCast::Sitofp: 2890 case InstCast::Sitofp:
2891 if (isVectorType(DestTy)) { 2891 if (isVectorType(DestTy)) {
2892 assert(DestTy == IceType_v4f32 && 2892 assert(DestTy == IceType_v4f32 &&
2893 Inst->getSrc(0)->getType() == IceType_v4i32); 2893 Instr->getSrc(0)->getType() == IceType_v4i32);
2894 Operand *Src0RM = legalize(Inst->getSrc(0), Legal_Reg | Legal_Mem); 2894 Operand *Src0RM = legalize(Instr->getSrc(0), Legal_Reg | Legal_Mem);
2895 if (llvm::isa<X86OperandMem>(Src0RM)) 2895 if (llvm::isa<X86OperandMem>(Src0RM))
2896 Src0RM = legalizeToReg(Src0RM); 2896 Src0RM = legalizeToReg(Src0RM);
2897 Variable *T = makeReg(DestTy); 2897 Variable *T = makeReg(DestTy);
2898 _cvt(T, Src0RM, Traits::Insts::Cvt::Dq2ps); 2898 _cvt(T, Src0RM, Traits::Insts::Cvt::Dq2ps);
2899 _movp(Dest, T); 2899 _movp(Dest, T);
2900 } else if (!Traits::Is64Bit && Inst->getSrc(0)->getType() == IceType_i64) { 2900 } else if (!Traits::Is64Bit && Instr->getSrc(0)->getType() == IceType_i64) {
2901 llvm::report_fatal_error("Helper call was expected"); 2901 llvm::report_fatal_error("Helper call was expected");
2902 } else { 2902 } else {
2903 Operand *Src0RM = legalize(Inst->getSrc(0), Legal_Reg | Legal_Mem); 2903 Operand *Src0RM = legalize(Instr->getSrc(0), Legal_Reg | Legal_Mem);
2904 // Sign-extend the operand. 2904 // Sign-extend the operand.
2905 // t1.i32 = movsx Src0RM; t2 = Cvt t1.i32; Dest = t2 2905 // t1.i32 = movsx Src0RM; t2 = Cvt t1.i32; Dest = t2
2906 Variable *T_1 = nullptr; 2906 Variable *T_1 = nullptr;
2907 if (Traits::Is64Bit && Src0RM->getType() == IceType_i64) { 2907 if (Traits::Is64Bit && Src0RM->getType() == IceType_i64) {
2908 T_1 = makeReg(IceType_i64); 2908 T_1 = makeReg(IceType_i64);
2909 } else { 2909 } else {
2910 assert(Src0RM->getType() != IceType_i64); 2910 assert(Src0RM->getType() != IceType_i64);
2911 T_1 = makeReg(IceType_i32); 2911 T_1 = makeReg(IceType_i32);
2912 } 2912 }
2913 Variable *T_2 = makeReg(DestTy); 2913 Variable *T_2 = makeReg(DestTy);
2914 if (Src0RM->getType() == T_1->getType()) 2914 if (Src0RM->getType() == T_1->getType())
2915 _mov(T_1, Src0RM); 2915 _mov(T_1, Src0RM);
2916 else 2916 else
2917 _movsx(T_1, Src0RM); 2917 _movsx(T_1, Src0RM);
2918 _cvt(T_2, T_1, Traits::Insts::Cvt::Si2ss); 2918 _cvt(T_2, T_1, Traits::Insts::Cvt::Si2ss);
2919 _mov(Dest, T_2); 2919 _mov(Dest, T_2);
2920 } 2920 }
2921 break; 2921 break;
2922 case InstCast::Uitofp: { 2922 case InstCast::Uitofp: {
2923 Operand *Src0 = Inst->getSrc(0); 2923 Operand *Src0 = Instr->getSrc(0);
2924 if (isVectorType(Src0->getType())) { 2924 if (isVectorType(Src0->getType())) {
2925 llvm::report_fatal_error("Helper call was expected"); 2925 llvm::report_fatal_error("Helper call was expected");
2926 } else if (Src0->getType() == IceType_i64 || 2926 } else if (Src0->getType() == IceType_i64 ||
2927 (!Traits::Is64Bit && Src0->getType() == IceType_i32)) { 2927 (!Traits::Is64Bit && Src0->getType() == IceType_i32)) {
2928 llvm::report_fatal_error("Helper call was expected"); 2928 llvm::report_fatal_error("Helper call was expected");
2929 } else { 2929 } else {
2930 Operand *Src0RM = legalize(Src0, Legal_Reg | Legal_Mem); 2930 Operand *Src0RM = legalize(Src0, Legal_Reg | Legal_Mem);
2931 // Zero-extend the operand. 2931 // Zero-extend the operand.
2932 // t1.i32 = movzx Src0RM; t2 = Cvt t1.i32; Dest = t2 2932 // t1.i32 = movzx Src0RM; t2 = Cvt t1.i32; Dest = t2
2933 Variable *T_1 = nullptr; 2933 Variable *T_1 = nullptr;
2934 if (Traits::Is64Bit && Src0RM->getType() == IceType_i32) { 2934 if (Traits::Is64Bit && Src0RM->getType() == IceType_i32) {
2935 T_1 = makeReg(IceType_i64); 2935 T_1 = makeReg(IceType_i64);
2936 } else { 2936 } else {
2937 assert(Src0RM->getType() != IceType_i64); 2937 assert(Src0RM->getType() != IceType_i64);
2938 assert(Traits::Is64Bit || Src0RM->getType() != IceType_i32); 2938 assert(Traits::Is64Bit || Src0RM->getType() != IceType_i32);
2939 T_1 = makeReg(IceType_i32); 2939 T_1 = makeReg(IceType_i32);
2940 } 2940 }
2941 Variable *T_2 = makeReg(DestTy); 2941 Variable *T_2 = makeReg(DestTy);
2942 if (Src0RM->getType() == T_1->getType()) 2942 if (Src0RM->getType() == T_1->getType())
2943 _mov(T_1, Src0RM); 2943 _mov(T_1, Src0RM);
2944 else 2944 else
2945 _movzx(T_1, Src0RM); 2945 _movzx(T_1, Src0RM);
2946 _cvt(T_2, T_1, Traits::Insts::Cvt::Si2ss); 2946 _cvt(T_2, T_1, Traits::Insts::Cvt::Si2ss);
2947 _mov(Dest, T_2); 2947 _mov(Dest, T_2);
2948 } 2948 }
2949 break; 2949 break;
2950 } 2950 }
2951 case InstCast::Bitcast: { 2951 case InstCast::Bitcast: {
2952 Operand *Src0 = Inst->getSrc(0); 2952 Operand *Src0 = Instr->getSrc(0);
2953 if (DestTy == Src0->getType()) { 2953 if (DestTy == Src0->getType()) {
2954 auto *Assign = InstAssign::create(Func, Dest, Src0); 2954 auto *Assign = InstAssign::create(Func, Dest, Src0);
2955 lowerAssign(Assign); 2955 lowerAssign(Assign);
2956 return; 2956 return;
2957 } 2957 }
2958 switch (DestTy) { 2958 switch (DestTy) {
2959 default: 2959 default:
2960 llvm_unreachable("Unexpected Bitcast dest type"); 2960 llvm_unreachable("Unexpected Bitcast dest type");
2961 case IceType_i8: { 2961 case IceType_i8: {
2962 llvm::report_fatal_error("Helper call was expected"); 2962 llvm::report_fatal_error("Helper call was expected");
(...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after
3085 _movp(Dest, legalizeToReg(Src0)); 3085 _movp(Dest, legalizeToReg(Src0));
3086 } break; 3086 } break;
3087 } 3087 }
3088 break; 3088 break;
3089 } 3089 }
3090 } 3090 }
3091 } 3091 }
3092 3092
3093 template <typename TraitsType> 3093 template <typename TraitsType>
3094 void TargetX86Base<TraitsType>::lowerExtractElement( 3094 void TargetX86Base<TraitsType>::lowerExtractElement(
3095 const InstExtractElement *Inst) { 3095 const InstExtractElement *Instr) {
3096 Operand *SourceVectNotLegalized = Inst->getSrc(0); 3096 Operand *SourceVectNotLegalized = Instr->getSrc(0);
3097 ConstantInteger32 *ElementIndex = 3097 ConstantInteger32 *ElementIndex =
3098 llvm::dyn_cast<ConstantInteger32>(Inst->getSrc(1)); 3098 llvm::dyn_cast<ConstantInteger32>(Instr->getSrc(1));
3099 // Only constant indices are allowed in PNaCl IR. 3099 // Only constant indices are allowed in PNaCl IR.
3100 assert(ElementIndex); 3100 assert(ElementIndex);
3101 3101
3102 unsigned Index = ElementIndex->getValue(); 3102 unsigned Index = ElementIndex->getValue();
3103 Type Ty = SourceVectNotLegalized->getType(); 3103 Type Ty = SourceVectNotLegalized->getType();
3104 Type ElementTy = typeElementType(Ty); 3104 Type ElementTy = typeElementType(Ty);
3105 Type InVectorElementTy = Traits::getInVectorElementType(Ty); 3105 Type InVectorElementTy = Traits::getInVectorElementType(Ty);
3106 3106
3107 // TODO(wala): Determine the best lowering sequences for each type. 3107 // TODO(wala): Determine the best lowering sequences for each type.
3108 bool CanUsePextr = Ty == IceType_v8i16 || Ty == IceType_v8i1 || 3108 bool CanUsePextr = Ty == IceType_v8i16 || Ty == IceType_v8i1 ||
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
3161 if (ElementTy == IceType_i1) { 3161 if (ElementTy == IceType_i1) {
3162 // Truncate extracted integers to i1s if necessary. 3162 // Truncate extracted integers to i1s if necessary.
3163 Variable *T = makeReg(IceType_i1); 3163 Variable *T = makeReg(IceType_i1);
3164 InstCast *Cast = 3164 InstCast *Cast =
3165 InstCast::create(Func, InstCast::Trunc, T, ExtractedElementR); 3165 InstCast::create(Func, InstCast::Trunc, T, ExtractedElementR);
3166 lowerCast(Cast); 3166 lowerCast(Cast);
3167 ExtractedElementR = T; 3167 ExtractedElementR = T;
3168 } 3168 }
3169 3169
3170 // Copy the element to the destination. 3170 // Copy the element to the destination.
3171 Variable *Dest = Inst->getDest(); 3171 Variable *Dest = Instr->getDest();
3172 _mov(Dest, ExtractedElementR); 3172 _mov(Dest, ExtractedElementR);
3173 } 3173 }
3174 3174
3175 template <typename TraitsType> 3175 template <typename TraitsType>
3176 void TargetX86Base<TraitsType>::lowerFcmp(const InstFcmp *Fcmp) { 3176 void TargetX86Base<TraitsType>::lowerFcmp(const InstFcmp *Fcmp) {
3177 Variable *Dest = Fcmp->getDest(); 3177 Variable *Dest = Fcmp->getDest();
3178 3178
3179 if (isVectorType(Dest->getType())) { 3179 if (isVectorType(Dest->getType())) {
3180 lowerFcmpVector(Fcmp); 3180 lowerFcmpVector(Fcmp);
3181 } else { 3181 } else {
(...skipping 562 matching lines...) Expand 10 before | Expand all | Expand 10 after
3744 Context.insert<InstFakeUse>(T); 3744 Context.insert<InstFakeUse>(T);
3745 Context.insert<InstFakeDef>(Dest); 3745 Context.insert<InstFakeDef>(Dest);
3746 _br(Traits::Cond::Br_ne, Br->getTargetTrue(), Br->getTargetFalse()); 3746 _br(Traits::Cond::Br_ne, Br->getTargetTrue(), Br->getTargetFalse());
3747 return; 3747 return;
3748 } 3748 }
3749 llvm::report_fatal_error("Unexpected consumer type"); 3749 llvm::report_fatal_error("Unexpected consumer type");
3750 } 3750 }
3751 3751
3752 template <typename TraitsType> 3752 template <typename TraitsType>
3753 void TargetX86Base<TraitsType>::lowerInsertElement( 3753 void TargetX86Base<TraitsType>::lowerInsertElement(
3754 const InstInsertElement *Inst) { 3754 const InstInsertElement *Instr) {
3755 Operand *SourceVectNotLegalized = Inst->getSrc(0); 3755 Operand *SourceVectNotLegalized = Instr->getSrc(0);
3756 Operand *ElementToInsertNotLegalized = Inst->getSrc(1); 3756 Operand *ElementToInsertNotLegalized = Instr->getSrc(1);
3757 ConstantInteger32 *ElementIndex = 3757 ConstantInteger32 *ElementIndex =
3758 llvm::dyn_cast<ConstantInteger32>(Inst->getSrc(2)); 3758 llvm::dyn_cast<ConstantInteger32>(Instr->getSrc(2));
3759 // Only constant indices are allowed in PNaCl IR. 3759 // Only constant indices are allowed in PNaCl IR.
3760 assert(ElementIndex); 3760 assert(ElementIndex);
3761 unsigned Index = ElementIndex->getValue(); 3761 unsigned Index = ElementIndex->getValue();
3762 assert(Index < typeNumElements(SourceVectNotLegalized->getType())); 3762 assert(Index < typeNumElements(SourceVectNotLegalized->getType()));
3763 3763
3764 Type Ty = SourceVectNotLegalized->getType(); 3764 Type Ty = SourceVectNotLegalized->getType();
3765 Type ElementTy = typeElementType(Ty); 3765 Type ElementTy = typeElementType(Ty);
3766 Type InVectorElementTy = Traits::getInVectorElementType(Ty); 3766 Type InVectorElementTy = Traits::getInVectorElementType(Ty);
3767 3767
3768 if (ElementTy == IceType_i1) { 3768 if (ElementTy == IceType_i1) {
(...skipping 24 matching lines...) Expand all
3793 // the use 3793 // the use
3794 // of r16 and r8 by converting them through getBaseReg(), while emitIAS() 3794 // of r16 and r8 by converting them through getBaseReg(), while emitIAS()
3795 // validates that the original and base register encodings are the same. 3795 // validates that the original and base register encodings are the same.
3796 if (ElementRM->getType() == IceType_i8 && 3796 if (ElementRM->getType() == IceType_i8 &&
3797 llvm::isa<Variable>(ElementRM)) { 3797 llvm::isa<Variable>(ElementRM)) {
3798 // Don't use ah/bh/ch/dh for pinsrb. 3798 // Don't use ah/bh/ch/dh for pinsrb.
3799 ElementRM = copyToReg8(ElementRM); 3799 ElementRM = copyToReg8(ElementRM);
3800 } 3800 }
3801 _pinsr(T, ElementRM, Ctx->getConstantInt32(Index)); 3801 _pinsr(T, ElementRM, Ctx->getConstantInt32(Index));
3802 } 3802 }
3803 _movp(Inst->getDest(), T); 3803 _movp(Instr->getDest(), T);
3804 } else if (Ty == IceType_v4i32 || Ty == IceType_v4f32 || Ty == IceType_v4i1) { 3804 } else if (Ty == IceType_v4i32 || Ty == IceType_v4f32 || Ty == IceType_v4i1) {
3805 // Use shufps or movss. 3805 // Use shufps or movss.
3806 Variable *ElementR = nullptr; 3806 Variable *ElementR = nullptr;
3807 Operand *SourceVectRM = 3807 Operand *SourceVectRM =
3808 legalize(SourceVectNotLegalized, Legal_Reg | Legal_Mem); 3808 legalize(SourceVectNotLegalized, Legal_Reg | Legal_Mem);
3809 3809
3810 if (InVectorElementTy == IceType_f32) { 3810 if (InVectorElementTy == IceType_f32) {
3811 // ElementR will be in an XMM register since it is floating point. 3811 // ElementR will be in an XMM register since it is floating point.
3812 ElementR = legalizeToReg(ElementToInsertNotLegalized); 3812 ElementR = legalizeToReg(ElementToInsertNotLegalized);
3813 } else { 3813 } else {
3814 // Copy an integer to an XMM register. 3814 // Copy an integer to an XMM register.
3815 Operand *T = legalize(ElementToInsertNotLegalized, Legal_Reg | Legal_Mem); 3815 Operand *T = legalize(ElementToInsertNotLegalized, Legal_Reg | Legal_Mem);
3816 ElementR = makeReg(Ty); 3816 ElementR = makeReg(Ty);
3817 _movd(ElementR, T); 3817 _movd(ElementR, T);
3818 } 3818 }
3819 3819
3820 if (Index == 0) { 3820 if (Index == 0) {
3821 Variable *T = makeReg(Ty); 3821 Variable *T = makeReg(Ty);
3822 _movp(T, SourceVectRM); 3822 _movp(T, SourceVectRM);
3823 _movss(T, ElementR); 3823 _movss(T, ElementR);
3824 _movp(Inst->getDest(), T); 3824 _movp(Instr->getDest(), T);
3825 return; 3825 return;
3826 } 3826 }
3827 3827
3828 // shufps treats the source and destination operands as vectors of four 3828 // shufps treats the source and destination operands as vectors of four
3829 // doublewords. The destination's two high doublewords are selected from 3829 // doublewords. The destination's two high doublewords are selected from
3830 // the source operand and the two low doublewords are selected from the 3830 // the source operand and the two low doublewords are selected from the
3831 // (original value of) the destination operand. An insertelement operation 3831 // (original value of) the destination operand. An insertelement operation
3832 // can be effected with a sequence of two shufps operations with 3832 // can be effected with a sequence of two shufps operations with
3833 // appropriate masks. In all cases below, Element[0] is being inserted into 3833 // appropriate masks. In all cases below, Element[0] is being inserted into
3834 // SourceVectOperand. Indices are ordered from left to right. 3834 // SourceVectOperand. Indices are ordered from left to right.
(...skipping 13 matching lines...) Expand all
3848 // T := T[0, 1] ElementR[3, 0] 3848 // T := T[0, 1] ElementR[3, 0]
3849 const unsigned char Mask1[3] = {0, 192, 128}; 3849 const unsigned char Mask1[3] = {0, 192, 128};
3850 const unsigned char Mask2[3] = {227, 196, 52}; 3850 const unsigned char Mask2[3] = {227, 196, 52};
3851 3851
3852 Constant *Mask1Constant = Ctx->getConstantInt32(Mask1[Index - 1]); 3852 Constant *Mask1Constant = Ctx->getConstantInt32(Mask1[Index - 1]);
3853 Constant *Mask2Constant = Ctx->getConstantInt32(Mask2[Index - 1]); 3853 Constant *Mask2Constant = Ctx->getConstantInt32(Mask2[Index - 1]);
3854 3854
3855 if (Index == 1) { 3855 if (Index == 1) {
3856 _shufps(ElementR, SourceVectRM, Mask1Constant); 3856 _shufps(ElementR, SourceVectRM, Mask1Constant);
3857 _shufps(ElementR, SourceVectRM, Mask2Constant); 3857 _shufps(ElementR, SourceVectRM, Mask2Constant);
3858 _movp(Inst->getDest(), ElementR); 3858 _movp(Instr->getDest(), ElementR);
3859 } else { 3859 } else {
3860 Variable *T = makeReg(Ty); 3860 Variable *T = makeReg(Ty);
3861 _movp(T, SourceVectRM); 3861 _movp(T, SourceVectRM);
3862 _shufps(ElementR, T, Mask1Constant); 3862 _shufps(ElementR, T, Mask1Constant);
3863 _shufps(T, ElementR, Mask2Constant); 3863 _shufps(T, ElementR, Mask2Constant);
3864 _movp(Inst->getDest(), T); 3864 _movp(Instr->getDest(), T);
3865 } 3865 }
3866 } else { 3866 } else {
3867 assert(Ty == IceType_v16i8 || Ty == IceType_v16i1); 3867 assert(Ty == IceType_v16i8 || Ty == IceType_v16i1);
3868 // Spill the value to a stack slot and perform the insertion in memory. 3868 // Spill the value to a stack slot and perform the insertion in memory.
3869 // 3869 //
3870 // TODO(wala): use legalize(SourceVectNotLegalized, Legal_Mem) when support 3870 // TODO(wala): use legalize(SourceVectNotLegalized, Legal_Mem) when support
3871 // for legalizing to mem is implemented. 3871 // for legalizing to mem is implemented.
3872 Variable *Slot = Func->makeVariable(Ty); 3872 Variable *Slot = Func->makeVariable(Ty);
3873 Slot->setMustNotHaveReg(); 3873 Slot->setMustNotHaveReg();
3874 _movp(Slot, legalizeToReg(SourceVectNotLegalized)); 3874 _movp(Slot, legalizeToReg(SourceVectNotLegalized));
3875 3875
3876 // Compute the location of the position to insert in memory. 3876 // Compute the location of the position to insert in memory.
3877 unsigned Offset = Index * typeWidthInBytes(InVectorElementTy); 3877 unsigned Offset = Index * typeWidthInBytes(InVectorElementTy);
3878 X86OperandMem *Loc = 3878 X86OperandMem *Loc =
3879 getMemoryOperandForStackSlot(InVectorElementTy, Slot, Offset); 3879 getMemoryOperandForStackSlot(InVectorElementTy, Slot, Offset);
3880 _store(legalizeToReg(ElementToInsertNotLegalized), Loc); 3880 _store(legalizeToReg(ElementToInsertNotLegalized), Loc);
3881 3881
3882 Variable *T = makeReg(Ty); 3882 Variable *T = makeReg(Ty);
3883 _movp(T, Slot); 3883 _movp(T, Slot);
3884 _movp(Inst->getDest(), T); 3884 _movp(Instr->getDest(), T);
3885 } 3885 }
3886 } 3886 }
3887 3887
3888 template <typename TraitsType> 3888 template <typename TraitsType>
3889 void TargetX86Base<TraitsType>::lowerIntrinsicCall( 3889 void TargetX86Base<TraitsType>::lowerIntrinsicCall(
3890 const InstIntrinsicCall *Instr) { 3890 const InstIntrinsicCall *Instr) {
3891 switch (Intrinsics::IntrinsicID ID = Instr->getIntrinsicInfo().ID) { 3891 switch (Intrinsics::IntrinsicID ID = Instr->getIntrinsicInfo().ID) {
3892 case Intrinsics::AtomicCmpxchg: { 3892 case Intrinsics::AtomicCmpxchg: {
3893 if (!Intrinsics::isMemoryOrderValid( 3893 if (!Intrinsics::isMemoryOrderValid(
3894 ID, getConstantMemoryOrder(Instr->getArg(3)), 3894 ID, getConstantMemoryOrder(Instr->getArg(3)),
(...skipping 1097 matching lines...) Expand 10 before | Expand all | Expand 10 after
4992 inline const Inst *matchShiftedIndex(Variable **Index, uint16_t *Shift); 4992 inline const Inst *matchShiftedIndex(Variable **Index, uint16_t *Shift);
4993 4993
4994 inline const Inst *matchOffsetBase(Variable **Base, 4994 inline const Inst *matchOffsetBase(Variable **Base,
4995 ConstantRelocatable **Relocatable, 4995 ConstantRelocatable **Relocatable,
4996 int32_t *Offset); 4996 int32_t *Offset);
4997 4997
4998 private: 4998 private:
4999 const Cfg *const Func; 4999 const Cfg *const Func;
5000 const VariablesMetadata *const VMetadata; 5000 const VariablesMetadata *const VMetadata;
5001 5001
5002 static bool isAdd(const Inst *Inst) { 5002 static bool isAdd(const Inst *Instr) {
5003 if (auto *Arith = llvm::dyn_cast_or_null<const InstArithmetic>(Inst)) { 5003 if (auto *Arith = llvm::dyn_cast_or_null<const InstArithmetic>(Instr)) {
5004 return (Arith->getOp() == InstArithmetic::Add); 5004 return (Arith->getOp() == InstArithmetic::Add);
5005 } 5005 }
5006 return false; 5006 return false;
5007 } 5007 }
5008 }; 5008 };
5009 5009
5010 void AddressOptimizer::dumpAddressOpt( 5010 void AddressOptimizer::dumpAddressOpt(
5011 const ConstantRelocatable *const Relocatable, int32_t Offset, 5011 const ConstantRelocatable *const Relocatable, int32_t Offset,
5012 const Variable *Base, const Variable *Index, uint16_t Shift, 5012 const Variable *Base, const Variable *Index, uint16_t Shift,
5013 const Inst *Reason) const { 5013 const Inst *Reason) const {
(...skipping 492 matching lines...) Expand 10 before | Expand all | Expand 10 after
5506 Variable *DestLoad = Load->getDest(); 5506 Variable *DestLoad = Load->getDest();
5507 Type Ty = DestLoad->getType(); 5507 Type Ty = DestLoad->getType();
5508 Operand *Src0 = formMemoryOperand(Load->getSourceAddress(), Ty); 5508 Operand *Src0 = formMemoryOperand(Load->getSourceAddress(), Ty);
5509 doMockBoundsCheck(Src0); 5509 doMockBoundsCheck(Src0);
5510 auto *Assign = InstAssign::create(Func, DestLoad, Src0); 5510 auto *Assign = InstAssign::create(Func, DestLoad, Src0);
5511 lowerAssign(Assign); 5511 lowerAssign(Assign);
5512 } 5512 }
5513 5513
5514 template <typename TraitsType> 5514 template <typename TraitsType>
5515 void TargetX86Base<TraitsType>::doAddressOptLoad() { 5515 void TargetX86Base<TraitsType>::doAddressOptLoad() {
5516 Inst *Inst = Context.getCur(); 5516 Inst *Instr = Context.getCur();
5517 Operand *Addr = Inst->getSrc(0); 5517 Operand *Addr = Instr->getSrc(0);
5518 Variable *Dest = Inst->getDest(); 5518 Variable *Dest = Instr->getDest();
5519 if (auto *OptAddr = computeAddressOpt(Inst, Dest->getType(), Addr)) { 5519 if (auto *OptAddr = computeAddressOpt(Instr, Dest->getType(), Addr)) {
5520 Inst->setDeleted(); 5520 Instr->setDeleted();
5521 Context.insert<InstLoad>(Dest, OptAddr); 5521 Context.insert<InstLoad>(Dest, OptAddr);
5522 } 5522 }
5523 } 5523 }
5524 5524
5525 template <typename TraitsType> 5525 template <typename TraitsType>
5526 void TargetX86Base<TraitsType>::randomlyInsertNop(float Probability, 5526 void TargetX86Base<TraitsType>::randomlyInsertNop(float Probability,
5527 RandomNumberGenerator &RNG) { 5527 RandomNumberGenerator &RNG) {
5528 RandomNumberGeneratorWrapper RNGW(RNG); 5528 RandomNumberGeneratorWrapper RNGW(RNG);
5529 if (RNGW.getTrueWithProbability(Probability)) { 5529 if (RNGW.getTrueWithProbability(Probability)) {
5530 _nop(RNGW(Traits::X86_NUM_NOP_VARIANTS)); 5530 _nop(RNGW(Traits::X86_NUM_NOP_VARIANTS));
5531 } 5531 }
5532 } 5532 }
5533 5533
5534 template <typename TraitsType> 5534 template <typename TraitsType>
5535 void TargetX86Base<TraitsType>::lowerPhi(const InstPhi * /*Inst*/) { 5535 void TargetX86Base<TraitsType>::lowerPhi(const InstPhi * /*Instr*/) {
5536 Func->setError("Phi found in regular instruction list"); 5536 Func->setError("Phi found in regular instruction list");
5537 } 5537 }
5538 5538
5539 template <typename TraitsType> 5539 template <typename TraitsType>
5540 void TargetX86Base<TraitsType>::lowerRet(const InstRet *Inst) { 5540 void TargetX86Base<TraitsType>::lowerRet(const InstRet *Instr) {
5541 Variable *Reg = nullptr; 5541 Variable *Reg = nullptr;
5542 if (Inst->hasRetValue()) { 5542 if (Instr->hasRetValue()) {
5543 Operand *RetValue = legalize(Inst->getRetValue()); 5543 Operand *RetValue = legalize(Instr->getRetValue());
5544 const Type ReturnType = RetValue->getType(); 5544 const Type ReturnType = RetValue->getType();
5545 assert(isVectorType(ReturnType) || isScalarFloatingType(ReturnType) || 5545 assert(isVectorType(ReturnType) || isScalarFloatingType(ReturnType) ||
5546 (ReturnType == IceType_i32) || (ReturnType == IceType_i64)); 5546 (ReturnType == IceType_i32) || (ReturnType == IceType_i64));
5547 Reg = moveReturnValueToRegister(RetValue, ReturnType); 5547 Reg = moveReturnValueToRegister(RetValue, ReturnType);
5548 } 5548 }
5549 // Add a ret instruction even if sandboxing is enabled, because addEpilog 5549 // Add a ret instruction even if sandboxing is enabled, because addEpilog
5550 // explicitly looks for a ret instruction as a marker for where to insert the 5550 // explicitly looks for a ret instruction as a marker for where to insert the
5551 // frame removal instructions. 5551 // frame removal instructions.
5552 _ret(Reg); 5552 _ret(Reg);
5553 // Add a fake use of esp to make sure esp stays alive for the entire 5553 // Add a fake use of esp to make sure esp stays alive for the entire
(...skipping 162 matching lines...) Expand 10 before | Expand all | Expand 10 after
5716 Variable *Dest = Icmp->getDest(); 5716 Variable *Dest = Icmp->getDest();
5717 if (isVectorType(Dest->getType())) { 5717 if (isVectorType(Dest->getType())) {
5718 lowerIcmpVector(Icmp); 5718 lowerIcmpVector(Icmp);
5719 } else { 5719 } else {
5720 constexpr Inst *Consumer = nullptr; 5720 constexpr Inst *Consumer = nullptr;
5721 lowerIcmpAndConsumer(Icmp, Consumer); 5721 lowerIcmpAndConsumer(Icmp, Consumer);
5722 } 5722 }
5723 } 5723 }
5724 5724
5725 template <typename TraitsType> 5725 template <typename TraitsType>
5726 void TargetX86Base<TraitsType>::lowerSelectVector(const InstSelect *Inst) { 5726 void TargetX86Base<TraitsType>::lowerSelectVector(const InstSelect *Instr) {
5727 Variable *Dest = Inst->getDest(); 5727 Variable *Dest = Instr->getDest();
5728 Type DestTy = Dest->getType(); 5728 Type DestTy = Dest->getType();
5729 Operand *SrcT = Inst->getTrueOperand(); 5729 Operand *SrcT = Instr->getTrueOperand();
5730 Operand *SrcF = Inst->getFalseOperand(); 5730 Operand *SrcF = Instr->getFalseOperand();
5731 Operand *Condition = Inst->getCondition(); 5731 Operand *Condition = Instr->getCondition();
5732 5732
5733 if (!isVectorType(DestTy)) 5733 if (!isVectorType(DestTy))
5734 llvm::report_fatal_error("Expected a vector select"); 5734 llvm::report_fatal_error("Expected a vector select");
5735 5735
5736 Type SrcTy = SrcT->getType(); 5736 Type SrcTy = SrcT->getType();
5737 Variable *T = makeReg(SrcTy); 5737 Variable *T = makeReg(SrcTy);
5738 Operand *SrcTRM = legalize(SrcT, Legal_Reg | Legal_Mem); 5738 Operand *SrcTRM = legalize(SrcT, Legal_Reg | Legal_Mem);
5739 Operand *SrcFRM = legalize(SrcF, Legal_Reg | Legal_Mem); 5739 Operand *SrcFRM = legalize(SrcF, Legal_Reg | Legal_Mem);
5740 if (InstructionSet >= Traits::SSE4_1) { 5740 if (InstructionSet >= Traits::SSE4_1) {
5741 // TODO(wala): If the condition operand is a constant, use blendps or 5741 // TODO(wala): If the condition operand is a constant, use blendps or
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
5784 _movp(T2, T); 5784 _movp(T2, T);
5785 _pand(T, SrcTRM); 5785 _pand(T, SrcTRM);
5786 _pandn(T2, SrcFRM); 5786 _pandn(T2, SrcFRM);
5787 _por(T, T2); 5787 _por(T, T2);
5788 _movp(Dest, T); 5788 _movp(Dest, T);
5789 5789
5790 return; 5790 return;
5791 } 5791 }
5792 5792
5793 template <typename TraitsType> 5793 template <typename TraitsType>
5794 void TargetX86Base<TraitsType>::lowerStore(const InstStore *Inst) { 5794 void TargetX86Base<TraitsType>::lowerStore(const InstStore *Instr) {
5795 Operand *Value = Inst->getData(); 5795 Operand *Value = Instr->getData();
5796 Operand *Addr = Inst->getAddr(); 5796 Operand *Addr = Instr->getAddr();
5797 X86OperandMem *NewAddr = formMemoryOperand(Addr, Value->getType()); 5797 X86OperandMem *NewAddr = formMemoryOperand(Addr, Value->getType());
5798 doMockBoundsCheck(NewAddr); 5798 doMockBoundsCheck(NewAddr);
5799 Type Ty = NewAddr->getType(); 5799 Type Ty = NewAddr->getType();
5800 5800
5801 if (!Traits::Is64Bit && Ty == IceType_i64) { 5801 if (!Traits::Is64Bit && Ty == IceType_i64) {
5802 Value = legalizeUndef(Value); 5802 Value = legalizeUndef(Value);
5803 Operand *ValueHi = legalize(hiOperand(Value), Legal_Reg | Legal_Imm); 5803 Operand *ValueHi = legalize(hiOperand(Value), Legal_Reg | Legal_Imm);
5804 _store(ValueHi, llvm::cast<X86OperandMem>(hiOperand(NewAddr))); 5804 _store(ValueHi, llvm::cast<X86OperandMem>(hiOperand(NewAddr)));
5805 Operand *ValueLo = legalize(loOperand(Value), Legal_Reg | Legal_Imm); 5805 Operand *ValueLo = legalize(loOperand(Value), Legal_Reg | Legal_Imm);
5806 _store(ValueLo, llvm::cast<X86OperandMem>(loOperand(NewAddr))); 5806 _store(ValueLo, llvm::cast<X86OperandMem>(loOperand(NewAddr)));
5807 } else if (isVectorType(Ty)) { 5807 } else if (isVectorType(Ty)) {
5808 _storep(legalizeToReg(Value), NewAddr); 5808 _storep(legalizeToReg(Value), NewAddr);
5809 } else { 5809 } else {
5810 Value = legalize(Value, Legal_Reg | Legal_Imm); 5810 Value = legalize(Value, Legal_Reg | Legal_Imm);
5811 _store(Value, NewAddr); 5811 _store(Value, NewAddr);
5812 } 5812 }
5813 } 5813 }
5814 5814
5815 template <typename TraitsType> 5815 template <typename TraitsType>
5816 void TargetX86Base<TraitsType>::doAddressOptStore() { 5816 void TargetX86Base<TraitsType>::doAddressOptStore() {
5817 auto *Inst = llvm::cast<InstStore>(Context.getCur()); 5817 auto *Instr = llvm::cast<InstStore>(Context.getCur());
5818 Operand *Addr = Inst->getAddr(); 5818 Operand *Addr = Instr->getAddr();
5819 Operand *Data = Inst->getData(); 5819 Operand *Data = Instr->getData();
5820 if (auto *OptAddr = computeAddressOpt(Inst, Data->getType(), Addr)) { 5820 if (auto *OptAddr = computeAddressOpt(Instr, Data->getType(), Addr)) {
5821 Inst->setDeleted(); 5821 Instr->setDeleted();
5822 auto *NewStore = Context.insert<InstStore>(Data, OptAddr); 5822 auto *NewStore = Context.insert<InstStore>(Data, OptAddr);
5823 if (Inst->getDest()) 5823 if (Instr->getDest())
5824 NewStore->setRmwBeacon(Inst->getRmwBeacon()); 5824 NewStore->setRmwBeacon(Instr->getRmwBeacon());
5825 } 5825 }
5826 } 5826 }
5827 5827
5828 template <typename TraitsType> 5828 template <typename TraitsType>
5829 Operand *TargetX86Base<TraitsType>::lowerCmpRange(Operand *Comparison, 5829 Operand *TargetX86Base<TraitsType>::lowerCmpRange(Operand *Comparison,
5830 uint64_t Min, uint64_t Max) { 5830 uint64_t Min, uint64_t Max) {
5831 // TODO(ascull): 64-bit should not reach here but only because it is not 5831 // TODO(ascull): 64-bit should not reach here but only because it is not
5832 // implemented yet. This should be able to handle the 64-bit case. 5832 // implemented yet. This should be able to handle the 64-bit case.
5833 assert(Traits::Is64Bit || Comparison->getType() != IceType_i64); 5833 assert(Traits::Is64Bit || Comparison->getType() != IceType_i64);
5834 // Subtracting 0 is a nop so don't do it 5834 // Subtracting 0 is a nop so don't do it
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after
5921 _br(Traits::Cond::Br_be, Case.getTarget()); 5921 _br(Traits::Cond::Br_be, Case.getTarget());
5922 } 5922 }
5923 if (DefaultTarget != nullptr) 5923 if (DefaultTarget != nullptr)
5924 _br(DefaultTarget); 5924 _br(DefaultTarget);
5925 return; 5925 return;
5926 } 5926 }
5927 } 5927 }
5928 } 5928 }
5929 5929
5930 template <typename TraitsType> 5930 template <typename TraitsType>
5931 void TargetX86Base<TraitsType>::lowerSwitch(const InstSwitch *Inst) { 5931 void TargetX86Base<TraitsType>::lowerSwitch(const InstSwitch *Instr) {
5932 // Group cases together and navigate through them with a binary search 5932 // Group cases together and navigate through them with a binary search
5933 CaseClusterArray CaseClusters = CaseCluster::clusterizeSwitch(Func, Inst); 5933 CaseClusterArray CaseClusters = CaseCluster::clusterizeSwitch(Func, Instr);
5934 Operand *Src0 = Inst->getComparison(); 5934 Operand *Src0 = Instr->getComparison();
5935 CfgNode *DefaultTarget = Inst->getLabelDefault(); 5935 CfgNode *DefaultTarget = Instr->getLabelDefault();
5936 5936
5937 assert(CaseClusters.size() != 0); // Should always be at least one 5937 assert(CaseClusters.size() != 0); // Should always be at least one
5938 5938
5939 if (!Traits::Is64Bit && Src0->getType() == IceType_i64) { 5939 if (!Traits::Is64Bit && Src0->getType() == IceType_i64) {
5940 Src0 = legalize(Src0); // get Base/Index into physical registers 5940 Src0 = legalize(Src0); // get Base/Index into physical registers
5941 Operand *Src0Lo = loOperand(Src0); 5941 Operand *Src0Lo = loOperand(Src0);
5942 Operand *Src0Hi = hiOperand(Src0); 5942 Operand *Src0Hi = hiOperand(Src0);
5943 if (CaseClusters.back().getHigh() > UINT32_MAX) { 5943 if (CaseClusters.back().getHigh() > UINT32_MAX) {
5944 // TODO(ascull): handle 64-bit case properly (currently naive version) 5944 // TODO(ascull): handle 64-bit case properly (currently naive version)
5945 // This might be handled by a higher level lowering of switches. 5945 // This might be handled by a higher level lowering of switches.
5946 SizeT NumCases = Inst->getNumCases(); 5946 SizeT NumCases = Instr->getNumCases();
5947 if (NumCases >= 2) { 5947 if (NumCases >= 2) {
5948 Src0Lo = legalizeToReg(Src0Lo); 5948 Src0Lo = legalizeToReg(Src0Lo);
5949 Src0Hi = legalizeToReg(Src0Hi); 5949 Src0Hi = legalizeToReg(Src0Hi);
5950 } else { 5950 } else {
5951 Src0Lo = legalize(Src0Lo, Legal_Reg | Legal_Mem); 5951 Src0Lo = legalize(Src0Lo, Legal_Reg | Legal_Mem);
5952 Src0Hi = legalize(Src0Hi, Legal_Reg | Legal_Mem); 5952 Src0Hi = legalize(Src0Hi, Legal_Reg | Legal_Mem);
5953 } 5953 }
5954 for (SizeT I = 0; I < NumCases; ++I) { 5954 for (SizeT I = 0; I < NumCases; ++I) {
5955 Constant *ValueLo = Ctx->getConstantInt32(Inst->getValue(I)); 5955 Constant *ValueLo = Ctx->getConstantInt32(Instr->getValue(I));
5956 Constant *ValueHi = Ctx->getConstantInt32(Inst->getValue(I) >> 32); 5956 Constant *ValueHi = Ctx->getConstantInt32(Instr->getValue(I) >> 32);
5957 InstX86Label *Label = InstX86Label::create(Func, this); 5957 InstX86Label *Label = InstX86Label::create(Func, this);
5958 _cmp(Src0Lo, ValueLo); 5958 _cmp(Src0Lo, ValueLo);
5959 _br(Traits::Cond::Br_ne, Label); 5959 _br(Traits::Cond::Br_ne, Label);
5960 _cmp(Src0Hi, ValueHi); 5960 _cmp(Src0Hi, ValueHi);
5961 _br(Traits::Cond::Br_e, Inst->getLabel(I)); 5961 _br(Traits::Cond::Br_e, Instr->getLabel(I));
5962 Context.insert(Label); 5962 Context.insert(Label);
5963 } 5963 }
5964 _br(Inst->getLabelDefault()); 5964 _br(Instr->getLabelDefault());
5965 return; 5965 return;
5966 } else { 5966 } else {
5967 // All the values are 32-bit so just check the operand is too and then 5967 // All the values are 32-bit so just check the operand is too and then
5968 // fall through to the 32-bit implementation. This is a common case. 5968 // fall through to the 32-bit implementation. This is a common case.
5969 Src0Hi = legalize(Src0Hi, Legal_Reg | Legal_Mem); 5969 Src0Hi = legalize(Src0Hi, Legal_Reg | Legal_Mem);
5970 Constant *Zero = Ctx->getConstantInt32(0); 5970 Constant *Zero = Ctx->getConstantInt32(0);
5971 _cmp(Src0Hi, Zero); 5971 _cmp(Src0Hi, Zero);
5972 _br(Traits::Cond::Br_ne, DefaultTarget); 5972 _br(Traits::Cond::Br_ne, DefaultTarget);
5973 Src0 = Src0Lo; 5973 Src0 = Src0Lo;
5974 } 5974 }
(...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after
6116 NextCast->setDeleted(); 6116 NextCast->setDeleted();
6117 _movp(NextCast->getDest(), legalizeToReg(SignExtendedResult)); 6117 _movp(NextCast->getDest(), legalizeToReg(SignExtendedResult));
6118 // Skip over the instruction. 6118 // Skip over the instruction.
6119 Context.advanceNext(); 6119 Context.advanceNext();
6120 } 6120 }
6121 } 6121 }
6122 } 6122 }
6123 6123
6124 template <typename TraitsType> 6124 template <typename TraitsType>
6125 void TargetX86Base<TraitsType>::lowerUnreachable( 6125 void TargetX86Base<TraitsType>::lowerUnreachable(
6126 const InstUnreachable * /*Inst*/) { 6126 const InstUnreachable * /*Instr*/) {
6127 _ud2(); 6127 _ud2();
6128 // Add a fake use of esp to make sure esp adjustments after the unreachable 6128 // Add a fake use of esp to make sure esp adjustments after the unreachable
6129 // do not get dead-code eliminated. 6129 // do not get dead-code eliminated.
6130 keepEspLiveAtExit(); 6130 keepEspLiveAtExit();
6131 } 6131 }
6132 6132
6133 template <typename TraitsType> 6133 template <typename TraitsType>
6134 void TargetX86Base<TraitsType>::lowerRMW(const InstX86FakeRMW *RMW) { 6134 void TargetX86Base<TraitsType>::lowerRMW(const InstX86FakeRMW *RMW) {
6135 // If the beacon variable's live range does not end in this instruction, then 6135 // If the beacon variable's live range does not end in this instruction, then
6136 // it must end in the modified Store instruction that follows. This means 6136 // it must end in the modified Store instruction that follows. This means
(...skipping 1318 matching lines...) Expand 10 before | Expand all | Expand 10 after
7455 emitGlobal(*Var, SectionSuffix); 7455 emitGlobal(*Var, SectionSuffix);
7456 } 7456 }
7457 } 7457 }
7458 } break; 7458 } break;
7459 } 7459 }
7460 } 7460 }
7461 } // end of namespace X86NAMESPACE 7461 } // end of namespace X86NAMESPACE
7462 } // end of namespace Ice 7462 } // end of namespace Ice
7463 7463
7464 #endif // SUBZERO_SRC_ICETARGETLOWERINGX86BASEIMPL_H 7464 #endif // SUBZERO_SRC_ICETARGETLOWERINGX86BASEIMPL_H
OLDNEW
« no previous file with comments | « src/IceTargetLoweringX86Base.h ('k') | src/PNaClTranslator.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698