Fixed a LONG standing, SCARY problem with bytecode encoding. It turns out to be...
authorChris Lattner <sabre@nondot.org>
Tue, 23 Oct 2001 03:21:10 +0000 (03:21 +0000)
committerChris Lattner <sabre@nondot.org>
Tue, 23 Oct 2001 03:21:10 +0000 (03:21 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@961 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Bytecode/Reader/InstructionReader.cpp
lib/Bytecode/Reader/ReaderInternals.h
lib/Bytecode/Writer/InstructionWriter.cpp

index 1f4aa68f4aebaeface3c719138be676a6ca25137..fc4f73c7840a0f87de9f311d9f757e998716997a 100644 (file)
@@ -22,30 +22,53 @@ bool BytecodeParser::ParseRawInst(const uchar *&Buf, const uchar *EndBuf,
   unsigned Op, Typ;
   if (read(Buf, EndBuf, Op)) return failure(true);
 
-  Result.NumOperands =  Op >> 30;
-  Result.Opcode      = (Op >> 24) & 63;
+  // bits   Instruction format:        Common to all formats
+  // --------------------------
+  // 01-00: Opcode type, fixed to 1.
+  // 07-02: Opcode
+  Result.NumOperands = (Op >> 0) & 03;
+  Result.Opcode      = (Op >> 2) & 63;
 
   switch (Result.NumOperands) {
   case 1:
-    Result.Ty   = getType((Op >> 12) & 4095);
-    Result.Arg1 = Op & 4095;
+    // 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;
     break;
   case 2:
-    Result.Ty   = getType((Op >> 16) & 255);
-    Result.Arg1 = (Op >> 8 ) & 255;
-    Result.Arg2 = (Op >> 0 ) & 255;
+    // bits   Instruction format:
+    // --------------------------
+    // 15-08: Resulting type plane
+    // 23-16: Operand #1
+    // 31-24: Operand #2  
+    //
+    Result.Ty   = getType((Op >> 8) & 255);
+    Result.Arg1 = (Op >> 16) & 255;
+    Result.Arg2 = (Op >> 24) & 255;
     break;
   case 3:
-    Result.Ty   = getType((Op >> 18) & 63);
-    Result.Arg1 = (Op >> 12) & 63;
-    Result.Arg2 = (Op >> 6 ) & 63;
-    Result.Arg3 = (Op >> 0 ) & 63;
+    // bits   Instruction format:
+    // --------------------------
+    // 13-08: Resulting type plane
+    // 19-14: Operand #1
+    // 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;
     break;
   case 0:
     Buf -= 4;  // Hrm, try this again...
     if (read_vbr(Buf, EndBuf, Result.Opcode)) return failure(true);
+    Result.Opcode >>= 2;
     if (read_vbr(Buf, EndBuf, Typ)) return failure(true);
     Result.Ty = getType(Typ);
     if (Result.Ty == 0) return failure(true);
@@ -93,7 +116,8 @@ bool BytecodeParser::ParseRawInst(const uchar *&Buf, const uchar *EndBuf,
 bool BytecodeParser::ParseInstruction(const uchar *&Buf, const uchar *EndBuf,
                                      Instruction *&Res) {
   RawInst Raw;
-  if (ParseRawInst(Buf, EndBuf, Raw)) return failure(true);
+  if (ParseRawInst(Buf, EndBuf, Raw))
+    return failure(true);
 
   if (Raw.Opcode >= Instruction::FirstUnaryOp && 
       Raw.Opcode <  Instruction::NumUnaryOps  && Raw.NumOperands == 1) {
index 1d9903dcdeb686bd95e3f18be3dea64919cf542d..eed4fd0b498f20bb619c94407b08581b1ef27918 100644 (file)
@@ -16,7 +16,7 @@
 #include <list>
 
 // Enable to trace to figure out what the heck is going on when parsing fails
-#define TRACE_LEVEL 0
+#define TRACE_LEVEL 10
 
 #if TRACE_LEVEL    // ByteCodeReading_TRACEer
 #include "llvm/Assembly/Writer.h"
index c6a32ed51f032f0bb2a46d0516d7a5a05ec1ef05..54459100356c97e64a735ec8e72065bb1e9abac1 100644 (file)
@@ -30,7 +30,7 @@ static void outputInstructionFormat0(const Instruction *I,
                                     const SlotCalculator &Table,
                                     unsigned Type, deque<uchar> &Out) {
   // Opcode must have top two bits clear...
-  output_vbr(I->getOpcode(), Out);               // Instruction Opcode ID
+  output_vbr(I->getOpcode() << 2, Out);          // Instruction Opcode ID
   output_vbr(Type, Out);                         // Result type
 
   unsigned NumArgs = I->getNumOperands();
@@ -66,7 +66,7 @@ static void outputInstrVarArgsCall(const Instruction *I,
                                   deque<uchar> &Out) {
   assert(isa<CallInst>(I) || isa<InvokeInst>(I));
   // Opcode must have top two bits clear...
-  output_vbr(I->getOpcode(), Out);               // Instruction Opcode ID
+  output_vbr(I->getOpcode() << 2, Out);          // Instruction Opcode ID
   output_vbr(Type, Out);                         // Result type (varargs type)
 
   unsigned NumArgs = I->getNumOperands();
@@ -107,18 +107,18 @@ static void outputInstrVarArgsCall(const Instruction *I,
 static void outputInstructionFormat1(const Instruction *I, 
                                     const SlotCalculator &Table, int *Slots,
                                     unsigned Type, deque<uchar> &Out) {
-  unsigned IType = I->getOpcode();      // Instruction Opcode ID
+  unsigned Opcode = I->getOpcode();      // Instruction Opcode ID
   
   // bits   Instruction format:
   // --------------------------
-  // 31-30: Opcode type, fixed to 1.
-  // 29-24: Opcode
-  // 23-12: Resulting type plane
-  // 11- 0: Operand #1 (if set to (2^12-1), then zero operands)
+  // 01-00: Opcode type, fixed to 1.
+  // 07-02: Opcode
+  // 19-08: Resulting type plane
+  // 31-20: Operand #1 (if set to (2^12-1), then zero operands)
   //
-  unsigned Opcode = (1 << 30) | (IType << 24) | (Type << 12) | Slots[0];
+  unsigned Bits = 1 | (Opcode << 2) | (Type << 8) | (Slots[0] << 20);
   //  cerr << "1 " << IType << " " << Type << " " << Slots[0] << endl;
-  output(Opcode, Out);
+  output(Bits, Out);
 }
 
 
@@ -128,21 +128,21 @@ static void outputInstructionFormat1(const Instruction *I,
 static void outputInstructionFormat2(const Instruction *I, 
                                     const SlotCalculator &Table, int *Slots,
                                     unsigned Type, deque<uchar> &Out) {
-  unsigned IType = I->getOpcode();      // Instruction Opcode ID
+  unsigned Opcode = I->getOpcode();      // Instruction Opcode ID
 
   // bits   Instruction format:
   // --------------------------
-  // 31-30: Opcode type, fixed to 2.
-  // 29-24: Opcode
-  // 23-16: Resulting type plane
-  // 15- 8: Operand #1
-  //  7- 0: Operand #2  
+  // 01-00: Opcode type, fixed to 2.
+  // 07-02: Opcode
+  // 15-08: Resulting type plane
+  // 23-16: Operand #1
+  // 31-24: Operand #2  
   //
-  unsigned Opcode = (2 << 30) | (IType << 24) | (Type << 16) |
-                    (Slots[0] << 8) | (Slots[1] << 0);
+  unsigned Bits = 2 | (Opcode << 2) | (Type << 8) |
+                    (Slots[0] << 16) | (Slots[1] << 24);
   //  cerr << "2 " << IType << " " << Type << " " << Slots[0] << " " 
   //       << Slots[1] << endl;
-  output(Opcode, Out);
+  output(Bits, Out);
 }
 
 
@@ -152,22 +152,22 @@ static void outputInstructionFormat2(const Instruction *I,
 static void outputInstructionFormat3(const Instruction *I, 
                                     const SlotCalculator &Table, int *Slots,
                                     unsigned Type, deque<uchar> &Out) {
-  unsigned IType = I->getOpcode();      // Instruction Opcode ID
+  unsigned Opcode = I->getOpcode();      // Instruction Opcode ID
 
   // bits   Instruction format:
   // --------------------------
-  // 31-30: Opcode type, fixed to 3
-  // 29-24: Opcode
-  // 23-18: Resulting type plane
-  // 17-12: Operand #1
-  // 11- 6: Operand #2
-  //  5- 0: Operand #3
+  // 01-00: Opcode type, fixed to 3.
+  // 07-02: Opcode
+  // 13-08: Resulting type plane
+  // 19-14: Operand #1
+  // 25-20: Operand #2
+  // 31-26: Operand #3
   //
-  unsigned Opcode = (3 << 30) | (IType << 24) | (Type << 18) |
-                    (Slots[0] << 12) | (Slots[1] << 6) | (Slots[2] << 0);
+  unsigned Bits = 3 | (Opcode << 2) | (Type << 8) |
+          (Slots[0] << 14) | (Slots[1] << 20) | (Slots[2] << 26);
   //cerr << "3 " << IType << " " << Type << " " << Slots[0] << " " 
   //     << Slots[1] << " " << Slots[2] << endl;
-  output(Opcode, Out);
+  output(Bits, Out);
 }
 
 void BytecodeWriter::processInstruction(const Instruction *I) {