1311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff// Copyright 2008 Google Inc.
2311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff// Author: Lincoln Smith
3311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff//
4311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff// Licensed under the Apache License, Version 2.0 (the "License");
5311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff// you may not use this file except in compliance with the License.
6311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff// You may obtain a copy of the License at
7311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff//
8311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff//      http://www.apache.org/licenses/LICENSE-2.0
9311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff//
10311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff// Unless required by applicable law or agreed to in writing, software
11311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff// distributed under the License is distributed on an "AS IS" BASIS,
12311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff// See the License for the specific language governing permissions and
14311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff// limitations under the License.
15311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff//
16311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff// codetable.cc:
17311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff//     Classes to implement the Code Table
18311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff//     described in sections 5.5, 5.6 and 7 of
19311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff//     RFC 3284 - The VCDIFF Generic Differencing and Compression Data Format.
20311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff//     The RFC text can be found at http://www.faqs.org/rfcs/rfc3284.html
21311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff
22311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff#include <config.h>
23311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff#include "addrcache.h"
24311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff#include "codetable.h"
25311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff#include "logging.h"
26311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff#include "vcdiff_defs.h"  // VCD_MAX_MODES
27311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff
28311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiffnamespace open_vcdiff {
29311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff
30311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiffconst char* VCDiffInstructionName(VCDiffInstructionType inst) {
31311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff  switch (inst) {
32311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff    case VCD_NOOP:
33311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff      return "NOOP";
34311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff    case VCD_ADD:
35311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff      return "ADD";
36311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff    case VCD_RUN:
37311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff      return "RUN";
38311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff    case VCD_COPY:
39311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff      return "COPY";
40311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff    default:
41732fff248e662ec47aa27c124632f406f27b6c8dopenvcdiff@gmail.com      VCD_ERROR << "Unexpected instruction type " << inst << VCD_ENDL;
42311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff      return "";
43311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff  }
44311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff}
45311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff
46311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff// This is the default code table defined in the RFC, section 5.6.
47311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff// Using a static struct means that the compiler will do the work of
48311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff// laying out the values in memory rather than having to use loops to do so
49311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff// at runtime.  The letters "N", "A", "R", and "C" are defined as VCD_NOOP,
50311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff// VCD_ADD, VCD_RUN, and VCD_COPY respectively (see the definition of
51311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff// struct VCDiffCodeTableData), which allows for a compact
52311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff// representation of the code table data.
53311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff//
54311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiffconst VCDiffCodeTableData VCDiffCodeTableData::kDefaultCodeTableData =
55311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff    // inst1
56311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff    { { R,  // opcode 0
57311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff        A, A, A, A, A, A, A, A, A, A, A, A, A, A, A, A, A, A,  // opcodes 1-18
58311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff        C, C, C, C, C, C, C, C, C, C, C, C, C, C, C, C,  // opcodes 19-34
59311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff        C, C, C, C, C, C, C, C, C, C, C, C, C, C, C, C,  // opcodes 35-50
60311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff        C, C, C, C, C, C, C, C, C, C, C, C, C, C, C, C,  // opcodes 51-66
61311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff        C, C, C, C, C, C, C, C, C, C, C, C, C, C, C, C,  // opcodes 67-82
62311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff        C, C, C, C, C, C, C, C, C, C, C, C, C, C, C, C,  // opcodes 83-98
63311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff        C, C, C, C, C, C, C, C, C, C, C, C, C, C, C, C,  // opcodes 99-114
64311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff        C, C, C, C, C, C, C, C, C, C, C, C, C, C, C, C,  // opcodes 115-130
65311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff        C, C, C, C, C, C, C, C, C, C, C, C, C, C, C, C,  // opcodes 131-146
66311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff        C, C, C, C, C, C, C, C, C, C, C, C, C, C, C, C,  // opcodes 147-162
67311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff        A, A, A, A, A, A, A, A, A, A, A, A,  // opcodes 163-174
68311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff        A, A, A, A, A, A, A, A, A, A, A, A,  // opcodes 175-186
69311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff        A, A, A, A, A, A, A, A, A, A, A, A,  // opcodes 187-198
70311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff        A, A, A, A, A, A, A, A, A, A, A, A,  // opcodes 199-210
71311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff        A, A, A, A, A, A, A, A, A, A, A, A,  // opcodes 211-222
72311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff        A, A, A, A, A, A, A, A, A, A, A, A,  // opcodes 223-234
73311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff        A, A, A, A,  // opcodes 235-238
74311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff        A, A, A, A,  // opcodes 239-242
75311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff        A, A, A, A,  // opcodes 243-246
76311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff        C, C, C, C, C, C, C, C, C },  // opcodes 247-255
77311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff    // inst2
78311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff      { N,  // opcode 0
79311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff        N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N,  // opcodes 1-18
80311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff        N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N,  // opcodes 19-34
81311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff        N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N,  // opcodes 35-50
82311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff        N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N,  // opcodes 51-66
83311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff        N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N,  // opcodes 67-82
84311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff        N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N,  // opcodes 83-98
85311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff        N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N,  // opcodes 99-114
86311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff        N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N,  // opcodes 115-130
87311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff        N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N,  // opcodes 131-146
88311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff        N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N,  // opcodes 147-162
89311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff        C, C, C, C, C, C, C, C, C, C, C, C,  // opcodes 163-174
90311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff        C, C, C, C, C, C, C, C, C, C, C, C,  // opcodes 175-186
91311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff        C, C, C, C, C, C, C, C, C, C, C, C,  // opcodes 187-198
92311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff        C, C, C, C, C, C, C, C, C, C, C, C,  // opcodes 199-210
93311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff        C, C, C, C, C, C, C, C, C, C, C, C,  // opcodes 211-222
94311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff        C, C, C, C, C, C, C, C, C, C, C, C,  // opcodes 223-234
95311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff        C, C, C, C,  // opcodes 235-238
96311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff        C, C, C, C,  // opcodes 239-242
97311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff        C, C, C, C,  // opcodes 243-246
98311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff        A, A, A, A, A, A, A, A, A },  // opcodes 247-255
99311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff    // size1
100311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff      { 0,  // opcode 0
101311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff        0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17,  // 1-18
102311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff        0, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18,  // 19-34
103311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff        0, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18,  // 35-50
104311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff        0, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18,  // 51-66
105311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff        0, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18,  // 67-82
106311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff        0, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18,  // 83-98
107311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff        0, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18,  // 99-114
108311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff        0, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18,  // 115-130
109311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff        0, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18,  // 131-146
110311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff        0, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18,  // 147-162
111311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff        1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4,  // opcodes 163-174
112311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff        1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4,  // opcodes 175-186
113311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff        1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4,  // opcodes 187-198
114311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff        1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4,  // opcodes 199-210
115311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff        1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4,  // opcodes 211-222
116311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff        1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4,  // opcodes 223-234
117311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff        1, 2, 3, 4,  // opcodes 235-238
118311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff        1, 2, 3, 4,  // opcodes 239-242
119311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff        1, 2, 3, 4,  // opcodes 243-246
120311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff        4, 4, 4, 4, 4, 4, 4, 4, 4 },  // opcodes 247-255
121311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff    // size2
122311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff      { 0,  // opcode 0
123311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  // opcodes 1-18
124311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  // opcodes 19-34
125311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  // opcodes 35-50
126311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  // opcodes 51-66
127311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  // opcodes 67-82
128311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  // opcodes 83-98
129311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  // opcodes 99-114
130311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  // opcodes 115-130
131311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  // opcodes 131-146
132311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  // opcodes 147-162
133311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff        4, 5, 6, 4, 5, 6, 4, 5, 6, 4, 5, 6,  // opcodes 163-174
134311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff        4, 5, 6, 4, 5, 6, 4, 5, 6, 4, 5, 6,  // opcodes 175-186
135311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff        4, 5, 6, 4, 5, 6, 4, 5, 6, 4, 5, 6,  // opcodes 187-198
136311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff        4, 5, 6, 4, 5, 6, 4, 5, 6, 4, 5, 6,  // opcodes 199-210
137311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff        4, 5, 6, 4, 5, 6, 4, 5, 6, 4, 5, 6,  // opcodes 211-222
138311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff        4, 5, 6, 4, 5, 6, 4, 5, 6, 4, 5, 6,  // opcodes 223-234
139311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff        4, 4, 4, 4,  // opcodes 235-238
140311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff        4, 4, 4, 4,  // opcodes 239-242
141311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff        4, 4, 4, 4,  // opcodes 243-246
142311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff        1, 1, 1, 1, 1, 1, 1, 1, 1 },  // opcodes 247-255
143311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff    // mode1
144311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff      { 0,  // opcode 0
145311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  // opcodes 1-18
146311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  // opcodes 19-34
147311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // opcodes 35-50
148311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff        2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,  // opcodes 51-66
149311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff        3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,  // opcodes 67-82
150311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff        4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,  // opcodes 83-98
151311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff        5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,  // opcodes 99-114
152311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff        6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,  // opcodes 115-130
153311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff        7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,  // opcodes 131-146
154311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff        8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,  // opcodes 147-162
155311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  // opcodes 163-174
156311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  // opcodes 175-186
157311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  // opcodes 187-198
158311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  // opcodes 199-210
159311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  // opcodes 211-222
160311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  // opcodes 223-234
161311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff        0, 0, 0, 0,  // opcodes 235-238
162311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff        0, 0, 0, 0,  // opcodes 239-242
163311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff        0, 0, 0, 0,  // opcodes 243-246
164311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff        0, 1, 2, 3, 4, 5, 6, 7, 8 },  // opcodes 247-255
165311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff    // mode2
166311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff      { 0,  // opcode 0
167311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  // opcodes 1-18
168311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  // opcodes 19-34
169311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  // opcodes 35-50
170311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  // opcodes 51-66
171311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  // opcodes 67-82
172311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  // opcodes 83-98
173311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  // opcodes 99-114
174311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  // opcodes 115-130
175311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  // opcodes 131-146
176311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  // opcodes 147-162
177311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  // opcodes 163-174
178311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // opcodes 175-186
179311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff        2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,  // opcodes 187-198
180311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff        3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,  // opcodes 199-210
181311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff        4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,  // opcodes 211-222
182311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff        5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,  // opcodes 223-234
183311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff        6, 6, 6, 6,  // opcodes 235-238
184311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff        7, 7, 7, 7,  // opcodes 239-242
185311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff        8, 8, 8, 8,  // opcodes 243-246
186311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff        0, 0, 0, 0, 0, 0, 0, 0, 0 } };  // opcodes 247-255
187311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff
188311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiffbool VCDiffCodeTableData::ValidateOpcode(int opcode,
189311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff                                         unsigned char inst,
190311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff                                         unsigned char size,
191311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff                                         unsigned char mode,
192311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff                                         unsigned char max_mode,
193311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff                                         const char* first_or_second) {
194311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff  bool no_errors_found = true;
195311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff  // Check upper limits of inst and mode.  inst, size, and mode are
196311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff  // unsigned, so there is no lower limit on them.
197311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff  if (inst > VCD_LAST_INSTRUCTION_TYPE) {
198732fff248e662ec47aa27c124632f406f27b6c8dopenvcdiff@gmail.com    VCD_ERROR << "VCDiff: Bad code table; opcode " << opcode << " has invalid "
199732fff248e662ec47aa27c124632f406f27b6c8dopenvcdiff@gmail.com              << first_or_second << " instruction type "
200732fff248e662ec47aa27c124632f406f27b6c8dopenvcdiff@gmail.com              << static_cast<int>(inst) << VCD_ENDL;
201311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff    no_errors_found = false;
202311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff  }
203311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff  if (mode > max_mode) {
204732fff248e662ec47aa27c124632f406f27b6c8dopenvcdiff@gmail.com    VCD_ERROR << "VCDiff: Bad code table; opcode " << opcode << " has invalid "
205732fff248e662ec47aa27c124632f406f27b6c8dopenvcdiff@gmail.com              << first_or_second << " mode "
206732fff248e662ec47aa27c124632f406f27b6c8dopenvcdiff@gmail.com              << static_cast<int>(mode) << VCD_ENDL;
207311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff    no_errors_found = false;
208311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff  }
209311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff  // A NOOP instruction must have size 0
210311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff  // (and mode 0, which is included in the next rule)
211311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff  if ((inst == VCD_NOOP) && (size != 0)) {
212732fff248e662ec47aa27c124632f406f27b6c8dopenvcdiff@gmail.com    VCD_ERROR << "VCDiff: Bad code table; opcode " << opcode << " has "
213732fff248e662ec47aa27c124632f406f27b6c8dopenvcdiff@gmail.com              << first_or_second << " instruction NOOP with nonzero size "
214732fff248e662ec47aa27c124632f406f27b6c8dopenvcdiff@gmail.com              << static_cast<int>(size) << VCD_ENDL;
215311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff    no_errors_found = false;
216311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff  }
217311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff  // A nonzero mode can only be used with a COPY instruction
218311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff  if ((inst != VCD_COPY) && (mode != 0)) {
219732fff248e662ec47aa27c124632f406f27b6c8dopenvcdiff@gmail.com    VCD_ERROR << "VCDiff: Bad code table; opcode " << opcode
220732fff248e662ec47aa27c124632f406f27b6c8dopenvcdiff@gmail.com              << " has non-COPY "
221732fff248e662ec47aa27c124632f406f27b6c8dopenvcdiff@gmail.com              << first_or_second << " instruction with nonzero mode "
222732fff248e662ec47aa27c124632f406f27b6c8dopenvcdiff@gmail.com              << static_cast<int>(mode) << VCD_ENDL;
223311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff    no_errors_found = false;
224311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff  }
225311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff  return no_errors_found;
226311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff}
227311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff
228311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff// If an error is found while validating, continue to validate the rest
229311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff// of the code table so that all validation errors will appear in
230311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff// the error log.  Otherwise the user would have to fix a single error
231311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff// and then rerun validation to find the next error.
232311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff//
233311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiffbool VCDiffCodeTableData::Validate(unsigned char max_mode) const {
234311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff  const int kNumberOfTypesAndModes = VCD_LAST_INSTRUCTION_TYPE + max_mode + 1;
235311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff  bool hasOpcodeForTypeAndMode[VCD_LAST_INSTRUCTION_TYPE + VCD_MAX_MODES];
236311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff  bool no_errors_found = true;
237311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff  for (int i = 0; i < kNumberOfTypesAndModes; ++i) {
238311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff    hasOpcodeForTypeAndMode[i] = false;
239311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff  }
240311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff  for (int i = 0; i < kCodeTableSize; ++i) {
241311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff    no_errors_found =
242311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff        ValidateOpcode(i, inst1[i], size1[i], mode1[i], max_mode, "first")
243311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff        && no_errors_found;  // use as 2nd operand to avoid short-circuit
244311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff    no_errors_found =
245311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff        ValidateOpcode(i, inst2[i], size2[i], mode2[i], max_mode, "second")
246311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff        && no_errors_found;
247311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff    // A valid code table must have an opcode to encode every possible
248311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff    // combination of inst and mode with size=0 as its first instruction,
249311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff    // and NOOP as its second instruction.  If this condition fails,
250311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff    // then there exists a set of input instructions that cannot be encoded.
251311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff    if ((size1[i] == 0) &&
252311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff        (inst2[i] == VCD_NOOP) &&
253311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff        ((static_cast<int>(inst1[i]) + static_cast<int>(mode1[i]))
254311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff            < kNumberOfTypesAndModes)) {
255311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff      hasOpcodeForTypeAndMode[inst1[i] + mode1[i]] = true;
256311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff    }
257311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff  }
258311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff  for (int i = 0; i < kNumberOfTypesAndModes; ++i) {
259311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff    if (i == VCD_NOOP) continue;
260311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff    if (!hasOpcodeForTypeAndMode[i])  {
261311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff      if (i >= VCD_COPY) {
262732fff248e662ec47aa27c124632f406f27b6c8dopenvcdiff@gmail.com        VCD_ERROR << "VCDiff: Bad code table; there is no opcode for inst "
263732fff248e662ec47aa27c124632f406f27b6c8dopenvcdiff@gmail.com                     "COPY, size 0, mode " << (i - VCD_COPY) << VCD_ENDL;
264311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff      } else {
265732fff248e662ec47aa27c124632f406f27b6c8dopenvcdiff@gmail.com        VCD_ERROR << "VCDiff: Bad code table; there is no opcode for inst "
266311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff            << VCDiffInstructionName(static_cast<VCDiffInstructionType>(i))
267732fff248e662ec47aa27c124632f406f27b6c8dopenvcdiff@gmail.com            << ", size 0,  mode 0" << VCD_ENDL;
268311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff      }
269311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff      no_errors_found = false;
270311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff    }
271311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff  }
272311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff  return no_errors_found;
273311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff}
274311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff
275311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiffbool VCDiffCodeTableData::Validate() const {
276311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff  return Validate(VCDiffAddressCache::DefaultLastMode());
277311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff}
278311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff
279311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff}  // namespace open_vcdiff
280