Major refactoring of the bytecode reader. This includes the following
[oota-llvm.git] / lib / Bytecode / Reader / InstructionReader.cpp
index aee6ba34f4914478cfd5d5ce82746a5f6bf9c277..b085581c60eae6b0df1d99aaab0fb63eef8b91a4 100644 (file)
@@ -6,9 +6,6 @@
 // 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 "ReaderInternals.h"
 #include "llvm/iPHINode.h"
 #include "llvm/iOther.h"
 
-std::auto_ptr<RawInst>
-BytecodeParser::ParseRawInst(const unsigned char *&Buf,
-                             const unsigned char *EndBuf) { 
+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<unsigned> &Args);
+          
+};
+
+
+
+RawInst::RawInst(const unsigned char *&Buf, const unsigned char *EndBuf,
+                 std::vector<unsigned> &Args) {
   unsigned Op, Typ;
-  std::auto_ptr<RawInst> Result = std::auto_ptr<RawInst>(new RawInst());
   if (read(Buf, EndBuf, Op)) 
     throw std::string("Error reading from buffer.");
 
@@ -29,20 +36,20 @@ BytecodeParser::ParseRawInst(const unsigned char *&Buf,
   // --------------------------
   // 01-00: Opcode type, fixed to 1.
   // 07-02: Opcode
-  Result->NumOperands = (Op >> 0) & 03;
-  Result->Opcode      = (Op >> 2) & 63;
+  Opcode    = (Op >> 2) & 63;
+  Args.resize((Op >> 0) & 03);
 
-  switch (Result->NumOperands) {
+  switch (Args.size()) {
   case 1:
     // bits   Instruction format:
     // --------------------------
     // 19-08: Resulting type plane
     // 31-20: Operand #1 (if set to (2^12-1), then zero operands)
     //
-    Result->Ty   = getType((Op >> 8) & 4095);
-    Result->Arg1 = (Op >> 20) & 4095;
-    if (Result->Arg1 == 4095)    // Handle special encoding for 0 operands...
-      Result->NumOperands = 0;
+    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:
     // bits   Instruction format:
@@ -51,9 +58,9 @@ BytecodeParser::ParseRawInst(const unsigned char *&Buf,
     // 23-16: Operand #1
     // 31-24: Operand #2  
     //
-    Result->Ty   = getType((Op >> 8) & 255);
-    Result->Arg1 = (Op >> 16) & 255;
-    Result->Arg2 = (Op >> 24) & 255;
+    Type    = (Op >>  8) & 255;
+    Args[0] = (Op >> 16) & 255;
+    Args[1] = (Op >> 24) & 255;
     break;
   case 3:
     // bits   Instruction format:
@@ -63,159 +70,101 @@ BytecodeParser::ParseRawInst(const unsigned char *&Buf,
     // 25-20: Operand #2
     // 31-26: Operand #3
     //
-    Result->Ty   = getType((Op >> 8) & 63);
-    Result->Arg1 = (Op >> 14) & 63;
-    Result->Arg2 = (Op >> 20) & 63;
-    Result->Arg3 = (Op >> 26) & 63;
+    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))
+    if (read_vbr(Buf, EndBuf, Opcode))
       throw std::string("Error reading from buffer.");
-    Result->Opcode >>= 2;
-    if (read_vbr(Buf, EndBuf, Typ))
+    Opcode >>= 2;
+    if (read_vbr(Buf, EndBuf, Type))
       throw std::string("Error reading from buffer.");
-    Result->Ty = getType(Typ);
-    if (Result->Ty == 0) 
-      throw std::string("Invalid type read in instruction.");
-    if (read_vbr(Buf, EndBuf, Result->NumOperands))
+
+    unsigned NumOperands;
+    if (read_vbr(Buf, EndBuf, NumOperands))
       throw std::string("Error reading from buffer.");
+    Args.resize(NumOperands);
 
-    switch (Result->NumOperands) {
-    case 0: 
+    if (NumOperands == 0)
       throw std::string("Zero-argument instruction found; this is invalid.");
-    case 1: 
-      if (read_vbr(Buf, EndBuf, Result->Arg1)) 
-        throw std::string("Error reading from buffer");
-      break;
-    case 2:
-      if (read_vbr(Buf, EndBuf, Result->Arg1) || 
-         read_vbr(Buf, EndBuf, Result->Arg2))
-        throw std::string("Error reading from buffer");
-      break;
-    case 3:
-      if (read_vbr(Buf, EndBuf, Result->Arg1) || 
-         read_vbr(Buf, EndBuf, Result->Arg2) ||
-          read_vbr(Buf, EndBuf, Result->Arg3))
-        throw std::string("Error reading from buffer");
-      break;
-    default:
-      if (read_vbr(Buf, EndBuf, Result->Arg1) || 
-         read_vbr(Buf, EndBuf, Result->Arg2))
-        throw std::string("Error reading from buffer");
-
-      // Allocate a vector to hold arguments 3, 4, 5, 6 ...
-      Result->VarArgs = new std::vector<unsigned>(Result->NumOperands-2);
-      for (unsigned a = 0; a < Result->NumOperands-2; a++)
-       if (read_vbr(Buf, EndBuf, (*Result->VarArgs)[a]))
-        throw std::string("Error reading from buffer");          
 
-      break;
-    }
-    if (align32(Buf, EndBuf)) 
+    for (unsigned i = 0; i != NumOperands; ++i)
+      if (read_vbr(Buf, EndBuf, Args[i])) 
+        throw std::string("Error reading from buffer");
+    if (align32(Buf, EndBuf))
       throw std::string("Unaligned bytecode buffer.");
     break;
   }
-
-#if 0
-  std::cerr << "NO: "  << Result->NumOperands << " opcode: " << Result->Opcode 
-            << " Ty: "<< Result->Ty->getDescription()<< " arg1: "<< Result->Arg1
-            << " arg2: " << Result->Arg2 << " arg3: "   << Result->Arg3 << "\n";
-#endif
-  return Result;
 }
 
 
 Instruction *BytecodeParser::ParseInstruction(const unsigned char *&Buf,
                                               const unsigned char *EndBuf) {
-  std::auto_ptr<RawInst> Raw = ParseRawInst(Buf, EndBuf);
+  std::vector<unsigned> Args;
+  RawInst RI(Buf, EndBuf, Args);
+  const Type *InstTy = getType(RI.Type);
 
-  if (Raw->Opcode >= Instruction::BinaryOpsBegin &&
-      Raw->Opcode <  Instruction::BinaryOpsEnd  && Raw->NumOperands == 2)
-    return BinaryOperator::create((Instruction::BinaryOps)Raw->Opcode,
-                                  getValue(Raw->Ty, Raw->Arg1),
-                                  getValue(Raw->Ty, Raw->Arg2));
+  if (RI.Opcode >= Instruction::BinaryOpsBegin &&
+      RI.Opcode <  Instruction::BinaryOpsEnd  && Args.size() == 2)
+    return BinaryOperator::create((Instruction::BinaryOps)RI.Opcode,
+                                  getValue(InstTy, Args[0]),
+                                  getValue(InstTy, Args[1]));
 
-  switch (Raw->Opcode) {
+  switch (RI.Opcode) {
   case Instruction::VarArg:
-  case Instruction::Cast: {
-    Value *V = getValue(Raw->Ty, Raw->Arg1);
-    const Type *Ty = getType(Raw->Arg2);
-    if (Ty == 0) throw std::string("Invalid cast!\n");
-    if (Raw->Opcode == Instruction::Cast)
-      return new CastInst(V, Ty);
-    else
-      return new VarArgInst(V, Ty);
-  }
+    return new VarArgInst(getValue(InstTy, Args[0]), getType(Args[1]));
+  case Instruction::Cast:
+    return new CastInst(getValue(InstTy, Args[0]), getType(Args[1]));
   case Instruction::PHINode: {
-    PHINode *PN = new PHINode(Raw->Ty);
-    switch (Raw->NumOperands) {
-    case 0: 
-    case 1: 
-    case 3:
-      delete PN; 
+    if (Args.size() == 0 || (Args.size() & 1))
       throw std::string("Invalid phi node encountered!\n");
-    case 2:
-      PN->addIncoming(getValue(Raw->Ty, Raw->Arg1), getBasicBlock(Raw->Arg2));
-      break;
-    default:
-      PN->addIncoming(getValue(Raw->Ty, Raw->Arg1), getBasicBlock(Raw->Arg2));
-      if (Raw->VarArgs->size() & 1) {
-       delete PN;
-       throw std::string("PHI Node with ODD number of arguments!\n");
-      } else {
-        std::vector<unsigned> &args = *Raw->VarArgs;
-        for (unsigned i = 0; i < args.size(); i+=2)
-          PN->addIncoming(getValue(Raw->Ty, args[i]), getBasicBlock(args[i+1]));
-      }
-      delete Raw->VarArgs; 
-      break;
-    }
+
+    PHINode *PN = new PHINode(InstTy);
+    for (unsigned i = 0, e = Args.size(); i != e; i += 2)
+      PN->addIncoming(getValue(InstTy, Args[i]), getBasicBlock(Args[i+1]));
     return PN;
   }
 
   case Instruction::Shl:
   case Instruction::Shr:
-    return new ShiftInst((Instruction::OtherOps)Raw->Opcode,
-                         getValue(Raw->Ty, Raw->Arg1),
-                         getValue(Type::UByteTyID, Raw->Arg2));
+    return new ShiftInst((Instruction::OtherOps)RI.Opcode,
+                         getValue(InstTy, Args[0]),
+                         getValue(Type::UByteTyID, Args[1]));
   case Instruction::Ret:
-    if (Raw->NumOperands == 0)
+    if (Args.size() == 0)
       return new ReturnInst();
-    else if (Raw->NumOperands == 1)
-      return new ReturnInst(getValue(Raw->Ty, Raw->Arg1));
+    else if (Args.size() == 1)
+      return new ReturnInst(getValue(InstTy, Args[0]));
     break;
 
   case Instruction::Br:
-    if (Raw->NumOperands == 1)
-      return new BranchInst(getBasicBlock(Raw->Arg1));
-    else if (Raw->NumOperands == 3)
-      return new BranchInst(getBasicBlock(Raw->Arg1), getBasicBlock(Raw->Arg2),
-                            getValue(Type::BoolTyID , Raw->Arg3));
+    if (Args.size() == 1)
+      return new BranchInst(getBasicBlock(Args[0]));
+    else if (Args.size() == 3)
+      return new BranchInst(getBasicBlock(Args[0]), getBasicBlock(Args[1]),
+                            getValue(Type::BoolTyID , Args[2]));
     throw std::string("Invalid number of operands for a 'br' instruction!");
     
   case Instruction::Switch: {
-    SwitchInst *I = new SwitchInst(getValue(Raw->Ty, Raw->Arg1),
-                                   getBasicBlock(Raw->Arg2));
-    if (Raw->NumOperands < 3)
-      return I;
-
-    if (Raw->NumOperands == 3 || Raw->VarArgs->size() & 1) {
-      delete I;
+    if (Args.size() & 1)
       throw std::string("Switch statement with odd number of arguments!");
-    }
-    
-    std::vector<unsigned> &args = *Raw->VarArgs;
-    for (unsigned i = 0; i < args.size(); i += 2)
-      I->addCase(cast<Constant>(getValue(Raw->Ty, args[i])),
-                 getBasicBlock(args[i+1]));
 
-    delete Raw->VarArgs;
+    SwitchInst *I = new SwitchInst(getValue(InstTy, Args[0]),
+                                   getBasicBlock(Args[1]));
+    for (unsigned i = 2, e = Args.size(); i != e; i += 2)
+      I->addCase(cast<Constant>(getValue(InstTy, Args[i])),
+                 getBasicBlock(Args[i+1]));
     return I;
   }
 
   case Instruction::Call: {
-    Value *F = getValue(Raw->Ty, Raw->Arg1);
+    if (Args.size() == 0)
+      throw std::string("Invalid call instruction encountered!");
+
+    Value *F = getValue(InstTy, Args[0]);
 
     // Check to make sure we have a pointer to function type
     const PointerType *PTy = dyn_cast<PointerType>(F->getType());
@@ -229,45 +178,26 @@ Instruction *BytecodeParser::ParseInstruction(const unsigned char *&Buf,
     if (!FTy->isVarArg()) {
       FunctionType::ParamTypes::const_iterator It = PL.begin();
 
-      switch (Raw->NumOperands) {
-      case 0: throw std::string("Invalid call instruction encountered!");
-      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()) throw std::string("Invalid call instruction!");
-       Params.push_back(getValue(*It++, Raw->Arg3)); break;
-      default:
-       Params.push_back(getValue(*It++, Raw->Arg2));
-       {
-         std::vector<unsigned> &args = *Raw->VarArgs;
-         for (unsigned i = 0; i < args.size(); i++) {
-           if (It == PL.end()) throw std::string("Invalid call instruction!");
-           Params.push_back(getValue(*It++, args[i]));
-         }
-       }
-       delete Raw->VarArgs;
+      for (unsigned i = 1, e = Args.size(); i != e; ++i) {
+        if (It == PL.end()) throw std::string("Invalid call instruction!");
+        Params.push_back(getValue(*It++, Args[i]));
       }
       if (It != PL.end()) throw std::string("Invalid call instruction!");
     } else {
-      if (Raw->NumOperands > 2) {
-       std::vector<unsigned> &args = *Raw->VarArgs;
-       if (args.size() < 1) throw std::string("Invalid call instruction!");
-
-       if ((args.size() & 1) != 0)  // Must be pairs of type/value
-          throw std::string("Invalid call instruction!");
-       for (unsigned i = 0; i < args.size(); i+=2) {
-         const Type *Ty = getType(args[i]);
-         if (Ty == 0) throw std::string("Invalid call instruction!");
-         Params.push_back(getValue(Ty, args[i+1]));
-       }
-       delete Raw->VarArgs;
-      }
+      // FIXME: Args[1] is currently just a dummy padding field!
+
+      if (Args.size() & 1)  // Must be pairs of type/value
+        throw std::string("Invalid call instruction!");
+
+      for (unsigned i = 2, e = Args.size(); i != e; i += 2)
+        Params.push_back(getValue(getType(Args[i]), Args[i+1]));
     }
 
     return new CallInst(F, Params);
   }
   case Instruction::Invoke: {
-    Value *F = getValue(Raw->Ty, Raw->Arg1);
+    if (Args.size() < 3) throw std::string("Invalid invoke instruction!");
+    Value *F = getValue(InstTy, Args[0]);
 
     // Check to make sure we have a pointer to function type
     const PointerType *PTy = dyn_cast<PointerType>(F->getType());
@@ -276,131 +206,99 @@ Instruction *BytecodeParser::ParseInstruction(const unsigned char *&Buf,
     if (FTy == 0) throw std::string("Invoke to non function pointer value!");
 
     std::vector<Value *> Params;
-    const FunctionType::ParamTypes &PL = FTy->getParamTypes();
-    std::vector<unsigned> &args = *Raw->VarArgs;
-
     BasicBlock *Normal, *Except;
 
+    const FunctionType::ParamTypes &PL = FTy->getParamTypes();
+
     if (!FTy->isVarArg()) {
-      if (Raw->NumOperands < 3) throw std::string("Invalid call instruction!");
-
-      Normal = getBasicBlock(Raw->Arg2);
-      if (Raw->NumOperands == 3)
-        Except = getBasicBlock(Raw->Arg3);
-      else {
-        Except = getBasicBlock(args[0]);
-
-        FunctionType::ParamTypes::const_iterator It = PL.begin();
-        for (unsigned i = 1; i < args.size(); i++) {
-          if (It == PL.end()) throw std::string("Invalid invoke instruction!");
-          Params.push_back(getValue(*It++, args[i]));
-        }
-        if (It != PL.end()) throw std::string("Invalid invoke instruction!");
+      Normal = getBasicBlock(Args[1]);
+      Except = getBasicBlock(Args[2]);
+
+      FunctionType::ParamTypes::const_iterator It = PL.begin();
+      for (unsigned i = 3, e = Args.size(); i != e; ++i) {
+        if (It == PL.end()) throw std::string("Invalid invoke instruction!");
+        Params.push_back(getValue(*It++, Args[i]));
       }
+      if (It != PL.end()) throw std::string("Invalid invoke instruction!");
     } else {
-      if (args.size() < 4) throw std::string("Invalid invoke instruction!");
-      if (args[0] != Type::LabelTyID || args[2] != Type::LabelTyID)
+      // FIXME: Args[1] is a dummy padding field
+
+      if (Args.size() < 6) throw std::string("Invalid invoke instruction!");
+      if (Args[2] != Type::LabelTyID || Args[4] != Type::LabelTyID)
         throw std::string("Invalid invoke instruction!");
           
-      Normal = getBasicBlock(args[1]);
-      Except = getBasicBlock(args[3]);
+      Normal = getBasicBlock(Args[3]);
+      Except = getBasicBlock(Args[5]);
 
-      if ((args.size() & 1) != 0)   // Must be pairs of type/value
+      if (Args.size() & 1)   // Must be pairs of type/value
         throw std::string("Invalid invoke instruction!");
 
-      for (unsigned i = 4; i < args.size(); i += 2)
-        Params.push_back(getValue(args[i], args[i+1]));
+      for (unsigned i = 6; i < Args.size(); i += 2)
+        Params.push_back(getValue(Args[i], Args[i+1]));
     }
 
-    if (Raw->NumOperands > 3)
-      delete Raw->VarArgs;
     return new InvokeInst(F, Normal, Except, Params);
   }
   case Instruction::Malloc:
-    if (Raw->NumOperands > 2) throw std::string("Invalid malloc instruction!");
-    if (!isa<PointerType>(Raw->Ty))
+    if (Args.size() > 2) throw std::string("Invalid malloc instruction!");
+    if (!isa<PointerType>(InstTy))
       throw std::string("Invalid malloc instruction!");
 
-    return new MallocInst(cast<PointerType>(Raw->Ty)->getElementType(),
-                          Raw->NumOperands ? getValue(Type::UIntTyID,
-                                                      Raw->Arg1) : 0);
+    return new MallocInst(cast<PointerType>(InstTy)->getElementType(),
+                          Args.size() ? getValue(Type::UIntTyID,
+                                                      Args[0]) : 0);
 
   case Instruction::Alloca:
-    if (Raw->NumOperands > 2) throw std::string("Invalid alloca instruction!");
-    if (!isa<PointerType>(Raw->Ty))
+    if (Args.size() > 2) throw std::string("Invalid alloca instruction!");
+    if (!isa<PointerType>(InstTy))
       throw std::string("Invalid alloca instruction!");
 
-    return new AllocaInst(cast<PointerType>(Raw->Ty)->getElementType(),
-                          Raw->NumOperands ? getValue(Type::UIntTyID,
-                                                      Raw->Arg1) : 0);
+    return new AllocaInst(cast<PointerType>(InstTy)->getElementType(),
+                          Args.size() ? getValue(Type::UIntTyID,
+                                                      Args[0]) : 0);
   case Instruction::Free:
-    if (!isa<PointerType>(Raw->Ty))
+    if (!isa<PointerType>(InstTy))
       throw std::string("Invalid free instruction!");
-    return new FreeInst(getValue(Raw->Ty, Raw->Arg1));
+    return new FreeInst(getValue(InstTy, Args[0]));
 
   case Instruction::GetElementPtr: {
-    std::vector<Value*> Idx;
-    if (!isa<PointerType>(Raw->Ty))
+    if (Args.size() == 0 || !isa<PointerType>(InstTy))
       throw std::string("Invalid getelementptr instruction!");
-    const CompositeType *TopTy = dyn_cast<CompositeType>(Raw->Ty);
-
-    switch (Raw->NumOperands) {
-    case 0: throw std::string("Invalid getelementptr instruction!");
-    case 1: break;
-    case 2:
-      if (!TopTy) throw std::string("Invalid getelementptr instruction!");
-      Idx.push_back(getValue(TopTy->getIndexType(), Raw->Arg2));
-      break;
-    case 3: {
-      if (!TopTy) throw std::string("Invalid getelementptr instruction!");
-      Idx.push_back(getValue(TopTy->getIndexType(), Raw->Arg2));
-
-      const Type *ETy = GetElementPtrInst::getIndexedType(TopTy, Idx, true);
-      const CompositeType *ElTy = dyn_cast_or_null<CompositeType>(ETy);
-      if (!ElTy) throw std::string("Invalid getelementptr instruction!");
-
-      Idx.push_back(getValue(ElTy->getIndexType(), Raw->Arg3));
-      break;
-    }
-    default:
-      if (!TopTy) throw std::string("Invalid getelementptr instruction!");
-      Idx.push_back(getValue(TopTy->getIndexType(), Raw->Arg2));
-
-      std::vector<unsigned> &args = *Raw->VarArgs;
-      for (unsigned i = 0, E = args.size(); i != E; ++i) {
-        const Type *ETy = GetElementPtrInst::getIndexedType(Raw->Ty, Idx, true);
-        const CompositeType *ElTy = dyn_cast_or_null<CompositeType>(ETy);
-        if (!ElTy) throw std::string("Invalid getelementptr instruction!");
-       Idx.push_back(getValue(ElTy->getIndexType(), args[i]));
-      }
-      delete Raw->VarArgs; 
-      break;
+
+    std::vector<Value*> Idx;
+
+    const Type *NextTy = InstTy;
+    for (unsigned i = 1, e = Args.size(); i != e; ++i) {
+      const CompositeType *TopTy = dyn_cast_or_null<CompositeType>(NextTy);
+      if (!TopTy) throw std::string("Invalid getelementptr instruction!"); 
+      Idx.push_back(getValue(TopTy->getIndexType(), Args[i]));
+      NextTy = GetElementPtrInst::getIndexedType(InstTy, Idx, true);
     }
 
-    return new GetElementPtrInst(getValue(Raw->Ty, Raw->Arg1), Idx);
+    return new GetElementPtrInst(getValue(InstTy, Args[0]), Idx);
   }
 
   case 62:   // volatile load
   case Instruction::Load:
-    if (Raw->NumOperands != 1 || !isa<PointerType>(Raw->Ty))
+    if (Args.size() != 1 || !isa<PointerType>(InstTy))
       throw std::string("Invalid load instruction!");
-    return new LoadInst(getValue(Raw->Ty, Raw->Arg1), "", Raw->Opcode == 62);
+    return new LoadInst(getValue(InstTy, Args[0]), "", RI.Opcode == 62);
 
   case 63:   // volatile store 
   case Instruction::Store: {
-    if (!isa<PointerType>(Raw->Ty) || Raw->NumOperands != 2)
+    if (!isa<PointerType>(InstTy) || Args.size() != 2)
       throw std::string("Invalid store instruction!");
 
-    Value *Ptr = getValue(Raw->Ty, Raw->Arg2);
+    Value *Ptr = getValue(InstTy, Args[1]);
     const Type *ValTy = cast<PointerType>(Ptr->getType())->getElementType();
-    return new StoreInst(getValue(ValTy, Raw->Arg1), Ptr, Raw->Opcode == 63);
+    return new StoreInst(getValue(ValTy, Args[0]), Ptr, RI.Opcode == 63);
   }
   case Instruction::Unwind:
-    if (Raw->NumOperands != 0) throw std::string("Invalid unwind instruction!");
+    if (Args.size() != 0) throw std::string("Invalid unwind instruction!");
     return new UnwindInst();
-  }  // end switch(Raw->Opcode) 
+  }  // end switch(RI.Opcode) 
 
-  std::cerr << "Unrecognized instruction! " << Raw->Opcode 
+  std::cerr << "Unrecognized instruction! " << RI.Opcode 
             << " ADDR = 0x" << (void*)Buf << "\n";
   throw std::string("Unrecognized instruction!");
 }