blob: 227980a75ecddecb7cdcc14cc340bd540e4173ea [file] [log] [blame]
Chris Lattner00950542001-06-06 20:29:01 +00001//===-- WriteInst.cpp - Functions for writing instructions -------*- C++ -*--=//
2//
3// This file implements the routines for encoding instruction opcodes to a
4// bytecode stream.
5//
6// Note that the performance of this library is not terribly important, because
7// it shouldn't be used by JIT type applications... so it is not a huge focus
8// at least. :)
9//
10//===----------------------------------------------------------------------===//
11
12#include "WriterInternals.h"
13#include "llvm/Module.h"
Chris Lattner2fbfdcf2002-04-07 20:49:59 +000014#include "llvm/Function.h"
Chris Lattner00950542001-06-06 20:29:01 +000015#include "llvm/BasicBlock.h"
Chris Lattner00950542001-06-06 20:29:01 +000016#include "llvm/DerivedTypes.h"
Chris Lattneref9c23f2001-10-03 14:53:21 +000017#include "llvm/iOther.h"
Chris Lattner1b98c5c2001-10-13 06:48:38 +000018#include "llvm/iTerminators.h"
Chris Lattner00950542001-06-06 20:29:01 +000019#include <algorithm>
20
21typedef unsigned char uchar;
22
23// outputInstructionFormat0 - Output those wierd instructions that have a large
24// number of operands or have large operands themselves...
25//
26// Format: [opcode] [type] [numargs] [arg0] [arg1] ... [arg<numargs-1>]
27//
28static void outputInstructionFormat0(const Instruction *I,
29 const SlotCalculator &Table,
Chris Lattner697954c2002-01-20 22:54:45 +000030 unsigned Type, std::deque<uchar> &Out) {
Chris Lattner00950542001-06-06 20:29:01 +000031 // Opcode must have top two bits clear...
Chris Lattner2b9f6002001-10-23 03:21:10 +000032 output_vbr(I->getOpcode() << 2, Out); // Instruction Opcode ID
Chris Lattner00950542001-06-06 20:29:01 +000033 output_vbr(Type, Out); // Result type
34
Chris Lattnerc8b25d42001-07-07 08:36:50 +000035 unsigned NumArgs = I->getNumOperands();
Chris Lattner5ab1f872001-10-21 00:14:44 +000036 output_vbr(NumArgs + isa<CastInst>(I), Out);
Chris Lattner00950542001-06-06 20:29:01 +000037
Chris Lattnerc8b25d42001-07-07 08:36:50 +000038 for (unsigned i = 0; i < NumArgs; ++i) {
Chris Lattnere5a57ee2001-07-25 22:47:55 +000039 int Slot = Table.getValSlot(I->getOperand(i));
40 assert(Slot >= 0 && "No slot number for value!?!?");
41 output_vbr((unsigned)Slot, Out);
42 }
Chris Lattner5ab1f872001-10-21 00:14:44 +000043
44 if (isa<CastInst>(I)) {
45 int Slot = Table.getValSlot(I->getType());
46 assert(Slot != -1 && "Cast return type unknown?");
47 output_vbr((unsigned)Slot, Out);
48 }
49
Chris Lattnere5a57ee2001-07-25 22:47:55 +000050 align32(Out); // We must maintain correct alignment!
51}
52
53
Chris Lattner2fbfdcf2002-04-07 20:49:59 +000054// outputInstrVarArgsCall - Output the obsurdly annoying varargs function calls.
Chris Lattnere5a57ee2001-07-25 22:47:55 +000055// This are more annoying than most because the signature of the call does not
56// tell us anything about the types of the arguments in the varargs portion.
57// Because of this, we encode (as type 0) all of the argument types explicitly
58// before the argument value. This really sucks, but you shouldn't be using
59// varargs functions in your code! *death to printf*!
60//
61// Format: [opcode] [type] [numargs] [arg0] [arg1] ... [arg<numargs-1>]
62//
63static void outputInstrVarArgsCall(const Instruction *I,
64 const SlotCalculator &Table, unsigned Type,
Chris Lattner697954c2002-01-20 22:54:45 +000065 std::deque<uchar> &Out) {
Chris Lattner1b98c5c2001-10-13 06:48:38 +000066 assert(isa<CallInst>(I) || isa<InvokeInst>(I));
Chris Lattnere5a57ee2001-07-25 22:47:55 +000067 // Opcode must have top two bits clear...
Chris Lattner2b9f6002001-10-23 03:21:10 +000068 output_vbr(I->getOpcode() << 2, Out); // Instruction Opcode ID
Chris Lattnere5a57ee2001-07-25 22:47:55 +000069 output_vbr(Type, Out); // Result type (varargs type)
70
71 unsigned NumArgs = I->getNumOperands();
Chris Lattner1b98c5c2001-10-13 06:48:38 +000072 output_vbr(NumArgs*2, Out);
Chris Lattner2fbfdcf2002-04-07 20:49:59 +000073 // TODO: Don't need to emit types for the fixed types of the varargs function
Chris Lattner1b98c5c2001-10-13 06:48:38 +000074 // prototype...
Chris Lattnere5a57ee2001-07-25 22:47:55 +000075
Chris Lattner2fbfdcf2002-04-07 20:49:59 +000076 // The type for the function has already been emitted in the type field of the
Chris Lattner1b98c5c2001-10-13 06:48:38 +000077 // instruction. Just emit the slot # now.
Chris Lattnere5a57ee2001-07-25 22:47:55 +000078 int Slot = Table.getValSlot(I->getOperand(0));
79 assert(Slot >= 0 && "No slot number for value!?!?");
80 output_vbr((unsigned)Slot, Out);
81
Chris Lattner1b98c5c2001-10-13 06:48:38 +000082 // Output a dummy field to fill Arg#2 in the reader that is currently unused
83 // for varargs calls. This is a gross hack to make the code simpler, but we
84 // aren't really doing very small bytecode for varargs calls anyways.
85 // FIXME in the future: Smaller bytecode for varargs calls
86 output_vbr(0, Out);
Chris Lattnere5a57ee2001-07-25 22:47:55 +000087
Chris Lattner1b98c5c2001-10-13 06:48:38 +000088 for (unsigned i = 1; i < NumArgs; ++i) {
Chris Lattnere5a57ee2001-07-25 22:47:55 +000089 // Output Arg Type ID
90 Slot = Table.getValSlot(I->getOperand(i)->getType());
91 assert(Slot >= 0 && "No slot number for value!?!?");
92 output_vbr((unsigned)Slot, Out);
93
94 // Output arg ID itself
95 Slot = Table.getValSlot(I->getOperand(i));
Chris Lattnerc8b25d42001-07-07 08:36:50 +000096 assert(Slot >= 0 && "No slot number for value!?!?");
Chris Lattner00950542001-06-06 20:29:01 +000097 output_vbr((unsigned)Slot, Out);
98 }
99 align32(Out); // We must maintain correct alignment!
100}
101
102
103// outputInstructionFormat1 - Output one operand instructions, knowing that no
104// operand index is >= 2^12.
105//
106static void outputInstructionFormat1(const Instruction *I,
107 const SlotCalculator &Table, int *Slots,
Chris Lattner697954c2002-01-20 22:54:45 +0000108 unsigned Type, std::deque<uchar> &Out) {
Chris Lattner2b9f6002001-10-23 03:21:10 +0000109 unsigned Opcode = I->getOpcode(); // Instruction Opcode ID
Chris Lattner00950542001-06-06 20:29:01 +0000110
111 // bits Instruction format:
112 // --------------------------
Chris Lattner2b9f6002001-10-23 03:21:10 +0000113 // 01-00: Opcode type, fixed to 1.
114 // 07-02: Opcode
115 // 19-08: Resulting type plane
116 // 31-20: Operand #1 (if set to (2^12-1), then zero operands)
Chris Lattner00950542001-06-06 20:29:01 +0000117 //
Chris Lattner2b9f6002001-10-23 03:21:10 +0000118 unsigned Bits = 1 | (Opcode << 2) | (Type << 8) | (Slots[0] << 20);
Chris Lattner00950542001-06-06 20:29:01 +0000119 // cerr << "1 " << IType << " " << Type << " " << Slots[0] << endl;
Chris Lattner2b9f6002001-10-23 03:21:10 +0000120 output(Bits, Out);
Chris Lattner00950542001-06-06 20:29:01 +0000121}
122
123
124// outputInstructionFormat2 - Output two operand instructions, knowing that no
125// operand index is >= 2^8.
126//
127static void outputInstructionFormat2(const Instruction *I,
128 const SlotCalculator &Table, int *Slots,
Chris Lattner697954c2002-01-20 22:54:45 +0000129 unsigned Type, std::deque<uchar> &Out) {
Chris Lattner2b9f6002001-10-23 03:21:10 +0000130 unsigned Opcode = I->getOpcode(); // Instruction Opcode ID
Chris Lattner00950542001-06-06 20:29:01 +0000131
132 // bits Instruction format:
133 // --------------------------
Chris Lattner2b9f6002001-10-23 03:21:10 +0000134 // 01-00: Opcode type, fixed to 2.
135 // 07-02: Opcode
136 // 15-08: Resulting type plane
137 // 23-16: Operand #1
138 // 31-24: Operand #2
Chris Lattner00950542001-06-06 20:29:01 +0000139 //
Chris Lattner2b9f6002001-10-23 03:21:10 +0000140 unsigned Bits = 2 | (Opcode << 2) | (Type << 8) |
141 (Slots[0] << 16) | (Slots[1] << 24);
Chris Lattner00950542001-06-06 20:29:01 +0000142 // cerr << "2 " << IType << " " << Type << " " << Slots[0] << " "
143 // << Slots[1] << endl;
Chris Lattner2b9f6002001-10-23 03:21:10 +0000144 output(Bits, Out);
Chris Lattner00950542001-06-06 20:29:01 +0000145}
146
147
148// outputInstructionFormat3 - Output three operand instructions, knowing that no
149// operand index is >= 2^6.
150//
151static void outputInstructionFormat3(const Instruction *I,
152 const SlotCalculator &Table, int *Slots,
Chris Lattner697954c2002-01-20 22:54:45 +0000153 unsigned Type, std::deque<uchar> &Out) {
Chris Lattner2b9f6002001-10-23 03:21:10 +0000154 unsigned Opcode = I->getOpcode(); // Instruction Opcode ID
Chris Lattner00950542001-06-06 20:29:01 +0000155
156 // bits Instruction format:
157 // --------------------------
Chris Lattner2b9f6002001-10-23 03:21:10 +0000158 // 01-00: Opcode type, fixed to 3.
159 // 07-02: Opcode
160 // 13-08: Resulting type plane
161 // 19-14: Operand #1
162 // 25-20: Operand #2
163 // 31-26: Operand #3
Chris Lattner00950542001-06-06 20:29:01 +0000164 //
Chris Lattner2b9f6002001-10-23 03:21:10 +0000165 unsigned Bits = 3 | (Opcode << 2) | (Type << 8) |
166 (Slots[0] << 14) | (Slots[1] << 20) | (Slots[2] << 26);
Chris Lattnerc8b25d42001-07-07 08:36:50 +0000167 //cerr << "3 " << IType << " " << Type << " " << Slots[0] << " "
168 // << Slots[1] << " " << Slots[2] << endl;
Chris Lattner2b9f6002001-10-23 03:21:10 +0000169 output(Bits, Out);
Chris Lattner00950542001-06-06 20:29:01 +0000170}
171
Chris Lattnere8fdde12001-09-07 16:39:41 +0000172void BytecodeWriter::processInstruction(const Instruction *I) {
Chris Lattnera41f50d2001-07-07 19:24:15 +0000173 assert(I->getOpcode() < 64 && "Opcode too big???");
Chris Lattner00950542001-06-06 20:29:01 +0000174
Chris Lattnerc8b25d42001-07-07 08:36:50 +0000175 unsigned NumOperands = I->getNumOperands();
Chris Lattner00950542001-06-06 20:29:01 +0000176 int MaxOpSlot = 0;
Chris Lattnerc8b25d42001-07-07 08:36:50 +0000177 int Slots[3]; Slots[0] = (1 << 12)-1; // Marker to signify 0 operands
Chris Lattner00950542001-06-06 20:29:01 +0000178
Chris Lattnerc8b25d42001-07-07 08:36:50 +0000179 for (unsigned i = 0; i < NumOperands; ++i) {
180 const Value *Def = I->getOperand(i);
Chris Lattner00950542001-06-06 20:29:01 +0000181 int slot = Table.getValSlot(Def);
182 assert(slot != -1 && "Broken bytecode!");
183 if (slot > MaxOpSlot) MaxOpSlot = slot;
Chris Lattnerc8b25d42001-07-07 08:36:50 +0000184 if (i < 3) Slots[i] = slot;
Chris Lattner00950542001-06-06 20:29:01 +0000185 }
186
187 // Figure out which type to encode with the instruction. Typically we want
188 // the type of the first parameter, as opposed to the type of the instruction
189 // (for example, with setcc, we always know it returns bool, but the type of
190 // the first param is actually interesting). But if we have no arguments
191 // we take the type of the instruction itself.
192 //
Chris Lattnerab5ac6b2001-07-08 23:22:50 +0000193 const Type *Ty;
194 switch (I->getOpcode()) {
195 case Instruction::Malloc:
196 case Instruction::Alloca:
Chris Lattnerc8b25d42001-07-07 08:36:50 +0000197 Ty = I->getType(); // Malloc & Alloca ALWAYS want to encode the return type
Chris Lattnerab5ac6b2001-07-08 23:22:50 +0000198 break;
199 case Instruction::Store:
200 Ty = I->getOperand(1)->getType(); // Encode the pointer type...
Chris Lattner9b625032002-05-06 16:15:30 +0000201 assert(isa<PointerType>(Ty) && "Store to nonpointer type!?!?");
Chris Lattnerab5ac6b2001-07-08 23:22:50 +0000202 break;
203 default: // Otherwise use the default behavior...
204 Ty = NumOperands ? I->getOperand(0)->getType() : I->getType();
205 break;
206 }
Chris Lattner00950542001-06-06 20:29:01 +0000207
208 unsigned Type;
209 int Slot = Table.getValSlot(Ty);
210 assert(Slot != -1 && "Type not available!!?!");
211 Type = (unsigned)Slot;
212
Chris Lattner7c501472001-07-28 17:51:21 +0000213 // Make sure that we take the type number into consideration. We don't want
214 // to overflow the field size for the instruction format we select.
215 //
216 if (Slot > MaxOpSlot) MaxOpSlot = Slot;
217
Chris Lattner09083092001-07-08 04:57:15 +0000218 // Handle the special case for cast...
Chris Lattner5ab1f872001-10-21 00:14:44 +0000219 if (isa<CastInst>(I)) {
Chris Lattner09083092001-07-08 04:57:15 +0000220 // Cast has to encode the destination type as the second argument in the
221 // packet, or else we won't know what type to cast to!
222 Slots[1] = Table.getValSlot(I->getType());
223 assert(Slots[1] != -1 && "Cast return type unknown?");
224 if (Slots[1] > MaxOpSlot) MaxOpSlot = Slots[1];
225 NumOperands++;
Chris Lattneref9c23f2001-10-03 14:53:21 +0000226 } else if (const CallInst *CI = dyn_cast<CallInst>(I)) {// Handle VarArg calls
Chris Lattner9fcccb02002-06-05 17:49:40 +0000227 const PointerType *Ty = cast<PointerType>(CI->getCalledValue()->getType());
Chris Lattner2aac6bf2002-04-04 22:19:18 +0000228 if (cast<FunctionType>(Ty->getElementType())->isVarArg()) {
Chris Lattner1b98c5c2001-10-13 06:48:38 +0000229 outputInstrVarArgsCall(I, Table, Type, Out);
230 return;
231 }
232 } else if (const InvokeInst *II = dyn_cast<InvokeInst>(I)) { // ... & Invokes
Chris Lattner9fcccb02002-06-05 17:49:40 +0000233 const PointerType *Ty = cast<PointerType>(II->getCalledValue()->getType());
Chris Lattner2aac6bf2002-04-04 22:19:18 +0000234 if (cast<FunctionType>(Ty->getElementType())->isVarArg()) {
Chris Lattneref9c23f2001-10-03 14:53:21 +0000235 outputInstrVarArgsCall(I, Table, Type, Out);
236 return;
237 }
Chris Lattner09083092001-07-08 04:57:15 +0000238 }
Chris Lattner00950542001-06-06 20:29:01 +0000239
240 // Decide which instruction encoding to use. This is determined primarily by
241 // the number of operands, and secondarily by whether or not the max operand
242 // will fit into the instruction encoding. More operands == fewer bits per
243 // operand.
244 //
245 switch (NumOperands) {
246 case 0:
247 case 1:
248 if (MaxOpSlot < (1 << 12)-1) { // -1 because we use 4095 to indicate 0 ops
249 outputInstructionFormat1(I, Table, Slots, Type, Out);
Chris Lattnere8fdde12001-09-07 16:39:41 +0000250 return;
Chris Lattner00950542001-06-06 20:29:01 +0000251 }
252 break;
253
254 case 2:
255 if (MaxOpSlot < (1 << 8)) {
256 outputInstructionFormat2(I, Table, Slots, Type, Out);
Chris Lattnere8fdde12001-09-07 16:39:41 +0000257 return;
Chris Lattner00950542001-06-06 20:29:01 +0000258 }
259 break;
260
261 case 3:
262 if (MaxOpSlot < (1 << 6)) {
263 outputInstructionFormat3(I, Table, Slots, Type, Out);
Chris Lattnere8fdde12001-09-07 16:39:41 +0000264 return;
Chris Lattner00950542001-06-06 20:29:01 +0000265 }
266 break;
267 }
268
Chris Lattnerab5ac6b2001-07-08 23:22:50 +0000269 // If we weren't handled before here, we either have a large number of
270 // operands or a large operand index that we are refering to.
Chris Lattner00950542001-06-06 20:29:01 +0000271 outputInstructionFormat0(I, Table, Type, Out);
Chris Lattner00950542001-06-06 20:29:01 +0000272}