Chromium Code Reviews| Index: src/PNaClTranslator.cpp |
| diff --git a/src/PNaClTranslator.cpp b/src/PNaClTranslator.cpp |
| index 124ed894f34fd72da298a1c43b253227479e7179..23dcdad3f57de6aa1f60e5d2fb652c4b10a7bd2d 100644 |
| --- a/src/PNaClTranslator.cpp |
| +++ b/src/PNaClTranslator.cpp |
| @@ -1604,46 +1604,157 @@ private: |
| } |
| } |
| - /// Converts an LLVM cast opcode LLVMCastOp to the corresponding Ice |
| - /// cast opcode and assigns to CastKind. Returns true if successful, |
| - /// false otherwise. |
| - bool convertLLVMCastOpToIceOp(Instruction::CastOps LLVMCastOp, |
| - Ice::InstCast::OpKind &CastKind) const { |
| - switch (LLVMCastOp) { |
| - case Instruction::ZExt: |
| + /// Simplifies out vector types from Type1 and Type2, if both are vectors |
| + /// of the same size. |
| + void simplifyOutCommonVectorType(Ice::Type &Type1, Ice::Type &Type2) const { |
|
Jim Stichnoth
2014/12/12 22:47:54
All of these new functions, up to and including is
Karl
2014/12/15 17:40:18
Done.
|
| + bool IsType1Vector = isVectorType(Type1); |
| + bool IsType2Vector = isVectorType(Type2); |
| + if (IsType1Vector != IsType2Vector) |
| + return; |
| + if (IsType1Vector) { |
| + if (typeNumElements(Type1) != typeNumElements(Type2)) |
| + return; |
| + Type1 = typeElementType(Type1); |
| + Type2 = typeElementType(Type2); |
| + } |
| + } |
| + |
| + /// Returns true iff an integer truncation from SourceType to TargetType is |
| + /// valid. |
| + bool isIntTruncCastValid(Ice::Type SourceType, Ice::Type TargetType) const { |
| + if (!(Ice::isIntegerType(SourceType) && Ice::isIntegerType(TargetType))) |
| + return false; |
| + simplifyOutCommonVectorType(SourceType, TargetType); |
| + return Ice::getScalarIntBitWidth(SourceType) > |
|
jvoung (off chromium)
2014/12/12 23:46:45
nit: One of the getScalarIntBitWidth is prefixed w
Karl
2014/12/15 17:40:18
Good point. When I factored this out, I forgot to
|
| + getScalarIntBitWidth(TargetType); |
| + } |
| + |
| + /// Returns true iff a floating type truncation form SoruceType to TargetType |
|
Jim Stichnoth
2014/12/12 22:47:54
SourceType
Karl
2014/12/15 17:40:18
Done.
Also fixed "form" -> "from".
|
| + /// is valid. |
| + bool isFloatTruncCastValid(Ice::Type SourceType, Ice::Type TargetType) const { |
| + if (!(Ice::isFloatingType(SourceType) && Ice::isFloatingType(TargetType))) |
| + return false; |
| + simplifyOutCommonVectorType(SourceType, TargetType); |
| + return SourceType == Ice::IceType_f64 and TargetType == Ice::IceType_f32; |
|
Jim Stichnoth
2014/12/12 22:47:54
"and"? wow.
Karl
2014/12/15 17:40:18
Done.
|
| + } |
| + |
| + /// Returns true iff an integer extension from SourceType to TargetType is |
| + /// valid. |
| + bool isIntExtCastValid(Ice::Type SourceType, Ice::Type TargetType) const { |
| + return isIntTruncCastValid(TargetType, SourceType); |
| + } |
| + |
| + /// Returns true iff a floating type extension form SourceType to TargetType |
|
Jim Stichnoth
2014/12/12 22:47:54
from
Karl
2014/12/15 17:40:18
Done.
|
| + /// is valid. |
| + bool isFloatExtCastValid(Ice::Type SourceType, Ice::Type TargetType) const { |
| + return isFloatTruncCastValid(TargetType, SourceType); |
| + } |
| + |
| + /// Returns true if a floating type SourceType to integer type TargetType |
|
Jim Stichnoth
2014/12/12 22:47:54
Use "iff" for consistency?
Also, I think the word
Karl
2014/12/15 17:40:18
Done and Done.
|
| + /// is valid. |
| + bool isFPToICastValid(Ice::Type SourceType, Ice::Type TargetType) const { |
|
Jim Stichnoth
2014/12/12 22:47:54
name it isFloatToIntCastValid for consistency?
Karl
2014/12/15 17:40:18
Done.
|
| + if (!(Ice::isFloatingType(SourceType) && Ice::isIntegerType(TargetType))) |
| + return false; |
| + bool IsSourceVector = isVectorType(SourceType); |
| + bool IsTargetVector = isVectorType(TargetType); |
| + if (IsSourceVector != IsTargetVector) |
| + return false; |
| + if (IsSourceVector) { |
| + if (typeNumElements(SourceType) != typeNumElements(TargetType)) |
|
Jim Stichnoth
2014/12/12 22:47:54
Might be better to just use:
return typeNumEleme
Karl
2014/12/15 17:40:18
Done.
|
| + return false; |
| + } |
| + return true; |
| + } |
| + |
| + /// Returns true iff an integer type SourceType to floating type TargetType |
|
Jim Stichnoth
2014/12/12 22:47:55
add "cast" to the comment?
Karl
2014/12/15 17:40:18
Done.
|
| + /// is valid. |
| + bool isIToFPCastValid(Ice::Type SourceType, Ice::Type TargetType) const { |
|
Jim Stichnoth
2014/12/12 22:47:55
suggest isIntToFloatCastValid
Karl
2014/12/15 17:40:18
Done.
|
| + return isFPToICastValid(TargetType, SourceType); |
| + } |
| + |
| + /// Returns the number of bits used to model type Ty when defining the |
| + /// bitcast instruction. |
| + Ice::SizeT bitcastSizeInBits(Ice::Type Ty) const { |
| + if (Ice::isVectorType(Ty)) |
| + return Ice::typeNumElements(Ty) * |
| + bitcastSizeInBits(Ice::typeElementType(Ty)); |
| + if (Ty == Ice::IceType_i1) |
| + return 1; |
| + return Ice::typeWidthInBytes(Ty) * CHAR_BIT; |
| + } |
| + |
| + /// Returns true if a bitcast from SourceType to TargetType is allowed. |
| + bool isBitcastCastValid(Ice::Type SourceType, Ice::Type TargetType) const { |
|
Jim Stichnoth
2014/12/12 22:47:54
maybe just call it isBitcastValid()?
Karl
2014/12/15 17:40:18
Done.
|
| + return bitcastSizeInBits(SourceType) == bitcastSizeInBits(TargetType); |
| + } |
| + |
| + /// Returns true if the NaCl bitcode Opcode is a valid cast opcode |
| + /// for converting SourceType to TargetType. Updates CastKind to the |
| + /// corresponding instruction cast opcode. Also generates error message |
|
Jim Stichnoth
2014/12/12 22:47:54
generates *an* error message
Karl
2014/12/15 17:40:19
Done.
|
| + /// if function returns false. |
|
Jim Stichnoth
2014/12/12 22:47:55
what function?
Karl
2014/12/15 17:40:18
Added "this" and replaced "if" with "when".
|
| + bool convertCastOpToIceOp(uint64_t Opcode, Ice::Type SourceType, |
| + Ice::Type TargetType, |
| + Ice::InstCast::OpKind &CastKind) { |
| + bool Result; |
| + switch (Opcode) { |
| + default: { |
| + std::string Buffer; |
| + raw_string_ostream StrBuf(Buffer); |
| + StrBuf << "Cast opcode " << Opcode << " not understood.\n"; |
| + Error(StrBuf.str()); |
| + // TODO(kschimpf) Remove error recovery once implementation complete. |
| + CastKind = Ice::InstCast::Bitcast; |
| + return false; |
| + } |
| + case naclbitc::CAST_TRUNC: |
| + CastKind = Ice::InstCast::Trunc; |
| + Result = isIntTruncCastValid(SourceType, TargetType); |
| + break; |
| + case naclbitc::CAST_ZEXT: |
| CastKind = Ice::InstCast::Zext; |
| + Result = isIntExtCastValid(SourceType, TargetType); |
| break; |
| - case Instruction::SExt: |
| + case naclbitc::CAST_SEXT: |
| CastKind = Ice::InstCast::Sext; |
| + Result = isIntExtCastValid(SourceType, TargetType); |
| break; |
| - case Instruction::Trunc: |
| - CastKind = Ice::InstCast::Trunc; |
| - break; |
| - case Instruction::FPTrunc: |
| - CastKind = Ice::InstCast::Fptrunc; |
| - break; |
| - case Instruction::FPExt: |
| - CastKind = Ice::InstCast::Fpext; |
| + case naclbitc::CAST_FPTOUI: |
| + CastKind = Ice::InstCast::Fptoui; |
| + Result = isFPToICastValid(SourceType, TargetType); |
| break; |
| - case Instruction::FPToSI: |
| + case naclbitc::CAST_FPTOSI: |
| CastKind = Ice::InstCast::Fptosi; |
| + Result = isFPToICastValid(SourceType, TargetType); |
| break; |
| - case Instruction::FPToUI: |
| - CastKind = Ice::InstCast::Fptoui; |
| + case naclbitc::CAST_UITOFP: |
| + CastKind = Ice::InstCast::Uitofp; |
| + Result = isIToFPCastValid(SourceType, TargetType); |
| break; |
| - case Instruction::SIToFP: |
| + case naclbitc::CAST_SITOFP: |
| CastKind = Ice::InstCast::Sitofp; |
| + Result = isIToFPCastValid(SourceType, TargetType); |
| break; |
| - case Instruction::UIToFP: |
| - CastKind = Ice::InstCast::Uitofp; |
| + case naclbitc::CAST_FPTRUNC: |
| + CastKind = Ice::InstCast::Fptrunc; |
| + Result = isFloatTruncCastValid(SourceType, TargetType); |
| + break; |
| + case naclbitc::CAST_FPEXT: |
| + CastKind = Ice::InstCast::Fpext; |
| + Result = isFloatExtCastValid(SourceType, TargetType); |
| break; |
| - case Instruction::BitCast: |
| + case naclbitc::CAST_BITCAST: |
| CastKind = Ice::InstCast::Bitcast; |
| + Result = isBitcastCastValid(SourceType, TargetType); |
| break; |
| - default: |
| - return false; |
| } |
| - return true; |
| + if (!Result) { |
| + std::string Buffer; |
| + raw_string_ostream StrBuf(Buffer); |
| + StrBuf << "Illegal cast: " << Ice::InstCast::getCastName(CastKind) << " " |
| + << SourceType << " to " << TargetType; |
| + Error(StrBuf.str()); |
| + } |
| + return Result; |
| } |
| // Converts PNaCl bitcode Icmp operator to corresponding ICE op. |
| @@ -1876,30 +1987,13 @@ void FunctionParser::ProcessRecord() { |
| return; |
| Ice::Operand *Src = getRelativeOperand(Values[0], BaseIndex); |
| Ice::Type CastType = Context->getSimpleTypeByID(Values[1]); |
| - Instruction::CastOps LLVMCastOp; |
| Ice::InstCast::OpKind CastKind; |
| - if (!naclbitc::DecodeCastOpcode(Values[2], LLVMCastOp) || |
| - !convertLLVMCastOpToIceOp(LLVMCastOp, CastKind)) { |
| - std::string Buffer; |
| - raw_string_ostream StrBuf(Buffer); |
| - StrBuf << "Cast opcode not understood: " << Values[2]; |
| - Error(StrBuf.str()); |
| - appendErrorInstruction(CastType); |
| - return; |
| - } |
| if (isIRGenerationDisabled()) { |
| assert(Src == nullptr); |
| setNextLocalInstIndex(nullptr); |
| return; |
| } |
| - Ice::Type SrcType = Src->getType(); |
| - if (!CastInst::castIsValid(LLVMCastOp, Context->convertToLLVMType(SrcType), |
| - Context->convertToLLVMType(CastType))) { |
| - std::string Buffer; |
| - raw_string_ostream StrBuf(Buffer); |
| - StrBuf << "Illegal cast: " << Instruction::getOpcodeName(LLVMCastOp) |
| - << " " << SrcType << " to " << CastType; |
| - Error(StrBuf.str()); |
| + if (!convertCastOpToIceOp(Values[2], Src->getType(), CastType, CastKind)) { |
| appendErrorInstruction(CastType); |
| return; |
| } |