From 2b9f6004dfc87aa03774c494257c57695d591822 Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Tue, 23 Oct 2001 03:21:10 +0000 Subject: [PATCH] Fixed a LONG standing, SCARY problem with bytecode encoding. It turns out to be an endian problem that only shows up with type 0 instructions in LARGE programs. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@961 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Bytecode/Reader/InstructionReader.cpp | 48 ++++++++++++++----- lib/Bytecode/Reader/ReaderInternals.h | 2 +- lib/Bytecode/Writer/InstructionWriter.cpp | 56 +++++++++++------------ 3 files changed, 65 insertions(+), 41 deletions(-) diff --git a/lib/Bytecode/Reader/InstructionReader.cpp b/lib/Bytecode/Reader/InstructionReader.cpp index 1f4aa68f4ae..fc4f73c7840 100644 --- a/lib/Bytecode/Reader/InstructionReader.cpp +++ b/lib/Bytecode/Reader/InstructionReader.cpp @@ -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) { diff --git a/lib/Bytecode/Reader/ReaderInternals.h b/lib/Bytecode/Reader/ReaderInternals.h index 1d9903dcdeb..eed4fd0b498 100644 --- a/lib/Bytecode/Reader/ReaderInternals.h +++ b/lib/Bytecode/Reader/ReaderInternals.h @@ -16,7 +16,7 @@ #include // 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" diff --git a/lib/Bytecode/Writer/InstructionWriter.cpp b/lib/Bytecode/Writer/InstructionWriter.cpp index c6a32ed51f0..54459100356 100644 --- a/lib/Bytecode/Writer/InstructionWriter.cpp +++ b/lib/Bytecode/Writer/InstructionWriter.cpp @@ -30,7 +30,7 @@ static void outputInstructionFormat0(const Instruction *I, const SlotCalculator &Table, unsigned Type, deque &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 &Out) { assert(isa(I) || isa(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 &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 &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 &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) {