diff options
| author | Chris Lattner <sabre@nondot.org> | 2001-10-23 03:21:10 +0000 | 
|---|---|---|
| committer | Chris Lattner <sabre@nondot.org> | 2001-10-23 03:21:10 +0000 | 
| commit | 2b9f6004dfc87aa03774c494257c57695d591822 (patch) | |
| tree | 0d1ede1f944bb34b3afa328d6b796a6606d2a2ba /lib/Bytecode/Reader/InstructionReader.cpp | |
| parent | e638c10cb0fd3e5e50e0eec226367eba861eba0f (diff) | |
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
Diffstat (limited to 'lib/Bytecode/Reader/InstructionReader.cpp')
| -rw-r--r-- | lib/Bytecode/Reader/InstructionReader.cpp | 48 | 
1 files changed, 36 insertions, 12 deletions
diff --git a/lib/Bytecode/Reader/InstructionReader.cpp b/lib/Bytecode/Reader/InstructionReader.cpp index 1f4aa68f4a..fc4f73c784 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) {  | 
