blob: aee6ba34f4914478cfd5d5ce82746a5f6bf9c277 [file] [log] [blame]
Chris Lattner05950c32001-10-13 06:47:01 +00001//===- ReadInst.cpp - Code to read an instruction from bytecode -----------===//
Chris Lattner00950542001-06-06 20:29:01 +00002//
3// This file defines the mechanism to read an instruction from a bytecode
4// stream.
5//
6// Note that this library should be as fast as possible, reentrant, and
7// threadsafe!!
8//
9// TODO: Change from getValue(Raw.Arg1) etc, to getArg(Raw, 1)
10// Make it check type, so that casts are checked.
11//
Chris Lattner05950c32001-10-13 06:47:01 +000012//===----------------------------------------------------------------------===//
Chris Lattner00950542001-06-06 20:29:01 +000013
Chris Lattner7061dc52001-12-03 18:02:31 +000014#include "ReaderInternals.h"
Chris Lattner00950542001-06-06 20:29:01 +000015#include "llvm/iTerminators.h"
16#include "llvm/iMemory.h"
Chris Lattner7061dc52001-12-03 18:02:31 +000017#include "llvm/iPHINode.h"
18#include "llvm/iOther.h"
Chris Lattner00950542001-06-06 20:29:01 +000019
Misha Brukmand554ebf2003-09-23 16:17:50 +000020std::auto_ptr<RawInst>
21BytecodeParser::ParseRawInst(const unsigned char *&Buf,
22 const unsigned char *EndBuf) {
Chris Lattner00950542001-06-06 20:29:01 +000023 unsigned Op, Typ;
Misha Brukmand554ebf2003-09-23 16:17:50 +000024 std::auto_ptr<RawInst> Result = std::auto_ptr<RawInst>(new RawInst());
25 if (read(Buf, EndBuf, Op))
26 throw std::string("Error reading from buffer.");
Chris Lattner00950542001-06-06 20:29:01 +000027
Chris Lattner2b9f6002001-10-23 03:21:10 +000028 // bits Instruction format: Common to all formats
29 // --------------------------
30 // 01-00: Opcode type, fixed to 1.
31 // 07-02: Opcode
Misha Brukmand554ebf2003-09-23 16:17:50 +000032 Result->NumOperands = (Op >> 0) & 03;
33 Result->Opcode = (Op >> 2) & 63;
Chris Lattner00950542001-06-06 20:29:01 +000034
Misha Brukmand554ebf2003-09-23 16:17:50 +000035 switch (Result->NumOperands) {
Chris Lattner00950542001-06-06 20:29:01 +000036 case 1:
Chris Lattner2b9f6002001-10-23 03:21:10 +000037 // bits Instruction format:
38 // --------------------------
39 // 19-08: Resulting type plane
40 // 31-20: Operand #1 (if set to (2^12-1), then zero operands)
41 //
Misha Brukmand554ebf2003-09-23 16:17:50 +000042 Result->Ty = getType((Op >> 8) & 4095);
43 Result->Arg1 = (Op >> 20) & 4095;
44 if (Result->Arg1 == 4095) // Handle special encoding for 0 operands...
45 Result->NumOperands = 0;
Chris Lattner00950542001-06-06 20:29:01 +000046 break;
47 case 2:
Chris Lattner2b9f6002001-10-23 03:21:10 +000048 // bits Instruction format:
49 // --------------------------
50 // 15-08: Resulting type plane
51 // 23-16: Operand #1
52 // 31-24: Operand #2
53 //
Misha Brukmand554ebf2003-09-23 16:17:50 +000054 Result->Ty = getType((Op >> 8) & 255);
55 Result->Arg1 = (Op >> 16) & 255;
56 Result->Arg2 = (Op >> 24) & 255;
Chris Lattner00950542001-06-06 20:29:01 +000057 break;
58 case 3:
Chris Lattner2b9f6002001-10-23 03:21:10 +000059 // bits Instruction format:
60 // --------------------------
61 // 13-08: Resulting type plane
62 // 19-14: Operand #1
63 // 25-20: Operand #2
64 // 31-26: Operand #3
65 //
Misha Brukmand554ebf2003-09-23 16:17:50 +000066 Result->Ty = getType((Op >> 8) & 63);
67 Result->Arg1 = (Op >> 14) & 63;
68 Result->Arg2 = (Op >> 20) & 63;
69 Result->Arg3 = (Op >> 26) & 63;
Chris Lattner00950542001-06-06 20:29:01 +000070 break;
71 case 0:
72 Buf -= 4; // Hrm, try this again...
Misha Brukmand554ebf2003-09-23 16:17:50 +000073 if (read_vbr(Buf, EndBuf, Result->Opcode))
74 throw std::string("Error reading from buffer.");
75 Result->Opcode >>= 2;
76 if (read_vbr(Buf, EndBuf, Typ))
77 throw std::string("Error reading from buffer.");
78 Result->Ty = getType(Typ);
79 if (Result->Ty == 0)
80 throw std::string("Invalid type read in instruction.");
81 if (read_vbr(Buf, EndBuf, Result->NumOperands))
82 throw std::string("Error reading from buffer.");
Chris Lattner00950542001-06-06 20:29:01 +000083
Misha Brukmand554ebf2003-09-23 16:17:50 +000084 switch (Result->NumOperands) {
Chris Lattner00950542001-06-06 20:29:01 +000085 case 0:
Misha Brukmand554ebf2003-09-23 16:17:50 +000086 throw std::string("Zero-argument instruction found; this is invalid.");
Chris Lattner00950542001-06-06 20:29:01 +000087 case 1:
Misha Brukmand554ebf2003-09-23 16:17:50 +000088 if (read_vbr(Buf, EndBuf, Result->Arg1))
89 throw std::string("Error reading from buffer");
Chris Lattner00950542001-06-06 20:29:01 +000090 break;
91 case 2:
Misha Brukmand554ebf2003-09-23 16:17:50 +000092 if (read_vbr(Buf, EndBuf, Result->Arg1) ||
93 read_vbr(Buf, EndBuf, Result->Arg2))
94 throw std::string("Error reading from buffer");
Chris Lattner00950542001-06-06 20:29:01 +000095 break;
96 case 3:
Misha Brukmand554ebf2003-09-23 16:17:50 +000097 if (read_vbr(Buf, EndBuf, Result->Arg1) ||
98 read_vbr(Buf, EndBuf, Result->Arg2) ||
99 read_vbr(Buf, EndBuf, Result->Arg3))
100 throw std::string("Error reading from buffer");
Chris Lattner00950542001-06-06 20:29:01 +0000101 break;
102 default:
Misha Brukmand554ebf2003-09-23 16:17:50 +0000103 if (read_vbr(Buf, EndBuf, Result->Arg1) ||
104 read_vbr(Buf, EndBuf, Result->Arg2))
105 throw std::string("Error reading from buffer");
Chris Lattner00950542001-06-06 20:29:01 +0000106
107 // Allocate a vector to hold arguments 3, 4, 5, 6 ...
Misha Brukmand554ebf2003-09-23 16:17:50 +0000108 Result->VarArgs = new std::vector<unsigned>(Result->NumOperands-2);
109 for (unsigned a = 0; a < Result->NumOperands-2; a++)
110 if (read_vbr(Buf, EndBuf, (*Result->VarArgs)[a]))
111 throw std::string("Error reading from buffer");
112
Chris Lattner00950542001-06-06 20:29:01 +0000113 break;
114 }
Misha Brukmand554ebf2003-09-23 16:17:50 +0000115 if (align32(Buf, EndBuf))
116 throw std::string("Unaligned bytecode buffer.");
Chris Lattner00950542001-06-06 20:29:01 +0000117 break;
118 }
119
Chris Lattnerc8b25d42001-07-07 08:36:50 +0000120#if 0
Misha Brukmand554ebf2003-09-23 16:17:50 +0000121 std::cerr << "NO: " << Result->NumOperands << " opcode: " << Result->Opcode
122 << " Ty: "<< Result->Ty->getDescription()<< " arg1: "<< Result->Arg1
123 << " arg2: " << Result->Arg2 << " arg3: " << Result->Arg3 << "\n";
Chris Lattnerc8b25d42001-07-07 08:36:50 +0000124#endif
Misha Brukmand554ebf2003-09-23 16:17:50 +0000125 return Result;
Chris Lattner00950542001-06-06 20:29:01 +0000126}
127
128
Chris Lattner3483f542003-10-09 18:25:19 +0000129Instruction *BytecodeParser::ParseInstruction(const unsigned char *&Buf,
130 const unsigned char *EndBuf) {
Misha Brukmand554ebf2003-09-23 16:17:50 +0000131 std::auto_ptr<RawInst> Raw = ParseRawInst(Buf, EndBuf);
Chris Lattner00950542001-06-06 20:29:01 +0000132
Misha Brukmand554ebf2003-09-23 16:17:50 +0000133 if (Raw->Opcode >= Instruction::BinaryOpsBegin &&
Chris Lattner3483f542003-10-09 18:25:19 +0000134 Raw->Opcode < Instruction::BinaryOpsEnd && Raw->NumOperands == 2)
135 return BinaryOperator::create((Instruction::BinaryOps)Raw->Opcode,
136 getValue(Raw->Ty, Raw->Arg1),
137 getValue(Raw->Ty, Raw->Arg2));
Chris Lattner027dcc52001-07-08 21:10:27 +0000138
Misha Brukmand554ebf2003-09-23 16:17:50 +0000139 switch (Raw->Opcode) {
Chris Lattner8f77dae2003-05-08 02:44:12 +0000140 case Instruction::VarArg:
Chris Lattner5ab1f872001-10-21 00:14:44 +0000141 case Instruction::Cast: {
Chris Lattner3483f542003-10-09 18:25:19 +0000142 Value *V = getValue(Raw->Ty, Raw->Arg1);
Misha Brukmand554ebf2003-09-23 16:17:50 +0000143 const Type *Ty = getType(Raw->Arg2);
Chris Lattner3483f542003-10-09 18:25:19 +0000144 if (Ty == 0) throw std::string("Invalid cast!\n");
Misha Brukmand554ebf2003-09-23 16:17:50 +0000145 if (Raw->Opcode == Instruction::Cast)
Chris Lattner3483f542003-10-09 18:25:19 +0000146 return new CastInst(V, Ty);
Chris Lattner8f77dae2003-05-08 02:44:12 +0000147 else
Chris Lattner3483f542003-10-09 18:25:19 +0000148 return new VarArgInst(V, Ty);
Chris Lattner5ab1f872001-10-21 00:14:44 +0000149 }
Chris Lattner027dcc52001-07-08 21:10:27 +0000150 case Instruction::PHINode: {
Misha Brukmand554ebf2003-09-23 16:17:50 +0000151 PHINode *PN = new PHINode(Raw->Ty);
152 switch (Raw->NumOperands) {
Chris Lattneree976f32001-06-11 15:04:40 +0000153 case 0:
154 case 1:
Chris Lattner3483f542003-10-09 18:25:19 +0000155 case 3:
156 delete PN;
157 throw std::string("Invalid phi node encountered!\n");
158 case 2:
159 PN->addIncoming(getValue(Raw->Ty, Raw->Arg1), getBasicBlock(Raw->Arg2));
Chris Lattneree976f32001-06-11 15:04:40 +0000160 break;
Chris Lattner00950542001-06-06 20:29:01 +0000161 default:
Chris Lattner3483f542003-10-09 18:25:19 +0000162 PN->addIncoming(getValue(Raw->Ty, Raw->Arg1), getBasicBlock(Raw->Arg2));
Misha Brukmand554ebf2003-09-23 16:17:50 +0000163 if (Raw->VarArgs->size() & 1) {
Chris Lattneree976f32001-06-11 15:04:40 +0000164 delete PN;
Chris Lattner3483f542003-10-09 18:25:19 +0000165 throw std::string("PHI Node with ODD number of arguments!\n");
Chris Lattneree976f32001-06-11 15:04:40 +0000166 } else {
Misha Brukmand554ebf2003-09-23 16:17:50 +0000167 std::vector<unsigned> &args = *Raw->VarArgs;
Chris Lattneree976f32001-06-11 15:04:40 +0000168 for (unsigned i = 0; i < args.size(); i+=2)
Chris Lattner4ee8ef22003-10-08 22:52:54 +0000169 PN->addIncoming(getValue(Raw->Ty, args[i]), getBasicBlock(args[i+1]));
Chris Lattner00950542001-06-06 20:29:01 +0000170 }
Misha Brukmand554ebf2003-09-23 16:17:50 +0000171 delete Raw->VarArgs;
Chris Lattneree976f32001-06-11 15:04:40 +0000172 break;
Chris Lattner00950542001-06-06 20:29:01 +0000173 }
Chris Lattner3483f542003-10-09 18:25:19 +0000174 return PN;
Chris Lattner027dcc52001-07-08 21:10:27 +0000175 }
176
177 case Instruction::Shl:
178 case Instruction::Shr:
Chris Lattner3483f542003-10-09 18:25:19 +0000179 return new ShiftInst((Instruction::OtherOps)Raw->Opcode,
180 getValue(Raw->Ty, Raw->Arg1),
181 getValue(Type::UByteTyID, Raw->Arg2));
Chris Lattner027dcc52001-07-08 21:10:27 +0000182 case Instruction::Ret:
Chris Lattner3483f542003-10-09 18:25:19 +0000183 if (Raw->NumOperands == 0)
184 return new ReturnInst();
185 else if (Raw->NumOperands == 1)
186 return new ReturnInst(getValue(Raw->Ty, Raw->Arg1));
Chris Lattner027dcc52001-07-08 21:10:27 +0000187 break;
188
189 case Instruction::Br:
Chris Lattner3483f542003-10-09 18:25:19 +0000190 if (Raw->NumOperands == 1)
191 return new BranchInst(getBasicBlock(Raw->Arg1));
192 else if (Raw->NumOperands == 3)
193 return new BranchInst(getBasicBlock(Raw->Arg1), getBasicBlock(Raw->Arg2),
194 getValue(Type::BoolTyID , Raw->Arg3));
195 throw std::string("Invalid number of operands for a 'br' instruction!");
Chris Lattner027dcc52001-07-08 21:10:27 +0000196
197 case Instruction::Switch: {
Chris Lattner3483f542003-10-09 18:25:19 +0000198 SwitchInst *I = new SwitchInst(getValue(Raw->Ty, Raw->Arg1),
199 getBasicBlock(Raw->Arg2));
200 if (Raw->NumOperands < 3)
201 return I;
Chris Lattner00950542001-06-06 20:29:01 +0000202
Misha Brukmand554ebf2003-09-23 16:17:50 +0000203 if (Raw->NumOperands == 3 || Raw->VarArgs->size() & 1) {
Chris Lattner00950542001-06-06 20:29:01 +0000204 delete I;
Chris Lattner3483f542003-10-09 18:25:19 +0000205 throw std::string("Switch statement with odd number of arguments!");
206 }
Chris Lattner00950542001-06-06 20:29:01 +0000207
Misha Brukmand554ebf2003-09-23 16:17:50 +0000208 std::vector<unsigned> &args = *Raw->VarArgs;
Chris Lattner00950542001-06-06 20:29:01 +0000209 for (unsigned i = 0; i < args.size(); i += 2)
Misha Brukmand554ebf2003-09-23 16:17:50 +0000210 I->addCase(cast<Constant>(getValue(Raw->Ty, args[i])),
Chris Lattner4ee8ef22003-10-08 22:52:54 +0000211 getBasicBlock(args[i+1]));
Chris Lattner00950542001-06-06 20:29:01 +0000212
Misha Brukmand554ebf2003-09-23 16:17:50 +0000213 delete Raw->VarArgs;
Chris Lattner3483f542003-10-09 18:25:19 +0000214 return I;
Chris Lattner027dcc52001-07-08 21:10:27 +0000215 }
216
217 case Instruction::Call: {
Misha Brukmand554ebf2003-09-23 16:17:50 +0000218 Value *F = getValue(Raw->Ty, Raw->Arg1);
Chris Lattner00950542001-06-06 20:29:01 +0000219
Chris Lattner3483f542003-10-09 18:25:19 +0000220 // Check to make sure we have a pointer to function type
Chris Lattner5bea4112003-09-05 18:25:29 +0000221 const PointerType *PTy = dyn_cast<PointerType>(F->getType());
Chris Lattner3483f542003-10-09 18:25:19 +0000222 if (PTy == 0) throw std::string("Call to non function pointer value!");
Chris Lattner5bea4112003-09-05 18:25:29 +0000223 const FunctionType *FTy = dyn_cast<FunctionType>(PTy->getElementType());
Chris Lattner3483f542003-10-09 18:25:19 +0000224 if (FTy == 0) throw std::string("Call to non function pointer value!");
Chris Lattnere5a57ee2001-07-25 22:47:55 +0000225
Chris Lattner0d75d8d72003-03-06 16:32:25 +0000226 std::vector<Value *> Params;
Chris Lattner5bea4112003-09-05 18:25:29 +0000227 const FunctionType::ParamTypes &PL = FTy->getParamTypes();
Chris Lattner05950c32001-10-13 06:47:01 +0000228
Chris Lattner5bea4112003-09-05 18:25:29 +0000229 if (!FTy->isVarArg()) {
Chris Lattner2aac6bf2002-04-04 22:19:18 +0000230 FunctionType::ParamTypes::const_iterator It = PL.begin();
Chris Lattnere5a57ee2001-07-25 22:47:55 +0000231
Misha Brukmand554ebf2003-09-23 16:17:50 +0000232 switch (Raw->NumOperands) {
Chris Lattner3483f542003-10-09 18:25:19 +0000233 case 0: throw std::string("Invalid call instruction encountered!");
Chris Lattnere5a57ee2001-07-25 22:47:55 +0000234 case 1: break;
Misha Brukmand554ebf2003-09-23 16:17:50 +0000235 case 2: Params.push_back(getValue(*It++, Raw->Arg2)); break;
236 case 3: Params.push_back(getValue(*It++, Raw->Arg2));
Chris Lattner3483f542003-10-09 18:25:19 +0000237 if (It == PL.end()) throw std::string("Invalid call instruction!");
Misha Brukmand554ebf2003-09-23 16:17:50 +0000238 Params.push_back(getValue(*It++, Raw->Arg3)); break;
Chris Lattnere5a57ee2001-07-25 22:47:55 +0000239 default:
Misha Brukmand554ebf2003-09-23 16:17:50 +0000240 Params.push_back(getValue(*It++, Raw->Arg2));
Chris Lattnere5a57ee2001-07-25 22:47:55 +0000241 {
Misha Brukmand554ebf2003-09-23 16:17:50 +0000242 std::vector<unsigned> &args = *Raw->VarArgs;
Chris Lattnere5a57ee2001-07-25 22:47:55 +0000243 for (unsigned i = 0; i < args.size(); i++) {
Chris Lattner3483f542003-10-09 18:25:19 +0000244 if (It == PL.end()) throw std::string("Invalid call instruction!");
Chris Lattnere5a57ee2001-07-25 22:47:55 +0000245 Params.push_back(getValue(*It++, args[i]));
246 }
Chris Lattner00950542001-06-06 20:29:01 +0000247 }
Misha Brukmand554ebf2003-09-23 16:17:50 +0000248 delete Raw->VarArgs;
Chris Lattnere5a57ee2001-07-25 22:47:55 +0000249 }
Chris Lattner3483f542003-10-09 18:25:19 +0000250 if (It != PL.end()) throw std::string("Invalid call instruction!");
Chris Lattnere5a57ee2001-07-25 22:47:55 +0000251 } else {
Misha Brukmand554ebf2003-09-23 16:17:50 +0000252 if (Raw->NumOperands > 2) {
253 std::vector<unsigned> &args = *Raw->VarArgs;
Chris Lattner3483f542003-10-09 18:25:19 +0000254 if (args.size() < 1) throw std::string("Invalid call instruction!");
Chris Lattnere5a57ee2001-07-25 22:47:55 +0000255
Chris Lattner3483f542003-10-09 18:25:19 +0000256 if ((args.size() & 1) != 0) // Must be pairs of type/value
257 throw std::string("Invalid call instruction!");
Chris Lattner05950c32001-10-13 06:47:01 +0000258 for (unsigned i = 0; i < args.size(); i+=2) {
259 const Type *Ty = getType(args[i]);
Chris Lattner3483f542003-10-09 18:25:19 +0000260 if (Ty == 0) throw std::string("Invalid call instruction!");
261 Params.push_back(getValue(Ty, args[i+1]));
Chris Lattner05950c32001-10-13 06:47:01 +0000262 }
Misha Brukmand554ebf2003-09-23 16:17:50 +0000263 delete Raw->VarArgs;
Chris Lattner00950542001-06-06 20:29:01 +0000264 }
Chris Lattner00950542001-06-06 20:29:01 +0000265 }
Chris Lattner00950542001-06-06 20:29:01 +0000266
Chris Lattner3483f542003-10-09 18:25:19 +0000267 return new CallInst(F, Params);
Chris Lattner027dcc52001-07-08 21:10:27 +0000268 }
Chris Lattner05950c32001-10-13 06:47:01 +0000269 case Instruction::Invoke: {
Misha Brukmand554ebf2003-09-23 16:17:50 +0000270 Value *F = getValue(Raw->Ty, Raw->Arg1);
Chris Lattner05950c32001-10-13 06:47:01 +0000271
Chris Lattner3483f542003-10-09 18:25:19 +0000272 // Check to make sure we have a pointer to function type
Chris Lattner5bea4112003-09-05 18:25:29 +0000273 const PointerType *PTy = dyn_cast<PointerType>(F->getType());
Chris Lattner3483f542003-10-09 18:25:19 +0000274 if (PTy == 0) throw std::string("Invoke to non function pointer value!");
Chris Lattner5bea4112003-09-05 18:25:29 +0000275 const FunctionType *FTy = dyn_cast<FunctionType>(PTy->getElementType());
Chris Lattner3483f542003-10-09 18:25:19 +0000276 if (FTy == 0) throw std::string("Invoke to non function pointer value!");
Chris Lattner05950c32001-10-13 06:47:01 +0000277
Chris Lattner0d75d8d72003-03-06 16:32:25 +0000278 std::vector<Value *> Params;
Chris Lattner5bea4112003-09-05 18:25:29 +0000279 const FunctionType::ParamTypes &PL = FTy->getParamTypes();
Misha Brukmand554ebf2003-09-23 16:17:50 +0000280 std::vector<unsigned> &args = *Raw->VarArgs;
Chris Lattner05950c32001-10-13 06:47:01 +0000281
282 BasicBlock *Normal, *Except;
283
Chris Lattner5bea4112003-09-05 18:25:29 +0000284 if (!FTy->isVarArg()) {
Chris Lattner3483f542003-10-09 18:25:19 +0000285 if (Raw->NumOperands < 3) throw std::string("Invalid call instruction!");
Chris Lattner05950c32001-10-13 06:47:01 +0000286
Chris Lattner4ee8ef22003-10-08 22:52:54 +0000287 Normal = getBasicBlock(Raw->Arg2);
Misha Brukmand554ebf2003-09-23 16:17:50 +0000288 if (Raw->NumOperands == 3)
Chris Lattner4ee8ef22003-10-08 22:52:54 +0000289 Except = getBasicBlock(Raw->Arg3);
Chris Lattnereaeaad62003-06-17 13:31:10 +0000290 else {
Chris Lattner4ee8ef22003-10-08 22:52:54 +0000291 Except = getBasicBlock(args[0]);
Chris Lattner05950c32001-10-13 06:47:01 +0000292
Chris Lattnereaeaad62003-06-17 13:31:10 +0000293 FunctionType::ParamTypes::const_iterator It = PL.begin();
294 for (unsigned i = 1; i < args.size(); i++) {
Chris Lattner3483f542003-10-09 18:25:19 +0000295 if (It == PL.end()) throw std::string("Invalid invoke instruction!");
Chris Lattnereaeaad62003-06-17 13:31:10 +0000296 Params.push_back(getValue(*It++, args[i]));
297 }
Chris Lattner3483f542003-10-09 18:25:19 +0000298 if (It != PL.end()) throw std::string("Invalid invoke instruction!");
Chris Lattner05950c32001-10-13 06:47:01 +0000299 }
Chris Lattner05950c32001-10-13 06:47:01 +0000300 } else {
Chris Lattner3483f542003-10-09 18:25:19 +0000301 if (args.size() < 4) throw std::string("Invalid invoke instruction!");
Chris Lattner4ee8ef22003-10-08 22:52:54 +0000302 if (args[0] != Type::LabelTyID || args[2] != Type::LabelTyID)
Chris Lattner3483f542003-10-09 18:25:19 +0000303 throw std::string("Invalid invoke instruction!");
Chris Lattner4ee8ef22003-10-08 22:52:54 +0000304
305 Normal = getBasicBlock(args[1]);
306 Except = getBasicBlock(args[3]);
Chris Lattner05950c32001-10-13 06:47:01 +0000307
Chris Lattner3483f542003-10-09 18:25:19 +0000308 if ((args.size() & 1) != 0) // Must be pairs of type/value
309 throw std::string("Invalid invoke instruction!");
310
311 for (unsigned i = 4; i < args.size(); i += 2)
Chris Lattner36392bc2003-10-08 21:18:57 +0000312 Params.push_back(getValue(args[i], args[i+1]));
Chris Lattner05950c32001-10-13 06:47:01 +0000313 }
314
Misha Brukmand554ebf2003-09-23 16:17:50 +0000315 if (Raw->NumOperands > 3)
316 delete Raw->VarArgs;
Chris Lattner3483f542003-10-09 18:25:19 +0000317 return new InvokeInst(F, Normal, Except, Params);
Chris Lattner05950c32001-10-13 06:47:01 +0000318 }
Chris Lattner027dcc52001-07-08 21:10:27 +0000319 case Instruction::Malloc:
Chris Lattner3483f542003-10-09 18:25:19 +0000320 if (Raw->NumOperands > 2) throw std::string("Invalid malloc instruction!");
321 if (!isa<PointerType>(Raw->Ty))
322 throw std::string("Invalid malloc instruction!");
323
324 return new MallocInst(cast<PointerType>(Raw->Ty)->getElementType(),
325 Raw->NumOperands ? getValue(Type::UIntTyID,
326 Raw->Arg1) : 0);
Chris Lattner027dcc52001-07-08 21:10:27 +0000327
328 case Instruction::Alloca:
Chris Lattner3483f542003-10-09 18:25:19 +0000329 if (Raw->NumOperands > 2) throw std::string("Invalid alloca instruction!");
330 if (!isa<PointerType>(Raw->Ty))
331 throw std::string("Invalid alloca instruction!");
Chris Lattner027dcc52001-07-08 21:10:27 +0000332
Chris Lattner3483f542003-10-09 18:25:19 +0000333 return new AllocaInst(cast<PointerType>(Raw->Ty)->getElementType(),
334 Raw->NumOperands ? getValue(Type::UIntTyID,
335 Raw->Arg1) : 0);
Chris Lattner027dcc52001-07-08 21:10:27 +0000336 case Instruction::Free:
Chris Lattner3483f542003-10-09 18:25:19 +0000337 if (!isa<PointerType>(Raw->Ty))
338 throw std::string("Invalid free instruction!");
339 return new FreeInst(getValue(Raw->Ty, Raw->Arg1));
Chris Lattner027dcc52001-07-08 21:10:27 +0000340
Chris Lattnerab5ac6b2001-07-08 23:22:50 +0000341 case Instruction::GetElementPtr: {
Chris Lattner0d75d8d72003-03-06 16:32:25 +0000342 std::vector<Value*> Idx;
Chris Lattner3483f542003-10-09 18:25:19 +0000343 if (!isa<PointerType>(Raw->Ty))
344 throw std::string("Invalid getelementptr instruction!");
Misha Brukmand554ebf2003-09-23 16:17:50 +0000345 const CompositeType *TopTy = dyn_cast<CompositeType>(Raw->Ty);
Chris Lattnerb2b12b42001-11-26 16:54:55 +0000346
Misha Brukmand554ebf2003-09-23 16:17:50 +0000347 switch (Raw->NumOperands) {
Chris Lattner3483f542003-10-09 18:25:19 +0000348 case 0: throw std::string("Invalid getelementptr instruction!");
Chris Lattner027dcc52001-07-08 21:10:27 +0000349 case 1: break;
Chris Lattnerb2b12b42001-11-26 16:54:55 +0000350 case 2:
Chris Lattner3483f542003-10-09 18:25:19 +0000351 if (!TopTy) throw std::string("Invalid getelementptr instruction!");
352 Idx.push_back(getValue(TopTy->getIndexType(), Raw->Arg2));
Chris Lattnerb2b12b42001-11-26 16:54:55 +0000353 break;
354 case 3: {
Chris Lattner3483f542003-10-09 18:25:19 +0000355 if (!TopTy) throw std::string("Invalid getelementptr instruction!");
356 Idx.push_back(getValue(TopTy->getIndexType(), Raw->Arg2));
Chris Lattnerb2b12b42001-11-26 16:54:55 +0000357
Chris Lattnercc63f1c2002-08-22 23:37:20 +0000358 const Type *ETy = GetElementPtrInst::getIndexedType(TopTy, Idx, true);
Chris Lattnerb2b12b42001-11-26 16:54:55 +0000359 const CompositeType *ElTy = dyn_cast_or_null<CompositeType>(ETy);
Chris Lattner3483f542003-10-09 18:25:19 +0000360 if (!ElTy) throw std::string("Invalid getelementptr instruction!");
Chris Lattnerb2b12b42001-11-26 16:54:55 +0000361
Chris Lattner3483f542003-10-09 18:25:19 +0000362 Idx.push_back(getValue(ElTy->getIndexType(), Raw->Arg3));
Chris Lattnerb2b12b42001-11-26 16:54:55 +0000363 break;
364 }
Chris Lattner027dcc52001-07-08 21:10:27 +0000365 default:
Chris Lattner3483f542003-10-09 18:25:19 +0000366 if (!TopTy) throw std::string("Invalid getelementptr instruction!");
367 Idx.push_back(getValue(TopTy->getIndexType(), Raw->Arg2));
Chris Lattnerb2b12b42001-11-26 16:54:55 +0000368
Misha Brukmand554ebf2003-09-23 16:17:50 +0000369 std::vector<unsigned> &args = *Raw->VarArgs;
Chris Lattner027dcc52001-07-08 21:10:27 +0000370 for (unsigned i = 0, E = args.size(); i != E; ++i) {
Misha Brukmand554ebf2003-09-23 16:17:50 +0000371 const Type *ETy = GetElementPtrInst::getIndexedType(Raw->Ty, Idx, true);
Chris Lattnerb2b12b42001-11-26 16:54:55 +0000372 const CompositeType *ElTy = dyn_cast_or_null<CompositeType>(ETy);
Chris Lattner3483f542003-10-09 18:25:19 +0000373 if (!ElTy) throw std::string("Invalid getelementptr instruction!");
374 Idx.push_back(getValue(ElTy->getIndexType(), args[i]));
Chris Lattner027dcc52001-07-08 21:10:27 +0000375 }
Misha Brukmand554ebf2003-09-23 16:17:50 +0000376 delete Raw->VarArgs;
Chris Lattner027dcc52001-07-08 21:10:27 +0000377 break;
378 }
Chris Lattner77a316a2001-11-12 21:48:38 +0000379
Chris Lattner3483f542003-10-09 18:25:19 +0000380 return new GetElementPtrInst(getValue(Raw->Ty, Raw->Arg1), Idx);
Chris Lattnerab5ac6b2001-07-08 23:22:50 +0000381 }
Chris Lattner09bd0252003-09-08 18:04:16 +0000382
Chris Lattnerdba2b222003-09-08 18:20:14 +0000383 case 62: // volatile load
Chris Lattner09bd0252003-09-08 18:04:16 +0000384 case Instruction::Load:
Chris Lattner3483f542003-10-09 18:25:19 +0000385 if (Raw->NumOperands != 1 || !isa<PointerType>(Raw->Ty))
386 throw std::string("Invalid load instruction!");
387 return new LoadInst(getValue(Raw->Ty, Raw->Arg1), "", Raw->Opcode == 62);
Chris Lattnerb2b12b42001-11-26 16:54:55 +0000388
Chris Lattnerdba2b222003-09-08 18:20:14 +0000389 case 63: // volatile store
Chris Lattner09bd0252003-09-08 18:04:16 +0000390 case Instruction::Store: {
Chris Lattner3483f542003-10-09 18:25:19 +0000391 if (!isa<PointerType>(Raw->Ty) || Raw->NumOperands != 2)
392 throw std::string("Invalid store instruction!");
Chris Lattnerab5ac6b2001-07-08 23:22:50 +0000393
Misha Brukmand554ebf2003-09-23 16:17:50 +0000394 Value *Ptr = getValue(Raw->Ty, Raw->Arg2);
Chris Lattner352eef72002-08-21 22:55:27 +0000395 const Type *ValTy = cast<PointerType>(Ptr->getType())->getElementType();
Chris Lattner3483f542003-10-09 18:25:19 +0000396 return new StoreInst(getValue(ValTy, Raw->Arg1), Ptr, Raw->Opcode == 63);
Chris Lattner00950542001-06-06 20:29:01 +0000397 }
Chris Lattner36143fc2003-09-08 18:54:55 +0000398 case Instruction::Unwind:
Chris Lattner3483f542003-10-09 18:25:19 +0000399 if (Raw->NumOperands != 0) throw std::string("Invalid unwind instruction!");
400 return new UnwindInst();
Misha Brukmand554ebf2003-09-23 16:17:50 +0000401 } // end switch(Raw->Opcode)
Chris Lattner00950542001-06-06 20:29:01 +0000402
Misha Brukmand554ebf2003-09-23 16:17:50 +0000403 std::cerr << "Unrecognized instruction! " << Raw->Opcode
Chris Lattner0d75d8d72003-03-06 16:32:25 +0000404 << " ADDR = 0x" << (void*)Buf << "\n";
Chris Lattner3483f542003-10-09 18:25:19 +0000405 throw std::string("Unrecognized instruction!");
Chris Lattner00950542001-06-06 20:29:01 +0000406}