X-Git-Url: http://plrg.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FBytecode%2FReader%2FInstructionReader.cpp;h=8912704c6f624d59bb4b2b4ff0c88580eefcf085;hb=d5d89967206e1153d24abdb7b22002f7533f55c7;hp=300c40999eb17d599957cf34d8e9d4abf29ce90a;hpb=1d87bcf4909b06dcd86320722653341f08b8b396;p=oota-llvm.git diff --git a/lib/Bytecode/Reader/InstructionReader.cpp b/lib/Bytecode/Reader/InstructionReader.cpp index 300c40999eb..8912704c6f6 100644 --- a/lib/Bytecode/Reader/InstructionReader.cpp +++ b/lib/Bytecode/Reader/InstructionReader.cpp @@ -1,4 +1,11 @@ -//===- ReadInst.cpp - Code to read an instruction from bytecode -------------=== +//===- ReadInst.cpp - Code to read an instruction from bytecode -----------===// +// +// The LLVM Compiler Infrastructure +// +// This file was developed by the LLVM research group and is distributed under +// the University of Illinois Open Source License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// // // This file defines the mechanism to read an instruction from a bytecode // stream. @@ -6,327 +13,381 @@ // Note that this library should be as fast as possible, reentrant, and // threadsafe!! // -// TODO: Change from getValue(Raw.Arg1) etc, to getArg(Raw, 1) -// Make it check type, so that casts are checked. -// -//===------------------------------------------------------------------------=== +//===----------------------------------------------------------------------===// -#include "llvm/iOther.h" +#include "ReaderInternals.h" #include "llvm/iTerminators.h" #include "llvm/iMemory.h" -#include "llvm/DerivedTypes.h" -#include "ReaderInternals.h" +#include "llvm/iPHINode.h" +#include "llvm/iOther.h" +#include "llvm/Module.h" +using namespace llvm; -bool BytecodeParser::ParseRawInst(const uchar *&Buf, const uchar *EndBuf, - RawInst &Result) { - unsigned Op, Typ; - if (read(Buf, EndBuf, Op)) return failure(true); +namespace { + struct RawInst { // The raw fields out of the bytecode stream... + unsigned NumOperands; + unsigned Opcode; + unsigned Type; + + RawInst(const unsigned char *&Buf, const unsigned char *EndBuf, + std::vector &Args); + }; +} + +RawInst::RawInst(const unsigned char *&Buf, const unsigned char *EndBuf, + std::vector &Args) { + unsigned Op = read(Buf, EndBuf); - Result.NumOperands = Op >> 30; - Result.Opcode = (Op >> 24) & 63; + // bits Instruction format: Common to all formats + // -------------------------- + // 01-00: Opcode type, fixed to 1. + // 07-02: Opcode + Opcode = (Op >> 2) & 63; + Args.resize((Op >> 0) & 03); - switch (Result.NumOperands) { + switch (Args.size()) { case 1: - Result.Ty = getType((Op >> 12) & 4095); - Result.Arg1 = Op & 4095; - if (Result.Arg1 == 4095) // Handle special encoding for 0 operands... - Result.NumOperands = 0; + // bits Instruction format: + // -------------------------- + // 19-08: Resulting type plane + // 31-20: Operand #1 (if set to (2^12-1), then zero operands) + // + Type = (Op >> 8) & 4095; + Args[0] = (Op >> 20) & 4095; + if (Args[0] == 4095) // Handle special encoding for 0 operands... + Args.resize(0); break; case 2: - Result.Ty = getType((Op >> 16) & 255); - Result.Arg1 = (Op >> 8 ) & 255; - Result.Arg2 = (Op >> 0 ) & 255; + // bits Instruction format: + // -------------------------- + // 15-08: Resulting type plane + // 23-16: Operand #1 + // 31-24: Operand #2 + // + Type = (Op >> 8) & 255; + Args[0] = (Op >> 16) & 255; + Args[1] = (Op >> 24) & 255; break; case 3: - Result.Ty = getType((Op >> 18) & 63); - Result.Arg1 = (Op >> 12) & 63; - Result.Arg2 = (Op >> 6 ) & 63; - Result.Arg3 = (Op >> 0 ) & 63; + // bits Instruction format: + // -------------------------- + // 13-08: Resulting type plane + // 19-14: Operand #1 + // 25-20: Operand #2 + // 31-26: Operand #3 + // + Type = (Op >> 8) & 63; + Args[0] = (Op >> 14) & 63; + Args[1] = (Op >> 20) & 63; + Args[2] = (Op >> 26) & 63; break; case 0: Buf -= 4; // Hrm, try this again... - if (read_vbr(Buf, EndBuf, Result.Opcode)) return failure(true); - if (read_vbr(Buf, EndBuf, Typ)) return failure(true); - Result.Ty = getType(Typ); - if (read_vbr(Buf, EndBuf, Result.NumOperands)) return failure(true); - - switch (Result.NumOperands) { - case 0: - cerr << "Zero Arg instr found!\n"; - return failure(true); // This encoding is invalid! - case 1: - if (read_vbr(Buf, EndBuf, Result.Arg1)) return failure(true); - break; - case 2: - if (read_vbr(Buf, EndBuf, Result.Arg1) || - read_vbr(Buf, EndBuf, Result.Arg2)) return failure(true); - break; - case 3: - if (read_vbr(Buf, EndBuf, Result.Arg1) || - read_vbr(Buf, EndBuf, Result.Arg2) || - read_vbr(Buf, EndBuf, Result.Arg3)) return failure(true); - break; - default: - if (read_vbr(Buf, EndBuf, Result.Arg1) || - read_vbr(Buf, EndBuf, Result.Arg2)) return failure(true); - - // Allocate a vector to hold arguments 3, 4, 5, 6 ... - Result.VarArgs = new vector(Result.NumOperands-2); - for (unsigned a = 0; a < Result.NumOperands-2; a++) - if (read_vbr(Buf, EndBuf, (*Result.VarArgs)[a])) return failure(true); - break; - } - if (align32(Buf, EndBuf)) return failure(true); + Opcode = read_vbr_uint(Buf, EndBuf); + Opcode >>= 2; + Type = read_vbr_uint(Buf, EndBuf); + + unsigned NumOperands = read_vbr_uint(Buf, EndBuf); + Args.resize(NumOperands); + + if (NumOperands == 0) + throw std::string("Zero-argument instruction found; this is invalid."); + + for (unsigned i = 0; i != NumOperands; ++i) + Args[i] = read_vbr_uint(Buf, EndBuf); + align32(Buf, EndBuf); break; } - -#if 0 - cerr << "NO: " << Result.NumOperands << " opcode: " << Result.Opcode - << " Ty: " << Result.Ty->getDescription() << " arg1: " << Result.Arg1 - << " arg2: " << Result.Arg2 << " arg3: " << Result.Arg3 << endl; -#endif - return false; } -bool BytecodeParser::ParseInstruction(const uchar *&Buf, const uchar *EndBuf, - Instruction *&Res) { - RawInst Raw; - if (ParseRawInst(Buf, EndBuf, Raw)) return failure(true); - - if (Raw.Opcode >= Instruction::FirstUnaryOp && - Raw.Opcode < Instruction::NumUnaryOps && Raw.NumOperands == 1) { - Res = UnaryOperator::create((Instruction::UnaryOps)Raw.Opcode, - getValue(Raw.Ty,Raw.Arg1)); - return false; - } else if (Raw.Opcode >= Instruction::FirstBinaryOp && - Raw.Opcode < Instruction::NumBinaryOps && Raw.NumOperands == 2) { - Res = BinaryOperator::create((Instruction::BinaryOps)Raw.Opcode, - getValue(Raw.Ty, Raw.Arg1), - getValue(Raw.Ty, Raw.Arg2)); - return false; - } - - Value *V; - switch (Raw.Opcode) { - case Instruction::Cast: - Res = new CastInst(getValue(Raw.Ty, Raw.Arg1), getType(Raw.Arg2)); - return false; - - case Instruction::PHINode: { - PHINode *PN = new PHINode(Raw.Ty); - switch (Raw.NumOperands) { - case 0: - case 1: - case 3: cerr << "Invalid phi node encountered!\n"; - delete PN; - return failure(true); - case 2: PN->addIncoming(getValue(Raw.Ty, Raw.Arg1), - (BasicBlock*)getValue(Type::LabelTy, Raw.Arg2)); - break; - default: - PN->addIncoming(getValue(Raw.Ty, Raw.Arg1), - (BasicBlock*)getValue(Type::LabelTy, Raw.Arg2)); - if (Raw.VarArgs->size() & 1) { - cerr << "PHI Node with ODD number of arguments!\n"; - delete PN; - return failure(true); - } else { - vector &args = *Raw.VarArgs; - for (unsigned i = 0; i < args.size(); i+=2) - PN->addIncoming(getValue(Raw.Ty, args[i]), - (BasicBlock*)getValue(Type::LabelTy, args[i+1])); +void BytecodeParser::ParseInstruction(const unsigned char *&Buf, + const unsigned char *EndBuf, + std::vector &Args, + BasicBlock *BB) { + Args.clear(); + RawInst RI(Buf, EndBuf, Args); + const Type *InstTy = getType(RI.Type); + + Instruction *Result = 0; + if (RI.Opcode >= Instruction::BinaryOpsBegin && + RI.Opcode < Instruction::BinaryOpsEnd && Args.size() == 2) + Result = BinaryOperator::create((Instruction::BinaryOps)RI.Opcode, + getValue(RI.Type, Args[0]), + getValue(RI.Type, Args[1])); + + switch (RI.Opcode) { + default: + if (Result == 0) throw std::string("Illegal instruction read!"); + break; + case Instruction::VAArg: + Result = new VAArgInst(getValue(RI.Type, Args[0]), getType(Args[1])); + break; + case Instruction::VANext: + if (!hasOldStyleVarargs) { + Result = new VANextInst(getValue(RI.Type, Args[0]), getType(Args[1])); + } else { + // In the old-style varargs scheme, this was the "va_arg" instruction. + // Emit emulation code now. + if (!usesOldStyleVarargs) { + usesOldStyleVarargs = true; + std::cerr << "WARNING: this bytecode file uses obsolete features. " + << "Disassemble and assemble to update it.\n"; } - delete Raw.VarArgs; - break; + + Value *VAListPtr = getValue(RI.Type, Args[0]); + const Type *ArgTy = getType(Args[1]); + + // First, load the valist... + Instruction *CurVAList = new LoadInst(VAListPtr, ""); + BB->getInstList().push_back(CurVAList); + + // Construct the vaarg + Result = new VAArgInst(CurVAList, ArgTy); + + // Now we must advance the pointer and update it in memory. + Instruction *TheVANext = new VANextInst(CurVAList, ArgTy); + BB->getInstList().push_back(TheVANext); + + BB->getInstList().push_back(new StoreInst(TheVANext, VAListPtr)); } - Res = PN; - return false; + + break; + case Instruction::Cast: + Result = new CastInst(getValue(RI.Type, Args[0]), getType(Args[1])); + break; + case Instruction::PHI: { + if (Args.size() == 0 || (Args.size() & 1)) + throw std::string("Invalid phi node encountered!\n"); + + PHINode *PN = new PHINode(InstTy); + PN->op_reserve(Args.size()); + for (unsigned i = 0, e = Args.size(); i != e; i += 2) + PN->addIncoming(getValue(RI.Type, Args[i]), getBasicBlock(Args[i+1])); + Result = PN; + break; } case Instruction::Shl: case Instruction::Shr: - Res = new ShiftInst((Instruction::OtherOps)Raw.Opcode, - getValue(Raw.Ty, Raw.Arg1), - getValue(Type::UByteTy, Raw.Arg2)); - return false; + Result = new ShiftInst((Instruction::OtherOps)RI.Opcode, + getValue(RI.Type, Args[0]), + getValue(Type::UByteTyID, Args[1])); + break; case Instruction::Ret: - if (Raw.NumOperands == 0) { - Res = new ReturnInst(); return false; - } else if (Raw.NumOperands == 1) { - Res = new ReturnInst(getValue(Raw.Ty, Raw.Arg1)); return false; - } + if (Args.size() == 0) + Result = new ReturnInst(); + else if (Args.size() == 1) + Result = new ReturnInst(getValue(RI.Type, Args[0])); + else + throw std::string("Unrecognized instruction!"); break; case Instruction::Br: - if (Raw.NumOperands == 1) { - Res = new BranchInst((BasicBlock*)getValue(Type::LabelTy, Raw.Arg1)); - return false; - } else if (Raw.NumOperands == 3) { - Res = new BranchInst((BasicBlock*)getValue(Type::LabelTy, Raw.Arg1), - (BasicBlock*)getValue(Type::LabelTy, Raw.Arg2), - getValue(Type::BoolTy , Raw.Arg3)); - return false; - } + if (Args.size() == 1) + Result = new BranchInst(getBasicBlock(Args[0])); + else if (Args.size() == 3) + Result = new BranchInst(getBasicBlock(Args[0]), getBasicBlock(Args[1]), + getValue(Type::BoolTyID , Args[2])); + else + throw std::string("Invalid number of operands for a 'br' instruction!"); break; - case Instruction::Switch: { - SwitchInst *I = - new SwitchInst(getValue(Raw.Ty, Raw.Arg1), - (BasicBlock*)getValue(Type::LabelTy, Raw.Arg2)); - Res = I; - if (Raw.NumOperands < 3) return false; // No destinations? Wierd. - - if (Raw.NumOperands == 3 || Raw.VarArgs->size() & 1) { - cerr << "Switch statement with odd number of arguments!\n"; - delete I; - return failure(true); - } - - vector &args = *Raw.VarArgs; - for (unsigned i = 0; i < args.size(); i += 2) - I->dest_push_back((ConstPoolVal*)getValue(Raw.Ty, args[i]), - (BasicBlock*)getValue(Type::LabelTy, args[i+1])); + if (Args.size() & 1) + throw std::string("Switch statement with odd number of arguments!"); - delete Raw.VarArgs; - return false; + SwitchInst *I = new SwitchInst(getValue(RI.Type, Args[0]), + getBasicBlock(Args[1])); + for (unsigned i = 2, e = Args.size(); i != e; i += 2) + I->addCase(cast(getValue(RI.Type, Args[i])), + getBasicBlock(Args[i+1])); + Result = I; + break; } case Instruction::Call: { - Method *M = (Method*)getValue(Raw.Ty, Raw.Arg1); - if (M == 0) return failure(true); - - vector Params; - const MethodType::ParamTypes &PL = M->getType()->getParamTypes(); - - if (!M->getType()->isVarArg()) { - MethodType::ParamTypes::const_iterator It = PL.begin(); - - switch (Raw.NumOperands) { - case 0: cerr << "Invalid call instruction encountered!\n"; - return failure(true); - case 1: break; - case 2: Params.push_back(getValue(*It++, Raw.Arg2)); break; - case 3: Params.push_back(getValue(*It++, Raw.Arg2)); - if (It == PL.end()) return failure(true); - Params.push_back(getValue(*It++, Raw.Arg3)); break; - default: - Params.push_back(getValue(*It++, Raw.Arg2)); - { - vector &args = *Raw.VarArgs; - for (unsigned i = 0; i < args.size(); i++) { - if (It == PL.end()) return failure(true); - // TODO: Check getValue for null! - Params.push_back(getValue(*It++, args[i])); - } - } - delete Raw.VarArgs; + if (Args.size() == 0) + throw std::string("Invalid call instruction encountered!"); + + Value *F = getValue(RI.Type, Args[0]); + + // Check to make sure we have a pointer to function type + const PointerType *PTy = dyn_cast(F->getType()); + if (PTy == 0) throw std::string("Call to non function pointer value!"); + const FunctionType *FTy = dyn_cast(PTy->getElementType()); + if (FTy == 0) throw std::string("Call to non function pointer value!"); + + std::vector Params; + if (!FTy->isVarArg()) { + FunctionType::param_iterator It = FTy->param_begin(); + + for (unsigned i = 1, e = Args.size(); i != e; ++i) { + if (It == FTy->param_end()) + throw std::string("Invalid call instruction!"); + Params.push_back(getValue(getTypeSlot(*It++), Args[i])); } - if (It != PL.end()) return failure(true); + if (It != FTy->param_end()) + throw std::string("Invalid call instruction!"); } else { - // The first parameter does not have a type specifier... because there - // must be at least one concrete argument to a vararg type... - Params.push_back(getValue(PL.front(), Raw.Arg2)); - - vector &args = *Raw.VarArgs; - if ((args.size() & 1) != 0) - return failure(true); // Must be pairs of type/value - for (unsigned i = 0; i < args.size(); i+=2) { - // TODO: Check getValue for null! - Params.push_back(getValue(getType(args[i]), args[i+1])); + Args.erase(Args.begin(), Args.begin()+1+hasVarArgCallPadding); + + unsigned FirstVariableOperand; + if (!hasVarArgCallPadding) { + if (Args.size() < FTy->getNumParams()) + throw std::string("Call instruction missing operands!"); + + // Read all of the fixed arguments + for (unsigned i = 0, e = FTy->getNumParams(); i != e; ++i) + Params.push_back(getValue(getTypeSlot(FTy->getParamType(i)),Args[i])); + + FirstVariableOperand = FTy->getNumParams(); + } else { + FirstVariableOperand = 0; } - delete Raw.VarArgs; + + if ((Args.size()-FirstVariableOperand) & 1) // Must be pairs of type/value + throw std::string("Invalid call instruction!"); + + for (unsigned i = FirstVariableOperand, e = Args.size(); i != e; i += 2) + Params.push_back(getValue(Args[i], Args[i+1])); } - Res = new CallInst(M, Params); - return false; + Result = new CallInst(F, Params); + break; + } + case Instruction::Invoke: { + if (Args.size() < 3) throw std::string("Invalid invoke instruction!"); + Value *F = getValue(RI.Type, Args[0]); + + // Check to make sure we have a pointer to function type + const PointerType *PTy = dyn_cast(F->getType()); + if (PTy == 0) throw std::string("Invoke to non function pointer value!"); + const FunctionType *FTy = dyn_cast(PTy->getElementType()); + if (FTy == 0) throw std::string("Invoke to non function pointer value!"); + + std::vector Params; + BasicBlock *Normal, *Except; + + if (!FTy->isVarArg()) { + Normal = getBasicBlock(Args[1]); + Except = getBasicBlock(Args[2]); + + FunctionType::param_iterator It = FTy->param_begin(); + for (unsigned i = 3, e = Args.size(); i != e; ++i) { + if (It == FTy->param_end()) + throw std::string("Invalid invoke instruction!"); + Params.push_back(getValue(getTypeSlot(*It++), Args[i])); + } + if (It != FTy->param_end()) + throw std::string("Invalid invoke instruction!"); + } else { + Args.erase(Args.begin(), Args.begin()+1+hasVarArgCallPadding); + + unsigned FirstVariableArgument; + if (!hasVarArgCallPadding) { + Normal = getBasicBlock(Args[0]); + Except = getBasicBlock(Args[1]); + + FirstVariableArgument = FTy->getNumParams()+2; + for (unsigned i = 2; i != FirstVariableArgument; ++i) + Params.push_back(getValue(getTypeSlot(FTy->getParamType(i-2)), + Args[i])); + + } else { + if (Args.size() < 4) throw std::string("Invalid invoke instruction!"); + if (Args[0] != Type::LabelTyID || Args[2] != Type::LabelTyID) + throw std::string("Invalid invoke instruction!"); + Normal = getBasicBlock(Args[1]); + Except = getBasicBlock(Args[3]); + + FirstVariableArgument = 4; + } + + if (Args.size()-FirstVariableArgument & 1) // Must be pairs of type/value + throw std::string("Invalid invoke instruction!"); + + for (unsigned i = FirstVariableArgument; i < Args.size(); i += 2) + Params.push_back(getValue(Args[i], Args[i+1])); + } + + Result = new InvokeInst(F, Normal, Except, Params); + break; } case Instruction::Malloc: - if (Raw.NumOperands > 2) return failure(true); - V = Raw.NumOperands ? getValue(Type::UIntTy, Raw.Arg1) : 0; - Res = new MallocInst(Raw.Ty, V); - return false; + if (Args.size() > 2) throw std::string("Invalid malloc instruction!"); + if (!isa(InstTy)) + throw std::string("Invalid malloc instruction!"); + + Result = new MallocInst(cast(InstTy)->getElementType(), + Args.size() ? getValue(Type::UIntTyID, + Args[0]) : 0); + break; case Instruction::Alloca: - if (Raw.NumOperands > 2) return failure(true); - V = Raw.NumOperands ? getValue(Type::UIntTy, Raw.Arg1) : 0; - Res = new AllocaInst(Raw.Ty, V); - return false; + if (Args.size() > 2) throw std::string("Invalid alloca instruction!"); + if (!isa(InstTy)) + throw std::string("Invalid alloca instruction!"); + Result = new AllocaInst(cast(InstTy)->getElementType(), + Args.size() ? getValue(Type::UIntTyID, Args[0]) :0); + break; case Instruction::Free: - V = getValue(Raw.Ty, Raw.Arg1); - if (!V->getType()->isPointerType()) return failure(true); - Res = new FreeInst(V); - return false; - - case Instruction::Load: + if (!isa(InstTy)) + throw std::string("Invalid free instruction!"); + Result = new FreeInst(getValue(RI.Type, Args[0])); + break; case Instruction::GetElementPtr: { - vector Idx; - switch (Raw.NumOperands) { - case 0: cerr << "Invalid load encountered!\n"; return failure(true); - case 1: break; - case 2: V = getValue(Type::UByteTy, Raw.Arg2); - if (!isa(V)) return failure(true); - Idx.push_back(cast(V)); - break; - case 3: V = getValue(Type::UByteTy, Raw.Arg2); - if (!isa(V)) return failure(true); - Idx.push_back(cast(V)); - V = getValue(Type::UByteTy, Raw.Arg3); - if (!isa(V)) return failure(true); - Idx.push_back(cast(V)); - break; - default: - V = getValue(Type::UByteTy, Raw.Arg2); - if (!isa(V)) return failure(true); - Idx.push_back(cast(V)); - vector &args = *Raw.VarArgs; - for (unsigned i = 0, E = args.size(); i != E; ++i) { - V = getValue(Type::UByteTy, args[i]); - if (!isa(V)) return failure(true); - Idx.push_back(cast(V)); - } - delete Raw.VarArgs; - break; + if (Args.size() == 0 || !isa(InstTy)) + throw std::string("Invalid getelementptr instruction!"); + + std::vector Idx; + + const Type *NextTy = InstTy; + for (unsigned i = 1, e = Args.size(); i != e; ++i) { + const CompositeType *TopTy = dyn_cast_or_null(NextTy); + if (!TopTy) throw std::string("Invalid getelementptr instruction!"); + // FIXME: when PR82 is resolved. + unsigned IdxTy = isa(TopTy) ? Type::UByteTyID :Type::LongTyID; + + Idx.push_back(getValue(IdxTy, Args[i])); + NextTy = GetElementPtrInst::getIndexedType(InstTy, Idx, true); } - if (Raw.Opcode == Instruction::Load) - Res = new LoadInst(getValue(Raw.Ty, Raw.Arg1), Idx); - else if (Raw.Opcode == Instruction::GetElementPtr) - Res = new GetElementPtrInst(getValue(Raw.Ty, Raw.Arg1), Idx); - else - abort(); - return false; + + Result = new GetElementPtrInst(getValue(RI.Type, Args[0]), Idx); + break; } + + case 62: // volatile load + case Instruction::Load: + if (Args.size() != 1 || !isa(InstTy)) + throw std::string("Invalid load instruction!"); + Result = new LoadInst(getValue(RI.Type, Args[0]), "", RI.Opcode == 62); + break; + + case 63: // volatile store case Instruction::Store: { - vector Idx; - switch (Raw.NumOperands) { - case 0: - case 1: cerr << "Invalid store encountered!\n"; return failure(true); - case 2: break; - case 3: V = getValue(Type::UByteTy, Raw.Arg3); - if (!isa(V)) return failure(true); - Idx.push_back(cast(V)); - break; - default: - vector &args = *Raw.VarArgs; - for (unsigned i = 0, E = args.size(); i != E; ++i) { - V = getValue(Type::UByteTy, args[i]); - if (!isa(V)) return failure(true); - Idx.push_back(cast(V)); - } - delete Raw.VarArgs; - break; - } + if (!isa(InstTy) || Args.size() != 2) + throw std::string("Invalid store instruction!"); - const Type *ElType = StoreInst::getIndexedType(Raw.Ty, Idx); - if (ElType == 0) return failure(true); - Res = new StoreInst(getValue(ElType, Raw.Arg1), getValue(Raw.Ty, Raw.Arg2), - Idx); - return false; + Value *Ptr = getValue(RI.Type, Args[1]); + const Type *ValTy = cast(Ptr->getType())->getElementType(); + Result = new StoreInst(getValue(getTypeSlot(ValTy), Args[0]), Ptr, + RI.Opcode == 63); + break; } - } // end switch(Raw.Opcode) + case Instruction::Unwind: + if (Args.size() != 0) throw std::string("Invalid unwind instruction!"); + Result = new UnwindInst(); + break; + } // end switch(RI.Opcode) + + unsigned TypeSlot; + if (Result->getType() == InstTy) + TypeSlot = RI.Type; + else + TypeSlot = getTypeSlot(Result->getType()); - cerr << "Unrecognized instruction! " << Raw.Opcode - << " ADDR = 0x" << (void*)Buf << endl; - return failure(true); + insertValue(Result, TypeSlot, Values); + BB->getInstList().push_back(Result); + BCR_TRACE(4, *Result); }