1 //===-- WriteInst.cpp - Functions for writing instructions -------*- C++ -*--=//
3 // This file implements the routines for encoding instruction opcodes to a
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
10 //===----------------------------------------------------------------------===//
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"
21 typedef unsigned char uchar;
23 // outputInstructionFormat0 - Output those wierd instructions that have a large
24 // number of operands or have large operands themselves...
26 // Format: [opcode] [type] [numargs] [arg0] [arg1] ... [arg<numargs-1>]
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->getInstType(), Out); // Instruction Opcode ID
33 output_vbr(Type, Out); // Result type
35 unsigned NumArgs = I->getNumOperands();
36 output_vbr(NumArgs, Out);
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);
44 align32(Out); // We must maintain correct alignment!
48 // outputInstructionFormat1 - Output one operand instructions, knowing that no
49 // operand index is >= 2^12.
51 static void outputInstructionFormat1(const Instruction *I,
52 const SlotCalculator &Table, int *Slots,
53 unsigned Type, vector<uchar> &Out) {
54 unsigned IType = I->getInstType(); // Instruction Opcode ID
56 // bits Instruction format:
57 // --------------------------
58 // 31-30: Opcode type, fixed to 1.
60 // 23-12: Resulting type plane
61 // 11- 0: Operand #1 (if set to (2^12-1), then zero operands)
63 unsigned Opcode = (1 << 30) | (IType << 24) | (Type << 12) | Slots[0];
64 // cerr << "1 " << IType << " " << Type << " " << Slots[0] << endl;
69 // outputInstructionFormat2 - Output two operand instructions, knowing that no
70 // operand index is >= 2^8.
72 static void outputInstructionFormat2(const Instruction *I,
73 const SlotCalculator &Table, int *Slots,
74 unsigned Type, vector<uchar> &Out) {
75 unsigned IType = I->getInstType(); // Instruction Opcode ID
77 // bits Instruction format:
78 // --------------------------
79 // 31-30: Opcode type, fixed to 2.
81 // 23-16: Resulting type plane
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;
93 // outputInstructionFormat3 - Output three operand instructions, knowing that no
94 // operand index is >= 2^6.
96 static void outputInstructionFormat3(const Instruction *I,
97 const SlotCalculator &Table, int *Slots,
98 unsigned Type, vector<uchar> &Out) {
99 unsigned IType = I->getInstType(); // Instruction Opcode ID
101 // bits Instruction format:
102 // --------------------------
103 // 31-30: Opcode type, fixed to 3
105 // 23-18: Resulting type plane
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;
117 bool BytecodeWriter::processInstruction(const Instruction *I) {
118 assert(I->getInstType() < 64 && "Opcode too big???");
120 unsigned NumOperands = I->getNumOperands();
122 int Slots[3]; Slots[0] = (1 << 12)-1; // Marker to signify 0 operands
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;
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.
138 const Type *Ty = NumOperands ? I->getOperand(0)->getType() : I->getType();
139 if (I->getInstType() == Instruction::Malloc ||
140 I->getInstType() == Instruction::Alloca)
141 Ty = I->getType(); // Malloc & Alloca ALWAYS want to encode the return type
144 int Slot = Table.getValSlot(Ty);
145 assert(Slot != -1 && "Type not available!!?!");
146 Type = (unsigned)Slot;
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
154 switch (NumOperands) {
157 if (MaxOpSlot < (1 << 12)-1) { // -1 because we use 4095 to indicate 0 ops
158 outputInstructionFormat1(I, Table, Slots, Type, Out);
164 if (MaxOpSlot < (1 << 8)) {
165 outputInstructionFormat2(I, Table, Slots, Type, Out);
171 if (MaxOpSlot < (1 << 6)) {
172 outputInstructionFormat3(I, Table, Slots, Type, Out);
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);