Add cast instructions to subzero's pnacl bitcode translator.
Also clean up other error cases (in function block) to simply return, since they have already generated an error message.
BUG= https://code.google.com/p/nativeclient/issues/detail?id=3894
R=jvoung@chromium.org, stichnot@chromium.org
Review URL: https://codereview.chromium.org/514273002
diff --git a/src/PNaClTranslator.cpp b/src/PNaClTranslator.cpp
index d7dc0c3..8f157a6 100644
--- a/src/PNaClTranslator.cpp
+++ b/src/PNaClTranslator.cpp
@@ -1023,6 +1023,48 @@
return isValidIntegerLogicalOp(Op, Ty);
}
}
+
+ /// 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) {
+ switch (LLVMCastOp) {
+ case Instruction::ZExt:
+ CastKind = Ice::InstCast::Zext;
+ break;
+ case Instruction::SExt:
+ CastKind = Ice::InstCast::Sext;
+ break;
+ case Instruction::Trunc:
+ CastKind = Ice::InstCast::Trunc;
+ break;
+ case Instruction::FPTrunc:
+ CastKind = Ice::InstCast::Fptrunc;
+ break;
+ case Instruction::FPExt:
+ CastKind = Ice::InstCast::Fpext;
+ break;
+ case Instruction::FPToSI:
+ CastKind = Ice::InstCast::Fptosi;
+ break;
+ case Instruction::FPToUI:
+ CastKind = Ice::InstCast::Fptoui;
+ break;
+ case Instruction::SIToFP:
+ CastKind = Ice::InstCast::Sitofp;
+ break;
+ case Instruction::UIToFP:
+ CastKind = Ice::InstCast::Uitofp;
+ break;
+ case Instruction::BitCast:
+ CastKind = Ice::InstCast::Bitcast;
+ break;
+ default:
+ return false;
+ }
+ return true;
+ }
};
FunctionParser::~FunctionParser() {
@@ -1080,7 +1122,7 @@
case naclbitc::FUNC_CODE_DECLAREBLOCKS: {
// DECLAREBLOCKS: [n]
if (!isValidRecordSize(1, "function block count"))
- break;
+ return;
if (Func->getNodes().size() != 1) {
Error("Duplicate function block count record");
return;
@@ -1100,7 +1142,7 @@
case naclbitc::FUNC_CODE_INST_BINOP: {
// BINOP: [opval, opval, opcode]
if (!isValidRecordSize(3, "function block binop"))
- break;
+ return;
Ice::Operand *Op1 = getOperand(convertRelativeToAbsIndex(Values[0]));
Ice::Operand *Op2 = getOperand(convertRelativeToAbsIndex(Values[1]));
Ice::Type Type1 = Op1->getType();
@@ -1116,16 +1158,45 @@
Ice::InstArithmetic::OpKind Opcode;
if (!convertBinopOpcode(Values[2], Type1, Opcode))
- break;
+ return;
Ice::Variable *Dest = NextInstVar(Type1);
Inst = Ice::InstArithmetic::create(Func, Opcode, Dest, Op1, Op2);
break;
}
+ case naclbitc::FUNC_CODE_INST_CAST: {
+ // CAST: [opval, destty, castopc]
+ if (!isValidRecordSize(3, "function block cast"))
+ return;
+ Ice::Operand *Src = getOperand(convertRelativeToAbsIndex(Values[0]));
+ Type *CastType = Context->getTypeByID(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());
+ return;
+ }
+ Type *SrcType = Context->convertToLLVMType(Src->getType());
+ if (!CastInst::castIsValid(LLVMCastOp, SrcType, CastType)) {
+ std::string Buffer;
+ raw_string_ostream StrBuf(Buffer);
+ StrBuf << "Illegal cast: " << Instruction::getOpcodeName(LLVMCastOp)
+ << " " << *SrcType << " to " << *CastType;
+ Error(StrBuf.str());
+ return;
+ }
+ Ice::Variable *Dest = NextInstVar(Context->convertToIceType(CastType));
+ Inst = Ice::InstCast::create(Func, CastKind, Dest, Src);
+ break;
+ }
case naclbitc::FUNC_CODE_INST_RET: {
// RET: [opval?]
InstIsTerminating = true;
if (!isValidRecordSizeInRange(0, 1, "function block ret"))
- break;
+ return;
if (Values.size() == 0) {
Inst = Ice::InstRet::create(Func);
} else {