4 /* Part of __HIB section */
6 /***************************************************************************
7 * THE UNPACKING ROUTINES should GO HERE
10 const char hashLookupTable
[] = HASH_LOOKUP_TABLE_CONTENTS
;
13 #define GET_NEXT_TAG tags[tagsIndex++]
14 #define GET_NEXT_FULL_PATTERN fullPatterns[fullPatternsIndex++]
15 #define GET_NEXT_LOW_BITS lowBits[lowBitsIndex++]
16 #define GET_NEXT_DICTIONARY_INDEX dictionaryIndices[dictionaryIndicesIndex++]
19 /* WK_unpack_2bits takes any number of words containing 16 two-bit values
20 * and unpacks them into four times as many words containg those
21 * two bit values as bytes (with the low two bits of each byte holding
25 WK_unpack_2bits(WK_word
*input_buf
,
27 WK_word
*output_buf
) {
29 register WK_word
*input_next
= input_buf
;
30 register WK_word
*output_next
= output_buf
;
31 register WK_word packing_mask
= TWO_BITS_PACKING_MASK
;
33 /* loop to repeatedly grab one input word and unpack it into
34 * 4 output words. This loop could be unrolled a little---it's
35 * designed to be easy to do that.
37 while (input_next
< input_end
) {
38 register WK_word temp
= input_next
[0];
39 DEBUG_PRINT_2("Unpacked tags word: %.8x\n", temp
);
40 output_next
[0] = temp
& packing_mask
;
41 output_next
[1] = (temp
>> 2) & packing_mask
;
42 output_next
[2] = (temp
>> 4) & packing_mask
;
43 output_next
[3] = (temp
>> 6) & packing_mask
;
53 /* unpack four bits consumes any number of words (between input_buf
54 * and input_end) holding 8 4-bit values per word, and unpacks them
55 * into twice as many words, with each value in a separate byte.
56 * (The four-bit values occupy the low halves of the bytes in the
60 WK_unpack_4bits(WK_word
*input_buf
,
62 WK_word
*output_buf
) {
64 register WK_word
*input_next
= input_buf
;
65 register WK_word
*output_next
= output_buf
;
66 register WK_word packing_mask
= FOUR_BITS_PACKING_MASK
;
69 /* loop to repeatedly grab one input word and unpack it into
70 * 4 output words. This loop should probably be unrolled
71 * a little---it's designed to be easy to do that.
73 while (input_next
< input_end
) {
74 register WK_word temp
= input_next
[0];
75 DEBUG_PRINT_2("Unpacked dictionary indices word: %.8x\n", temp
);
76 output_next
[0] = temp
& packing_mask
;
77 output_next
[1] = (temp
>> 4) & packing_mask
;
87 /* unpack_3_tenbits unpacks three 10-bit items from (the low 30 bits of)
91 WK_unpack_3_tenbits(WK_word
*input_buf
,
93 WK_word
*output_buf
) {
95 register WK_word
*input_next
= input_buf
;
96 register WK_word
*output_next
= output_buf
;
97 register WK_word packing_mask
= LOW_BITS_MASK
;
99 /* loop to fetch words of input, splitting each into three
100 * words of output with 10 meaningful low bits. This loop
101 * probably ought to be unrolled and maybe coiled
103 while (input_next
< input_end
) {
104 register WK_word temp
= input_next
[0];
106 output_next
[0] = temp
& packing_mask
;
107 output_next
[1] = (temp
>> 10) & packing_mask
;
108 output_next
[2] = temp
>> 20;
118 /*********************************************************************
119 * WKdm_decompress --- THE DECOMPRESSOR
120 * Expects WORD pointers to the source and destination buffers
121 * and a page size in words. The page size had better be 1024 unless
122 * somebody finds the places that are dependent on the page size and
127 WKdm_decompress (WK_word
* src_buf
,
129 __unused
unsigned int words
)
132 DictionaryElement dictionary
[DICTIONARY_SIZE
];
134 /* arrays that hold output data in intermediate form during modeling */
135 /* and whose contents are packed into the actual output after modeling */
137 /* sizes of these arrays should be increased if you want to compress
138 * pages larger than 4KB
140 WK_word tempTagsArray
[300]; /* tags for everything */
141 WK_word tempQPosArray
[300]; /* queue positions for matches */
142 WK_word tempLowBitsArray
[1200]; /* low bits for partial matches */
147 printf("\nIn DECOMPRESSOR\n");
148 printf("tempTagsArray is at %u\n", (unsigned long int) tempTagsArray
);
149 printf("tempQPosArray is at %u\n", (unsigned long int) tempQPosArray
);
150 printf("tempLowBitsArray is at %u\n", (unsigned long int) tempLowBitsArray
);
152 printf(" first four words of source buffer are:\n");
153 printf(" %u\n %u\n %u\n %u\n",
154 src_buf
[0], src_buf
[1], src_buf
[2], src_buf
[3]);
157 WK_word
*arr
=(src_buf
+ TAGS_AREA_OFFSET
+ (PAGE_SIZE_IN_WORDS
/ 16));
159 printf(" first 20 full patterns are: \n");
160 for (i
= 0; i
< 20; i
++) {
161 printf(" %d", arr
[i
]);
167 WK_unpack_2bits(TAGS_AREA_START(src_buf
),
168 TAGS_AREA_END(src_buf
),
173 char* arr
= (char *) tempTagsArray
;
175 printf(" first 200 tags are: \n");
176 for (i
= 0; i
< 200; i
++) {
177 printf(" %d", arr
[i
]);
183 WK_unpack_4bits(QPOS_AREA_START(src_buf
),
184 QPOS_AREA_END(src_buf
),
189 char* arr
= (char *) tempQPosArray
;
191 printf(" first 200 queue positions are: \n");
192 for (i
= 0; i
< 200; i
++) {
193 printf(" %d", arr
[i
]);
199 WK_unpack_3_tenbits(LOW_BITS_AREA_START(src_buf
),
200 LOW_BITS_AREA_END(src_buf
),
204 printf("AFTER UNPACKING, about to enter main block \n");
208 register char *next_tag
= (char *) tempTagsArray
;
209 char *tags_area_end
=
210 ((char *) tempTagsArray
) + PAGE_SIZE_IN_WORDS
;
211 char *next_q_pos
= (char *) tempQPosArray
;
212 WK_word
*next_low_bits
= tempLowBitsArray
;
213 WK_word
*next_full_word
= FULL_WORD_AREA_START(src_buf
);
215 WK_word
*next_output
= dest_buf
;
218 printf("next_output is %u\n", next_output
);
220 printf("next_tag is %u \n", next_tag
);
221 printf("tags_area_end is %u\n", tags_area_end
);
222 printf("next_q_pos is %u\n", next_q_pos
);
223 printf("next_low_bits is %u\n", next_low_bits
);
224 printf("next_full_word is %u\n", next_full_word
);
227 /* this loop should probably be unrolled. Maybe we should unpack
228 * as 4 bit values, giving two consecutive tags, and switch on
229 * that 16 ways to decompress 2 words at a whack
231 while (next_tag
< tags_area_end
) {
233 char tag
= next_tag
[0];
242 WK_word
*dict_location
= dictionary
+ *(next_q_pos
++);
243 /* no need to replace dict. entry if matched exactly */
244 *next_output
= *dict_location
;
248 WK_word
*dict_location
= dictionary
+ *(next_q_pos
++);
250 WK_word temp
= *dict_location
;
252 /* strip out low bits */
253 temp
= ((temp
>> NUM_LOW_BITS
) << NUM_LOW_BITS
);
255 /* add in stored low bits from temp array */
256 temp
= temp
| *(next_low_bits
++);
258 *dict_location
= temp
; /* replace old value in dict. */
259 *next_output
= temp
; /* and echo it to output */
264 WK_word missed_word
= *(next_full_word
++);
265 WK_word
*dict_location
=
267 (((char *) dictionary
) + HASH_TO_DICT_BYTE_OFFSET(missed_word
));
268 *dict_location
= missed_word
;
269 *next_output
= missed_word
;
278 printf("AFTER DECOMPRESSING\n");
279 printf("next_output is %u\n", (unsigned long int) next_output
);
280 printf("next_tag is %u\n", (unsigned long int) next_tag
);
281 printf("next_full_word is %u\n", (unsigned long int) next_full_word
);
282 printf("next_q_pos is %u\n", (unsigned long int) next_q_pos
);