Broad superficial changes:
[oota-llvm.git] / lib / Bytecode / Writer / InstructionWriter.cpp
1 //===-- 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"
14 #include "llvm/Method.h"
15 #include "llvm/BasicBlock.h"
16 #include "llvm/Instruction.h"
17 #include "llvm/DerivedTypes.h"
18 #include "llvm/Tools/DataTypes.h"
19 #include <algorithm>
20
21 typedef 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 //
28 static void outputInstructionFormat0(const Instruction *I,
29                                      const SlotCalculator &Table,
30                                      unsigned Type, vector<uchar> &Out) {
31   // Opcode must have top two bits clear...
32   output_vbr(I->getOpcode(), Out);               // Instruction Opcode ID
33   output_vbr(Type, Out);                         // Result type
34
35   unsigned NumArgs = I->getNumOperands();
36   output_vbr(NumArgs, Out);
37
38   for (unsigned i = 0; i < NumArgs; ++i) {
39     const Value *N = I->getOperand(i);
40     int Slot = Table.getValSlot(N);
41     assert(Slot >= 0 && "No slot number for value!?!?");      
42     output_vbr((unsigned)Slot, Out);
43   }
44   align32(Out);    // We must maintain correct alignment!
45 }
46
47
48 // outputInstructionFormat1 - Output one operand instructions, knowing that no
49 // operand index is >= 2^12.
50 //
51 static void outputInstructionFormat1(const Instruction *I, 
52                                      const SlotCalculator &Table, int *Slots,
53                                      unsigned Type, vector<uchar> &Out) {
54   unsigned IType = I->getOpcode();      // Instruction Opcode ID
55   
56   // bits   Instruction format:
57   // --------------------------
58   // 31-30: Opcode type, fixed to 1.
59   // 29-24: Opcode
60   // 23-12: Resulting type plane
61   // 11- 0: Operand #1 (if set to (2^12-1), then zero operands)
62   //
63   unsigned Opcode = (1 << 30) | (IType << 24) | (Type << 12) | Slots[0];
64   //  cerr << "1 " << IType << " " << Type << " " << Slots[0] << endl;
65   output(Opcode, Out);
66 }
67
68
69 // outputInstructionFormat2 - Output two operand instructions, knowing that no
70 // operand index is >= 2^8.
71 //
72 static void outputInstructionFormat2(const Instruction *I, 
73                                      const SlotCalculator &Table, int *Slots,
74                                      unsigned Type, vector<uchar> &Out) {
75   unsigned IType = I->getOpcode();      // Instruction Opcode ID
76
77   // bits   Instruction format:
78   // --------------------------
79   // 31-30: Opcode type, fixed to 2.
80   // 29-24: Opcode
81   // 23-16: Resulting type plane
82   // 15- 8: Operand #1
83   //  7- 0: Operand #2  
84   //
85   unsigned Opcode = (2 << 30) | (IType << 24) | (Type << 16) |
86                     (Slots[0] << 8) | (Slots[1] << 0);
87   //  cerr << "2 " << IType << " " << Type << " " << Slots[0] << " " 
88   //       << Slots[1] << endl;
89   output(Opcode, Out);
90 }
91
92
93 // outputInstructionFormat3 - Output three operand instructions, knowing that no
94 // operand index is >= 2^6.
95 //
96 static void outputInstructionFormat3(const Instruction *I, 
97                                      const SlotCalculator &Table, int *Slots,
98                                      unsigned Type, vector<uchar> &Out) {
99   unsigned IType = I->getOpcode();      // Instruction Opcode ID
100
101   // bits   Instruction format:
102   // --------------------------
103   // 31-30: Opcode type, fixed to 3
104   // 29-24: Opcode
105   // 23-18: Resulting type plane
106   // 17-12: Operand #1
107   // 11- 6: Operand #2
108   //  5- 0: Operand #3
109   //
110   unsigned Opcode = (3 << 30) | (IType << 24) | (Type << 18) |
111                     (Slots[0] << 12) | (Slots[1] << 6) | (Slots[2] << 0);
112   //cerr << "3 " << IType << " " << Type << " " << Slots[0] << " " 
113   //     << Slots[1] << " " << Slots[2] << endl;
114   output(Opcode, Out);
115 }
116
117 bool BytecodeWriter::processInstruction(const Instruction *I) {
118   assert(I->getOpcode() < 64 && "Opcode too big???");
119
120   unsigned NumOperands = I->getNumOperands();
121   int MaxOpSlot = 0;
122   int Slots[3]; Slots[0] = (1 << 12)-1;   // Marker to signify 0 operands
123
124   for (unsigned i = 0; i < NumOperands; ++i) {
125     const Value *Def = I->getOperand(i);
126     int slot = Table.getValSlot(Def);
127     assert(slot != -1 && "Broken bytecode!");
128     if (slot > MaxOpSlot) MaxOpSlot = slot;
129     if (i < 3) Slots[i] = slot;
130   }
131
132   // Figure out which type to encode with the instruction.  Typically we want
133   // the type of the first parameter, as opposed to the type of the instruction
134   // (for example, with setcc, we always know it returns bool, but the type of
135   // the first param is actually interesting).  But if we have no arguments
136   // we take the type of the instruction itself.  
137   //
138   const Type *Ty = NumOperands ? I->getOperand(0)->getType() : I->getType();
139   if (I->getOpcode() == Instruction::Malloc || 
140       I->getOpcode() == Instruction::Alloca)
141     Ty = I->getType();  // Malloc & Alloca ALWAYS want to encode the return type
142
143   unsigned Type;
144   int Slot = Table.getValSlot(Ty);
145   assert(Slot != -1 && "Type not available!!?!");
146   Type = (unsigned)Slot;
147
148
149   // Decide which instruction encoding to use.  This is determined primarily by
150   // the number of operands, and secondarily by whether or not the max operand
151   // will fit into the instruction encoding.  More operands == fewer bits per
152   // operand.
153   //
154   switch (NumOperands) {
155   case 0:
156   case 1:
157     if (MaxOpSlot < (1 << 12)-1) { // -1 because we use 4095 to indicate 0 ops
158       outputInstructionFormat1(I, Table, Slots, Type, Out);
159       return false;
160     }
161     break;
162
163   case 2:
164     if (MaxOpSlot < (1 << 8)) {
165       outputInstructionFormat2(I, Table, Slots, Type, Out);
166       return false;
167     }
168     break;
169
170   case 3:
171     if (MaxOpSlot < (1 << 6)) {
172       outputInstructionFormat3(I, Table, Slots, Type, Out);
173       return false;
174     }
175     break;
176   }
177
178   // If we weren't handled before here, we either have a large number of operands
179   // or a large operand index that we are refering to.
180   outputInstructionFormat0(I, Table, Type, Out);
181   return false;
182 }