OLD | NEW |
1 //===- subzero/src/PNaClTranslator.cpp - ICE from bitcode -----------------===// | 1 //===- subzero/src/PNaClTranslator.cpp - ICE from bitcode -----------------===// |
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 // This file implements the PNaCl bitcode file to Ice, to machine code | 10 // This file implements the PNaCl bitcode file to Ice, to machine code |
(...skipping 1584 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1595 return isValidIntegerLogicalOp(Op, Ty); | 1595 return isValidIntegerLogicalOp(Op, Ty); |
1596 case naclbitc::BINOP_OR: | 1596 case naclbitc::BINOP_OR: |
1597 Op = Ice::InstArithmetic::Or; | 1597 Op = Ice::InstArithmetic::Or; |
1598 return isValidIntegerLogicalOp(Op, Ty); | 1598 return isValidIntegerLogicalOp(Op, Ty); |
1599 case naclbitc::BINOP_XOR: | 1599 case naclbitc::BINOP_XOR: |
1600 Op = Ice::InstArithmetic::Xor; | 1600 Op = Ice::InstArithmetic::Xor; |
1601 return isValidIntegerLogicalOp(Op, Ty); | 1601 return isValidIntegerLogicalOp(Op, Ty); |
1602 } | 1602 } |
1603 } | 1603 } |
1604 | 1604 |
1605 /// Converts an LLVM cast opcode LLVMCastOp to the corresponding Ice | 1605 /// Simplifies out vector types from Type1 and Type2, if both are vectors |
1606 /// cast opcode and assigns to CastKind. Returns true if successful, | 1606 /// of the same size. Returns true iff both are vectors of the same size, |
1607 /// false otherwise. | 1607 /// or are both scalar types. |
1608 bool convertLLVMCastOpToIceOp(Instruction::CastOps LLVMCastOp, | 1608 static bool simplifyOutCommonVectorType(Ice::Type &Type1, Ice::Type &Type2) { |
1609 Ice::InstCast::OpKind &CastKind) const { | 1609 bool IsType1Vector = isVectorType(Type1); |
1610 switch (LLVMCastOp) { | 1610 bool IsType2Vector = isVectorType(Type2); |
1611 case Instruction::ZExt: | 1611 if (IsType1Vector != IsType2Vector) |
1612 CastKind = Ice::InstCast::Zext; | |
1613 break; | |
1614 case Instruction::SExt: | |
1615 CastKind = Ice::InstCast::Sext; | |
1616 break; | |
1617 case Instruction::Trunc: | |
1618 CastKind = Ice::InstCast::Trunc; | |
1619 break; | |
1620 case Instruction::FPTrunc: | |
1621 CastKind = Ice::InstCast::Fptrunc; | |
1622 break; | |
1623 case Instruction::FPExt: | |
1624 CastKind = Ice::InstCast::Fpext; | |
1625 break; | |
1626 case Instruction::FPToSI: | |
1627 CastKind = Ice::InstCast::Fptosi; | |
1628 break; | |
1629 case Instruction::FPToUI: | |
1630 CastKind = Ice::InstCast::Fptoui; | |
1631 break; | |
1632 case Instruction::SIToFP: | |
1633 CastKind = Ice::InstCast::Sitofp; | |
1634 break; | |
1635 case Instruction::UIToFP: | |
1636 CastKind = Ice::InstCast::Uitofp; | |
1637 break; | |
1638 case Instruction::BitCast: | |
1639 CastKind = Ice::InstCast::Bitcast; | |
1640 break; | |
1641 default: | |
1642 return false; | 1612 return false; |
| 1613 if (!IsType1Vector) |
| 1614 return true; |
| 1615 if (typeNumElements(Type1) != typeNumElements(Type2)) |
| 1616 return false; |
| 1617 Type1 = typeElementType(Type1); |
| 1618 Type2 = typeElementType(Type2); |
| 1619 return true; |
| 1620 } |
| 1621 |
| 1622 /// Returns true iff an integer truncation from SourceType to TargetType is |
| 1623 /// valid. |
| 1624 static bool isIntTruncCastValid(Ice::Type SourceType, Ice::Type TargetType) { |
| 1625 return Ice::isIntegerType(SourceType) |
| 1626 && Ice::isIntegerType(TargetType) |
| 1627 && simplifyOutCommonVectorType(SourceType, TargetType) |
| 1628 && getScalarIntBitWidth(SourceType) > getScalarIntBitWidth(TargetType); |
| 1629 } |
| 1630 |
| 1631 /// Returns true iff a floating type truncation from SourceType to TargetType |
| 1632 /// is valid. |
| 1633 static bool isFloatTruncCastValid(Ice::Type SourceType, |
| 1634 Ice::Type TargetType) { |
| 1635 return simplifyOutCommonVectorType(SourceType, TargetType) |
| 1636 && SourceType == Ice::IceType_f64 |
| 1637 && TargetType == Ice::IceType_f32; |
| 1638 } |
| 1639 |
| 1640 /// Returns true iff an integer extension from SourceType to TargetType is |
| 1641 /// valid. |
| 1642 static bool isIntExtCastValid(Ice::Type SourceType, Ice::Type TargetType) { |
| 1643 return isIntTruncCastValid(TargetType, SourceType); |
| 1644 } |
| 1645 |
| 1646 /// Returns true iff a floating type extension from SourceType to TargetType |
| 1647 /// is valid. |
| 1648 static bool isFloatExtCastValid(Ice::Type SourceType, Ice::Type TargetType) { |
| 1649 return isFloatTruncCastValid(TargetType, SourceType); |
| 1650 } |
| 1651 |
| 1652 /// Returns true iff a cast from floating type SourceType to integer |
| 1653 /// type TargetType is valid. |
| 1654 static bool isFloatToIntCastValid(Ice::Type SourceType, |
| 1655 Ice::Type TargetType) { |
| 1656 if (!(Ice::isFloatingType(SourceType) && Ice::isIntegerType(TargetType))) |
| 1657 return false; |
| 1658 bool IsSourceVector = isVectorType(SourceType); |
| 1659 bool IsTargetVector = isVectorType(TargetType); |
| 1660 if (IsSourceVector != IsTargetVector) |
| 1661 return false; |
| 1662 if (IsSourceVector) { |
| 1663 return typeNumElements(SourceType) == typeNumElements(TargetType); |
1643 } | 1664 } |
1644 return true; | 1665 return true; |
1645 } | 1666 } |
1646 | 1667 |
| 1668 /// Returns true iff a cast from integer type SourceType to floating |
| 1669 /// type TargetType is valid. |
| 1670 static bool isIntToFloatCastValid(Ice::Type SourceType, |
| 1671 Ice::Type TargetType) { |
| 1672 return isFloatToIntCastValid(TargetType, SourceType); |
| 1673 } |
| 1674 |
| 1675 /// Returns the number of bits used to model type Ty when defining the |
| 1676 /// bitcast instruction. |
| 1677 static Ice::SizeT bitcastSizeInBits(Ice::Type Ty) { |
| 1678 if (Ice::isVectorType(Ty)) |
| 1679 return Ice::typeNumElements(Ty) * |
| 1680 bitcastSizeInBits(Ice::typeElementType(Ty)); |
| 1681 if (Ty == Ice::IceType_i1) |
| 1682 return 1; |
| 1683 return Ice::typeWidthInBytes(Ty) * CHAR_BIT; |
| 1684 } |
| 1685 |
| 1686 /// Returns true iff a bitcast from SourceType to TargetType is allowed. |
| 1687 static bool isBitcastValid(Ice::Type SourceType, Ice::Type TargetType) { |
| 1688 return bitcastSizeInBits(SourceType) == bitcastSizeInBits(TargetType); |
| 1689 } |
| 1690 |
| 1691 /// Returns true iff the NaCl bitcode Opcode is a valid cast opcode |
| 1692 /// for converting SourceType to TargetType. Updates CastKind to the |
| 1693 /// corresponding instruction cast opcode. Also generates an error |
| 1694 /// message when this function returns false. |
| 1695 bool convertCastOpToIceOp(uint64_t Opcode, Ice::Type SourceType, |
| 1696 Ice::Type TargetType, |
| 1697 Ice::InstCast::OpKind &CastKind) { |
| 1698 bool Result; |
| 1699 switch (Opcode) { |
| 1700 default: { |
| 1701 std::string Buffer; |
| 1702 raw_string_ostream StrBuf(Buffer); |
| 1703 StrBuf << "Cast opcode " << Opcode << " not understood.\n"; |
| 1704 Error(StrBuf.str()); |
| 1705 // TODO(kschimpf) Remove error recovery once implementation complete. |
| 1706 CastKind = Ice::InstCast::Bitcast; |
| 1707 return false; |
| 1708 } |
| 1709 case naclbitc::CAST_TRUNC: |
| 1710 CastKind = Ice::InstCast::Trunc; |
| 1711 Result = isIntTruncCastValid(SourceType, TargetType); |
| 1712 break; |
| 1713 case naclbitc::CAST_ZEXT: |
| 1714 CastKind = Ice::InstCast::Zext; |
| 1715 Result = isIntExtCastValid(SourceType, TargetType); |
| 1716 break; |
| 1717 case naclbitc::CAST_SEXT: |
| 1718 CastKind = Ice::InstCast::Sext; |
| 1719 Result = isIntExtCastValid(SourceType, TargetType); |
| 1720 break; |
| 1721 case naclbitc::CAST_FPTOUI: |
| 1722 CastKind = Ice::InstCast::Fptoui; |
| 1723 Result = isFloatToIntCastValid(SourceType, TargetType); |
| 1724 break; |
| 1725 case naclbitc::CAST_FPTOSI: |
| 1726 CastKind = Ice::InstCast::Fptosi; |
| 1727 Result = isFloatToIntCastValid(SourceType, TargetType); |
| 1728 break; |
| 1729 case naclbitc::CAST_UITOFP: |
| 1730 CastKind = Ice::InstCast::Uitofp; |
| 1731 Result = isIntToFloatCastValid(SourceType, TargetType); |
| 1732 break; |
| 1733 case naclbitc::CAST_SITOFP: |
| 1734 CastKind = Ice::InstCast::Sitofp; |
| 1735 Result = isIntToFloatCastValid(SourceType, TargetType); |
| 1736 break; |
| 1737 case naclbitc::CAST_FPTRUNC: |
| 1738 CastKind = Ice::InstCast::Fptrunc; |
| 1739 Result = isFloatTruncCastValid(SourceType, TargetType); |
| 1740 break; |
| 1741 case naclbitc::CAST_FPEXT: |
| 1742 CastKind = Ice::InstCast::Fpext; |
| 1743 Result = isFloatExtCastValid(SourceType, TargetType); |
| 1744 break; |
| 1745 case naclbitc::CAST_BITCAST: |
| 1746 CastKind = Ice::InstCast::Bitcast; |
| 1747 Result = isBitcastValid(SourceType, TargetType); |
| 1748 break; |
| 1749 } |
| 1750 if (!Result) { |
| 1751 std::string Buffer; |
| 1752 raw_string_ostream StrBuf(Buffer); |
| 1753 StrBuf << "Illegal cast: " << Ice::InstCast::getCastName(CastKind) << " " |
| 1754 << SourceType << " to " << TargetType; |
| 1755 Error(StrBuf.str()); |
| 1756 } |
| 1757 return Result; |
| 1758 } |
| 1759 |
1647 // Converts PNaCl bitcode Icmp operator to corresponding ICE op. | 1760 // Converts PNaCl bitcode Icmp operator to corresponding ICE op. |
1648 // Returns true if able to convert, false otherwise. | 1761 // Returns true if able to convert, false otherwise. |
1649 bool convertNaClBitcICmpOpToIce(uint64_t Op, | 1762 bool convertNaClBitcICmpOpToIce(uint64_t Op, |
1650 Ice::InstIcmp::ICond &Cond) const { | 1763 Ice::InstIcmp::ICond &Cond) const { |
1651 switch (Op) { | 1764 switch (Op) { |
1652 case naclbitc::ICMP_EQ: | 1765 case naclbitc::ICMP_EQ: |
1653 Cond = Ice::InstIcmp::Eq; | 1766 Cond = Ice::InstIcmp::Eq; |
1654 return true; | 1767 return true; |
1655 case naclbitc::ICMP_NE: | 1768 case naclbitc::ICMP_NE: |
1656 Cond = Ice::InstIcmp::Ne; | 1769 Cond = Ice::InstIcmp::Ne; |
(...skipping 210 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1867 CurrentNode->appendInst(Ice::InstArithmetic::create( | 1980 CurrentNode->appendInst(Ice::InstArithmetic::create( |
1868 Func, Opcode, getNextInstVar(Type1), Op1, Op2)); | 1981 Func, Opcode, getNextInstVar(Type1), Op1, Op2)); |
1869 return; | 1982 return; |
1870 } | 1983 } |
1871 case naclbitc::FUNC_CODE_INST_CAST: { | 1984 case naclbitc::FUNC_CODE_INST_CAST: { |
1872 // CAST: [opval, destty, castopc] | 1985 // CAST: [opval, destty, castopc] |
1873 if (!isValidRecordSize(3, "cast")) | 1986 if (!isValidRecordSize(3, "cast")) |
1874 return; | 1987 return; |
1875 Ice::Operand *Src = getRelativeOperand(Values[0], BaseIndex); | 1988 Ice::Operand *Src = getRelativeOperand(Values[0], BaseIndex); |
1876 Ice::Type CastType = Context->getSimpleTypeByID(Values[1]); | 1989 Ice::Type CastType = Context->getSimpleTypeByID(Values[1]); |
1877 Instruction::CastOps LLVMCastOp; | |
1878 Ice::InstCast::OpKind CastKind; | 1990 Ice::InstCast::OpKind CastKind; |
1879 if (!naclbitc::DecodeCastOpcode(Values[2], LLVMCastOp) || | |
1880 !convertLLVMCastOpToIceOp(LLVMCastOp, CastKind)) { | |
1881 std::string Buffer; | |
1882 raw_string_ostream StrBuf(Buffer); | |
1883 StrBuf << "Cast opcode not understood: " << Values[2]; | |
1884 Error(StrBuf.str()); | |
1885 appendErrorInstruction(CastType); | |
1886 return; | |
1887 } | |
1888 if (isIRGenerationDisabled()) { | 1991 if (isIRGenerationDisabled()) { |
1889 assert(Src == nullptr); | 1992 assert(Src == nullptr); |
1890 setNextLocalInstIndex(nullptr); | 1993 setNextLocalInstIndex(nullptr); |
1891 return; | 1994 return; |
1892 } | 1995 } |
1893 Ice::Type SrcType = Src->getType(); | 1996 if (!convertCastOpToIceOp(Values[2], Src->getType(), CastType, CastKind)) { |
1894 if (!CastInst::castIsValid(LLVMCastOp, Context->convertToLLVMType(SrcType), | |
1895 Context->convertToLLVMType(CastType))) { | |
1896 std::string Buffer; | |
1897 raw_string_ostream StrBuf(Buffer); | |
1898 StrBuf << "Illegal cast: " << Instruction::getOpcodeName(LLVMCastOp) | |
1899 << " " << SrcType << " to " << CastType; | |
1900 Error(StrBuf.str()); | |
1901 appendErrorInstruction(CastType); | 1997 appendErrorInstruction(CastType); |
1902 return; | 1998 return; |
1903 } | 1999 } |
1904 CurrentNode->appendInst( | 2000 CurrentNode->appendInst( |
1905 Ice::InstCast::create(Func, CastKind, getNextInstVar(CastType), Src)); | 2001 Ice::InstCast::create(Func, CastKind, getNextInstVar(CastType), Src)); |
1906 return; | 2002 return; |
1907 } | 2003 } |
1908 case naclbitc::FUNC_CODE_INST_VSELECT: { | 2004 case naclbitc::FUNC_CODE_INST_VSELECT: { |
1909 // VSELECT: [opval, opval, pred] | 2005 // VSELECT: [opval, opval, pred] |
1910 if (!isValidRecordSize(3, "select")) | 2006 if (!isValidRecordSize(3, "select")) |
(...skipping 1028 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2939 | 3035 |
2940 if (TopLevelBlocks != 1) { | 3036 if (TopLevelBlocks != 1) { |
2941 errs() << IRFilename | 3037 errs() << IRFilename |
2942 << ": Contains more than one module. Found: " << TopLevelBlocks | 3038 << ": Contains more than one module. Found: " << TopLevelBlocks |
2943 << "\n"; | 3039 << "\n"; |
2944 ErrorStatus = true; | 3040 ErrorStatus = true; |
2945 } | 3041 } |
2946 } | 3042 } |
2947 | 3043 |
2948 } // end of namespace Ice | 3044 } // end of namespace Ice |
OLD | NEW |