Index: src/PNaClTranslator.cpp |
diff --git a/src/PNaClTranslator.cpp b/src/PNaClTranslator.cpp |
index d63232f2be9ff5a29f5326cddd71becf019fc7c6..609804cbb577d7c2582448e44532050048f76136 100644 |
--- a/src/PNaClTranslator.cpp |
+++ b/src/PNaClTranslator.cpp |
@@ -1007,7 +1007,7 @@ private: |
// Must be forward reference, expand vector to accommodate. |
if (LocalIndex >= LocalOperands.size()) |
- LocalOperands.resize(LocalIndex+1); |
+ LocalOperands.resize(LocalIndex + 1); |
// If element not defined, set it. |
Ice::Operand *OldOp = LocalOperands[LocalIndex]; |
@@ -1023,8 +1023,8 @@ private: |
// Error has occurred. |
std::string Buffer; |
raw_string_ostream StrBuf(Buffer); |
- StrBuf << "Multiple definitions for index " << Index |
- << ": " << *Op << " and " << *OldOp; |
+ StrBuf << "Multiple definitions for index " << Index << ": " << *Op |
+ << " and " << *OldOp; |
Error(StrBuf.str()); |
// TODO(kschimpf) Remove error recovery once implementation complete. |
LocalOperands[LocalIndex] = Op; |
@@ -1037,9 +1037,7 @@ private: |
} |
// Returns the absolute index of the next value generating instruction. |
- uint32_t getNextInstIndex() const { |
- return NextLocalInstIndex; |
- } |
+ uint32_t getNextInstIndex() const { return NextLocalInstIndex; } |
// Generates type error message for binary operator Op |
// operating on Type OpTy. |
@@ -1682,6 +1680,65 @@ void FunctionParser::ProcessRecord() { |
InstIsTerminating = true; |
break; |
} |
+ case naclbitc::FUNC_CODE_INST_SWITCH: { |
+ // SWITCH: [Condty, Cond, BbIndex, NumCases Case ...] |
+ // where Case = [1, 1, Value, BbIndex]. |
+ // |
+ // Note: Unlike most instructions, we don't infer the type of |
+ // Cond, but provide it as a separate field. There are also |
+ // unnecesary data fields (i.e. constants 1). These were not |
+ // cleaned up in PNaCl bitcode because the bitcode format was |
+ // already frozen when the problem was noticed. |
+ if (!isValidRecordSizeAtLeast(4, "function block switch")) |
+ return; |
+ Ice::Type CondTy = |
+ Context->convertToIceType(Context->getTypeByID(Values[0])); |
+ if (!Ice::isScalarIntegerType(CondTy)) { |
+ std::string Buffer; |
+ raw_string_ostream StrBuf(Buffer); |
+ StrBuf << "Case condition must be non-wide integer. Found: " << CondTy; |
+ Error(StrBuf.str()); |
+ return; |
+ } |
+ Ice::SizeT BitWidth = Ice::getScalarIntBitWidth(CondTy); |
+ Ice::Operand *Cond = getRelativeOperand(Values[1], BaseIndex); |
+ if (CondTy != Cond->getType()) { |
+ std::string Buffer; |
+ raw_string_ostream StrBuf(Buffer); |
+ StrBuf << "Case condition expects type " << CondTy |
+ << ". Found: " << Cond->getType(); |
+ Error(StrBuf.str()); |
+ return; |
+ } |
+ Ice::CfgNode *DefaultLabel = getBranchBasicBlock(Values[2]); |
+ unsigned NumCases = Values[3]; |
+ |
+ // Now recognize each of the cases. |
+ if (!isValidRecordSize(4 + NumCases * 4, "Function block switch")) |
+ return; |
+ Ice::InstSwitch *Switch = |
+ Ice::InstSwitch::create(Func, NumCases, Cond, DefaultLabel); |
+ unsigned ValCaseIndex = 4; // index to beginning of case entry. |
+ for (unsigned CaseIndex = 0; CaseIndex < NumCases; |
+ ++CaseIndex, ValCaseIndex += 4) { |
+ if (Values[ValCaseIndex] != 1 || Values[ValCaseIndex+1] != 1) { |
+ std::string Buffer; |
+ raw_string_ostream StrBuf(Buffer); |
+ StrBuf << "Sequence [1, 1, value, label] expected for case entry " |
+ << "in switch record. (at index" << ValCaseIndex << ")"; |
+ Error(StrBuf.str()); |
+ return; |
+ } |
+ APInt Value(BitWidth, |
+ NaClDecodeSignRotatedValue(Values[ValCaseIndex + 2]), |
+ true); |
+ Ice::CfgNode *Label = getBranchBasicBlock(Values[ValCaseIndex + 3]); |
+ Switch->addBranch(CaseIndex, Value.getSExtValue(), Label); |
+ } |
+ CurrentNode->appendInst(Switch); |
+ InstIsTerminating = true; |
+ break; |
+ } |
case naclbitc::FUNC_CODE_INST_UNREACHABLE: { |
// UNREACHABLE: [] |
if (!isValidRecordSize(0, "function block unreachable")) |
@@ -1781,11 +1838,10 @@ void FunctionParser::ProcessRecord() { |
// FORWARDTYPEREF: [opval, ty] |
if (!isValidRecordSize(2, "function block forward type ref")) |
return; |
- setOperand(Values[0], createInstVar( |
- Context->convertToIceType(Context->getTypeByID(Values[1])))); |
+ setOperand(Values[0], createInstVar(Context->convertToIceType( |
+ Context->getTypeByID(Values[1])))); |
break; |
} |
- case naclbitc::FUNC_CODE_INST_SWITCH: |
case naclbitc::FUNC_CODE_INST_CALL: |
case naclbitc::FUNC_CODE_INST_CALL_INDIRECT: |
default: |