1 /* CMPSC.C (c) Bernard van der Helm, 2000-2015 */
2 /* S/390 compression call instruction */
3
4 /*----------------------------------------------------------------------------*/
5 /* Implementation of the S/390 compression call instruction described in */
6 /* SA22-7208-01: Data Compression within the Hercules S/390 emulator. */
7 /* This implementation couldn't be done without the test programs from */
8 /* Mario Bezzi. Thanks Mario! Also special thanks to Greg Smith who */
9 /* introduced iregs, needed when a page fault occurs. */
10 /* */
11 /* Please pay attention to the Q Public License Version 1. This is open */
12 /* source, but you are not allowed to "reuse" parts for your own purpose */
13 /* without the author's written permission! */
14 /* */
15 /* Implemented "unique" features: */
16 /* 8 index symbol block fetching and storing, preventing cbn calculations. */
17 /* Expand symbol translation caching. */
18 /* Compression dead end determination and elimination. */
19 /* Proactive dead end determination and elimination. */
20 /* */
21 /* (c) Copyright Bernard van der Helm, 2000-2015 */
22 /* Noordwijkerhout, The Netherlands. */
23 /* */
24 /*----------------------------------------------------------------------------*/
25
26 #include "hstdinc.h"
27
28 #ifndef _HENGINE_DLL_
29 #define _HENGINE_DLL_
30 #endif /* #ifndef _HENGINE_DLL_ */
31
32 #ifndef _CMPSC_C_
33 #define _CMPSC_C_
34 #endif /* #ifndef _CMPSC_C_ */
35
36 #include "hercules.h"
37 #include "opcode.h"
38 #include "inline.h"
39
40 #ifdef FEATURE_COMPRESSION
41 /*============================================================================*/
42 /* Common */
43 /*============================================================================*/
44
45 /*----------------------------------------------------------------------------*/
46 /* Debugging options: */
47 /*----------------------------------------------------------------------------*/
48 #if 0
49 #define OPTION_CMPSC_DEBUG
50 #define TRUEFALSE(boolean) ((boolean) ? "True" : "False")
51 #endif /* #if 0|1 */
52
53 /*----------------------------------------------------------------------------*/
54 /* After a successful compression of characters to an index symbol or a */
55 /* successful translation of an index symbol to characters, the registers */
56 /* must be updated. */
57 /*----------------------------------------------------------------------------*/
58 #define ADJUSTREGS(r, regs, iregs, len) \
59 { \
60 SET_GR_A((r), (iregs), (GR_A((r), (iregs)) + (len)) & ADDRESS_MAXWRAP((regs))); \
61 SET_GR_A((r) + 1, (iregs), GR_A((r) + 1, (iregs)) - (len)); \
62 }
63
64 /*----------------------------------------------------------------------------*/
65 /* Commit intermediate registers */
66 /*----------------------------------------------------------------------------*/
67 #ifdef OPTION_CMPSC_DEBUG
68 #define COMMITREGS(regs, iregs, r1, r2) \
69 __COMMITREGS((regs), (iregs), (r1), (r2)) \
70 logmsg("*** Regs committed\n");
71 #else
72 #define COMMITREGS(regs, iregs, r1, r2) \
73 __COMMITREGS((regs), (iregs), (r1), (r2))
74 #endif /* ifdef OPTION_CMPSC_DEBUG */
75 #define __COMMITREGS(regs, iregs, r1, r2) \
76 { \
77 SET_GR_A(1, (regs), GR_A(1, (iregs))); \
78 SET_GR_A((r1), (regs), GR_A((r1), (iregs))); \
79 SET_GR_A((r1) + 1, (regs), GR_A((r1) + 1, (iregs))); \
80 SET_GR_A((r2), (regs), GR_A((r2), (iregs))); \
81 SET_GR_A((r2) + 1, (regs), GR_A((r2) + 1, (iregs))); \
82 }
83
84 /*----------------------------------------------------------------------------*/
85 /* Commit intermediate registers, except for GR1 */
86 /*----------------------------------------------------------------------------*/
87 #ifdef OPTION_CMPSC_DEBUG
88 #define COMMITREGS2(regs, iregs, r1, r2) \
89 __COMMITREGS2((regs), (iregs), (r1), (r2)) \
90 logmsg("*** Regs committed\n");
91 #else
92 #define COMMITREGS2(regs, iregs, r1, r2) \
93 __COMMITREGS2((regs), (iregs), (r1), (r2))
94 #endif /* #ifdef OPTION_CMPSC_DEBUG */
95 #define __COMMITREGS2(regs, iregs, r1, r2) \
96 { \
97 SET_GR_A((r1), (regs), GR_A((r1), (iregs))); \
98 SET_GR_A((r1) + 1, (regs), GR_A((r1) + 1, (iregs))); \
99 SET_GR_A((r2), (regs), GR_A((r2), (iregs))); \
100 SET_GR_A((r2) + 1, (regs), GR_A((r2) + 1, (iregs))); \
101 }
102
103 /*----------------------------------------------------------------------------*/
104 /* Initialize intermediate registers */
105 /*----------------------------------------------------------------------------*/
106 #define INITREGS(iregs, regs, r1, r2) \
107 { \
108 (iregs)->gr[1] = (regs)->gr[1]; \
109 (iregs)->gr[(r1)] = (regs)->gr[(r1)]; \
110 (iregs)->gr[(r1) + 1] = (regs)->gr[(r1) + 1]; \
111 (iregs)->gr[(r2)] = (regs)->gr[(r2)]; \
112 (iregs)->gr[(r2) + 1] = (regs)->gr[(r2) + 1]; \
113 }
114
115 #if __GEN_ARCH == 900
116 #undef INITREGS
117 #define INITREGS(iregs, regs, r1, r2) \
118 { \
119 (iregs)->gr[1] = (regs)->gr[1]; \
120 (iregs)->gr[(r1)] = (regs)->gr[(r1)]; \
121 (iregs)->gr[(r1) + 1] = (regs)->gr[(r1) + 1]; \
122 (iregs)->gr[(r2)] = (regs)->gr[(r2)]; \
123 (iregs)->gr[(r2) + 1] = (regs)->gr[(r2) + 1]; \
124 (iregs)->psw.amode64 = (regs)->psw.amode64; \
125 }
126 #endif /* #if __GEN_ARCH == 900 */
127
128 /*----------------------------------------------------------------------------*/
129 /* General Purpose Register 0 macro's (GR0) */
130 /*----------------------------------------------------------------------------*/
131 /* cdss : compressed-data symbol size */
132 /* e : expansion operation */
133 /* f1 : format-1 sibling descriptors */
134 /* st : symbol-translation option */
135 /* zp : zero padding */
136 /* */
137 /* We recognize the zp flag and do conform POP nothing! We do something */
138 /* better: Eight index symbol processing. It saves a lot of time in cbn */
139 /* processing, index symbol fetching and storing. Please contact me if a */
140 /* 100% equal functionality is needed. I doubt it! */
141 /*----------------------------------------------------------------------------*/
142 #define GR0_cdss(regs) (((regs)->GR_L(0) & 0x0000F000) >> 12)
143 #define GR0_e(regs) ((regs)->GR_L(0) & 0x00000100)
144 #define GR0_f1(regs) ((regs)->GR_L(0) & 0x00000200)
145 #define GR0_st(regs) ((regs)->GR_L(0) & 0x00010000)
146 #define GR0_zp(regs) ((regs)->GR_L(0) & 0x00020000)
147
148 /*----------------------------------------------------------------------------*/
149 /* General Purpose Register 0 macro's (GR0) derived */
150 /*----------------------------------------------------------------------------*/
151 /* dcten : # dictionary entries */
152 /* dctsz : dictionary size */
153 /* smbsz : symbol size */
154 /*----------------------------------------------------------------------------*/
155 #define GR0_dcten(regs) (0x100 << GR0_cdss((regs)))
156 #define GR0_dctsz(regs) (0x800 << GR0_cdss((regs)))
157 #define GR0_smbsz(regs) (GR0_cdss((regs)) + 8)
158
159 /*----------------------------------------------------------------------------*/
160 /* General Purpose Register 1 macro's (GR1) */
161 /*----------------------------------------------------------------------------*/
162 /* cbn : compressed-data bit number */
163 /* dictor: compression dictionary or expansion dictionary */
164 /* sttoff: symbol-translation-table offset */
165 /*----------------------------------------------------------------------------*/
166 #define GR1_cbn(regs) (((regs)->GR_L(1) & 0x00000007))
167 #define GR1_dictor(regs) (GR_A(1, (regs)) & ((GREG) 0xFFFFFFFFFFFFF000ULL))
168 #define GR1_sttoff(regs) (((regs)->GR_L(1) & 0x00000FF8) << 4)
169
170 /*----------------------------------------------------------------------------*/
171 /* Set the compressed bit number in GR1 */
172 /*----------------------------------------------------------------------------*/
173 #define GR1_setcbn(regs, cbn) ((regs)->GR_L(1) = ((regs)->GR_L(1) & 0xFFFFFFF8) | ((cbn) & 0x00000007))
174
175 /*----------------------------------------------------------------------------*/
176 /* Constants */
177 /*----------------------------------------------------------------------------*/
178 #define MINPROC_SIZE 32768 /* Minumum processing size */
179
180 /*----------------------------------------------------------------------------*/
181 /* Typedefs and prototypes */
182 /*----------------------------------------------------------------------------*/
183 #ifndef NO_2ND_COMPILE
184 struct cc /* Compress context */
185 {
186 BYTE *cce; /* Character entry under investigation */
187 int cr; /* Characters read to check #261 */
188 unsigned dctsz; /* Dictionary size */
189 BYTE deadadm[8192][0x100 / 8]; /* Dead end administration */
190 BYTE deadend; /* Dead end indicator */
191 BYTE *dest; /* Destination MADDR address */
192 BYTE *dict[32]; /* Dictionary MADDR addresses */
193 GREG dictor; /* Dictionary origin */
194 BYTE *edict[32]; /* Expansion dictionary MADDR addrs */
195 int f1; /* Indication format-1 sibling descr */
196 REGS *iregs; /* Intermediate registers */
197 U16 is[8]; /* Cache for 8 index symbols */
198 unsigned ofst; /* Latest fetched offset */
199 int r1; /* Guess what */
200 int r2; /* Yep */
201 REGS *regs; /* Registers */
202 BYTE searchadm[1][0x100 / 8]; /* Search administration */
203 unsigned smbsz; /* Symbol size */
204 BYTE *src; /* Source MADDR page address */
205 unsigned srclen; /* Source length left in page */
206 BYTE st; /* Symbol translation */
207 };
208
209 struct ec /* Expand context */
210 {
211 BYTE *dest; /* Destination MADDR page address */
212 BYTE *dict[32]; /* Dictionary MADDR addresses */
213 GREG dictor; /* Dictionary origin */
214 BYTE ec[8192 * 7]; /* Expanded index symbol cache */
215 int eci[8192]; /* Index within cache for is */
216 int ecl[8192]; /* Size of expanded is */
217 int ecwm; /* Water mark */
218 REGS *iregs; /* Intermediate registers */
219 BYTE oc[8 * 260]; /* Output cache */
220 unsigned ocl; /* Output cache length */
221 int r1; /* Guess what */
222 int r2; /* Yep */
223 REGS *regs; /* Registers */
224 unsigned smbsz; /* Symbol size */
225 BYTE *src; /* Source MADDR page address */
226
227 #ifdef OPTION_CMPSC_DEBUG
228 unsigned dbgac; /* Alphabet characters */
229 unsigned dbgbi; /* bytes in */
230 unsigned dbgbo; /* bytes out */
231 unsigned dbgch; /* Cache hits */
232 unsigned dbgiss; /* Expanded iss */
233 #endif /* #ifdef OPTION_CMPSC_DEBUG */
234
235 };
236 #endif /* #ifndef NO_2ND_COMPILE */
237
238 static void ARCH_DEP(cmpsc_compress)(int r1, int r2, REGS *regs, REGS *iregs);
239 static int ARCH_DEP(cmpsc_compress_single_is)(struct cc *cc);
240 static void ARCH_DEP(cmpsc_expand)(int r1, int r2, REGS *regs, REGS *iregs);
241 static void ARCH_DEP(cmpsc_expand_is)(struct ec *ec, U16 is);
242 static int ARCH_DEP(cmpsc_expand_single_is)(struct ec *ec);
243 static BYTE *ARCH_DEP(cmpsc_fetch_cce)(struct cc *cc, unsigned index);
244 static int ARCH_DEP(cmpsc_fetch_ch)(struct cc *cc);
245 static int ARCH_DEP(cmpsc_fetch_is)(struct ec *ec, U16 *is);
246 static void ARCH_DEP(cmpsc_fetch_iss)(struct ec *ec, U16 is[8]);
247 #ifdef OPTION_CMPSC_DEBUG
248 static void cmpsc_print_cce(BYTE *cce);
249 static void cmpsc_print_ece(BYTE *ece);
250 static void cmpsc_print_sd(int f1, BYTE *sd1, BYTE *sd2);
251 #endif /* #ifdef OPTION_CMPSC_DEBUG */
252 static int ARCH_DEP(cmpsc_search_cce)(struct cc *cc, U16 *is);
253 static int ARCH_DEP(cmpsc_search_sd)(struct cc *cc, U16 *is);
254 static int ARCH_DEP(cmpsc_store_is)(struct cc *cc, U16 is);
255 static void ARCH_DEP(cmpsc_store_iss)(struct cc *cc);
256 static int ARCH_DEP(cmpsc_test_ec)(struct cc *cc, BYTE *cce);
257 static int ARCH_DEP(cmpsc_vstore)(struct ec *ec, BYTE *buf, unsigned len);
258
259 /*----------------------------------------------------------------------------*/
260 /* B263 CMPSC - Compression Call [RRE] */
261 /*----------------------------------------------------------------------------*/
DEF_INST(compression_call)262 DEF_INST(compression_call)
263 {
264 REGS iregs; /* Intermediate registers */
265 int r1; /* Guess what */
266 int r2; /* Yep */
267
268 RRE(inst, regs, r1, r2);
269
270 #ifdef OPTION_CMPSC_DEBUG
271 logmsg("CMPSC: compression call\n");
272 logmsg(" r1 : GR%02d\n", r1);
273 logmsg(" address : " F_VADR "\n", regs->GR(r1));
274 logmsg(" length : " F_GREG "\n", regs->GR(r1 + 1));
275 logmsg(" r2 : GR%02d\n", r2);
276 logmsg(" address : " F_VADR "\n", regs->GR(r2));
277 logmsg(" length : " F_GREG "\n", regs->GR(r2 + 1));
278 logmsg(" GR00 : " F_GREG "\n", regs->GR(0));
279 logmsg(" zp : %s\n", TRUEFALSE(GR0_zp(regs)));
280 logmsg(" st : %s\n", TRUEFALSE(GR0_st(regs)));
281 logmsg(" cdss : %d\n", GR0_cdss(regs));
282 logmsg(" f1 : %s\n", TRUEFALSE(GR0_f1(regs)));
283 logmsg(" e : %s\n", TRUEFALSE(GR0_e(regs)));
284 logmsg(" GR01 : " F_GREG "\n", regs->GR(1));
285 logmsg(" dictor: " F_GREG "\n", GR1_dictor(regs));
286 logmsg(" sttoff: %08X\n", GR1_sttoff(regs));
287 logmsg(" cbn : %d\n", GR1_cbn(regs));
288 #endif /* #ifdef OPTION_CMPSC_DEBUG */
289
290 /* Check the registers on even-odd pairs and valid compression-data symbol size */
291 if(unlikely(r1 & 0x01 || r2 & 0x01 || !GR0_cdss(regs) || GR0_cdss(regs) > 5))
292 ARCH_DEP(program_interrupt)(regs, PGM_SPECIFICATION_EXCEPTION);
293
294 /* Check for empty input */
295 if(unlikely(!GR_A(r2 + 1, regs)))
296 {
297
298 #ifdef OPTION_CMPSC_DEBUG
299 logmsg(" Zero input, returning cc0\n");
300 #endif /* #ifdef OPTION_CMPSC_DEBUG */
301
302 regs->psw.cc = 0;
303 return;
304 }
305
306 /* Check for empty output */
307 if(unlikely(!GR_A(r1 + 1, regs)))
308 {
309
310 #ifdef OPTION_CMPSC_DEBUG
311 logmsg(" Zero output, returning cc1\n");
312 #endif /* #ifdef OPTION_CMPSC_DEBUG */
313
314 regs->psw.cc = 1;
315 return;
316 }
317
318 /* Initialize intermediate registers */
319 INITREGS(&iregs, regs, r1, r2);
320
321 /* Now go to the requested function */
322 if(likely(GR0_e(regs)))
323 ARCH_DEP(cmpsc_expand)(r1, r2, regs, &iregs);
324 else
325 ARCH_DEP(cmpsc_compress)(r1, r2, regs, &iregs);
326 }
327
328 /*============================================================================*/
329 /* Compress */
330 /*============================================================================*/
331
332 /*----------------------------------------------------------------------------*/
333 /* Compression Character Entry macro's (CCE) */
334 /*----------------------------------------------------------------------------*/
335 /* act : additional-extension-character count */
336 /* cct : child count */
337 /* cptr : child pointer; index of first child */
338 /* d : double-character entry */
339 /* x(i) : examine child bit for children 1 to 5 */
340 /* y(i) : examine child bit for 6th/13th and 7th/14th sibling */
341 /*----------------------------------------------------------------------------*/
342 #define CCE_act(cce) ((cce)[1] >> 5)
343 #define CCE_cct(cce) ((cce)[0] >> 5)
344 #define CCE_cptr(cce) ((((cce)[1] & 0x1f) << 8) | (cce)[2])
345 #define CCE_d(cce) ((cce)[1] & 0x20)
346 #define CCE_x(cce, i) ((cce)[0] & (0x10 >> (i)))
347 #define CCE_y(cce, i) ((cce)[1] & (0x80 >> (i)))
348
349 /*----------------------------------------------------------------------------*/
350 /* Compression Character Entry macro's (CCE) derived */
351 /*----------------------------------------------------------------------------*/
352 /* cc(i) : child character */
353 /* ccc(i) : indication consecutive child character */
354 /* ccs : number of child characters */
355 /* ec(i) : additional extension character */
356 /* ecs : number of additional extension characters */
357 /* mcc : indication if siblings follow child characters */
358 /*----------------------------------------------------------------------------*/
359 #define CCE_cc(cce, i) ((cce)[3 + CCE_ecs((cce)) + (i)])
360 #define CCE_ccc(cce, i) (CCE_cc((cce), (i)) == CCE_cc((cce), 0))
361 #define CCE_ccs(cce) (CCE_cct((cce)) - (CCE_mcc((cce)) ? 1 : 0))
362 #define CCE_ec(cce, i) ((cce)[3 + (i)])
363 #define CCE_ecs(cce) ((CCE_cct((cce)) <= 1) ? CCE_act((cce)) : (CCE_d((cce)) ? 1 : 0))
364 #define CCE_mcc(cce) ((CCE_cct((cce)) + (CCE_d((cce)) ? 1 : 0) == 6))
365
366 /*----------------------------------------------------------------------------*/
367 /* Format-0 Sibling Descriptors macro's (SD0) */
368 /*----------------------------------------------------------------------------*/
369 /* sct : sibling count */
370 /* y(i) : examine child bit for siblings 1 to 5 */
371 /*----------------------------------------------------------------------------*/
372 #define SD0_sct(sd0) ((sd0)[0] >> 5)
373 #define SD0_y(sd0, i) ((sd0)[0] & (0x10 >> (i)))
374
375 /*----------------------------------------------------------------------------*/
376 /* Format-0 Sibling Descriptors macro's (SD0) derived */
377 /*----------------------------------------------------------------------------*/
378 /* ccc(i) : indication consecutive child character */
379 /* ecb(i) : examine child bit, if y then 6th/7th fetched from parent */
380 /* msc : indication if siblings follows last sibling */
381 /* sc(i) : sibling character */
382 /* scs : number of sibling characters */
383 /*----------------------------------------------------------------------------*/
384 #define SD0_ccc(sd0, i) (SD0_sc((sd0), (i)) == SD0_sc((sd0), 0))
385 #define SD0_ecb(sd0, i, cce, y) (((i) < 5) ? SD0_y((sd0), (i)) : (y) ? CCE_y((cce), ((i) - 5)) : 1)
386 #define SD0_msc(sd0) (!SD0_sct((sd0)))
387 #define SD0_sc(sd0, i) ((sd0)[1 + (i)])
388 #define SD0_scs(sd0) (SD0_msc((sd0)) ? 7 : SD0_sct((sd0)))
389
390 /*----------------------------------------------------------------------------*/
391 /* Format-1 Sibling Descriptors macro's (SD1) */
392 /*----------------------------------------------------------------------------*/
393 /* sct : sibling count */
394 /* y(i) : examine child bit for sibling 1 to 12 */
395 /*----------------------------------------------------------------------------*/
396 #define SD1_sct(sd1) ((sd1)[0] >> 4)
397 #define SD1_y(sd1, i) ((i) < 4 ? ((sd1)[0] & (0x08 >> (i))) : ((sd1)[1] & (0x800 >> (i))))
398
399 /*----------------------------------------------------------------------------*/
400 /* Format-1 Sibling Descriptors macro's (SD1) derived */
401 /*----------------------------------------------------------------------------*/
402 /* ccc(i) : indication consecutive child character */
403 /* ecb(i) : examine child bit, if y then 13th/14th fetched from parent */
404 /* msc : indication if siblings follows last sibling */
405 /* sc(i) : sibling character */
406 /* scs : number of sibling characters */
407 /*----------------------------------------------------------------------------*/
408 #define SD1_ccc(sd1, sd2, i) (SD1_sc((sd1), (sd2), (i)) == SD1_sc((sd1), (sd2), 0))
409 #define SD1_ecb(sd1, i, cce, y) (((i) < 12) ? SD1_y((sd1), (i)) : (y) ? CCE_y((cce), ((i) - 12)) : 1)
410 #define SD1_msc(sd1) ((SD1_sct((sd1)) == 15))
411 #define SD1_sc(sd1, sd2, i) ((i) < 6 ? (sd1)[2 + (i)] : (sd2)[(i) - 6])
412 #define SD1_scs(sd1) (SD1_msc((sd1)) ? 14 : SD1_sct((sd1)))
413
414 /*----------------------------------------------------------------------------*/
415 /* Format independent sibling descriptor macro's */
416 /*----------------------------------------------------------------------------*/
417 #define SD_ccc(f1, sd1, sd2, i) ((f1) ? SD1_ccc((sd1), (sd2), (i)) : SD0_ccc((sd1), (i)))
418 #define SD_ecb(f1, sd1, i, cce, y) ((f1) ? SD1_ecb((sd1), (i), (cce), (y)) : SD0_ecb((sd1), (i), (cce), (y)))
419 #define SD_msc(f1, sd1) ((f1) ? SD1_msc((sd1)) : SD0_msc((sd1)))
420 #define SD_sc(f1, sd1, sd2, i) ((f1) ? SD1_sc((sd1), (sd2), (i)) : SD0_sc((sd1), (i)))
421 #define SD_scs(f1, sd1) ((f1) ? SD1_scs((sd1)) : SD0_scs((sd1)))
422
423 /*----------------------------------------------------------------------------*/
424 /* ADJUSTREGS in compression context */
425 /*----------------------------------------------------------------------------*/
426 #define ADJUSTREGSC(cc, r, regs, iregs, len) \
427 { \
428 ADJUSTREGS((r), (regs), (iregs), (len)) \
429 if(likely((cc)->srclen > (len))) \
430 { \
431 (cc)->src += (len); \
432 (cc)->srclen -= (len); \
433 } \
434 else \
435 { \
436 (cc)->src = NULL; \
437 (cc)->srclen = 0; \
438 } \
439 }
440 #define BIT_get(array, is, ch) ((array)[(is)][(ch) / 8] & (0x80 >> ((ch) % 8)))
441 #define BIT_set(array, is, ch) ((array)[(is)][(ch) / 8] |= (0x80 >> ((ch) % 8)))
442
443 /*============================================================================*/
444
445 /*----------------------------------------------------------------------------*/
446 /* cmpsc_compress */
447 /*----------------------------------------------------------------------------*/
ARCH_DEP(cmpsc_compress)448 static void ARCH_DEP(cmpsc_compress)(int r1, int r2, REGS *regs, REGS *iregs)
449 {
450 struct cc cc; /* Compression context */
451 int i; /* Index */
452 U16 is; /* Last matched index symbol */
453 int j; /* Index */
454 GREG srclen; /* Source length */
455
456 /* Initialize compression context */
457 cc.dctsz = GR0_dctsz(regs);
458 memset(cc.deadadm, 0, sizeof(cc.deadadm));
459 cc.dest = NULL;
460 memset(cc.dict, 0, sizeof(cc.dict));
461 memset(cc.edict, 0, sizeof(cc.edict));
462 cc.dictor = GR1_dictor(iregs);
463 cc.f1 = GR0_f1(regs);
464 cc.iregs = iregs;
465 cc.r1 = r1;
466 cc.r2 = r2;
467 cc.regs = regs;
468 cc.smbsz = GR0_smbsz(regs);
469 cc.src = NULL;
470 cc.srclen = 0;
471 cc.st = GR0_st(regs) ? 1 : 0;
472
473 /* Initialize values */
474 srclen = GR_A(cc.r2 + 1, cc.iregs);
475
476 /*--------------------------------------------------------------------------*/
477 /* Process individual index symbols until cbn becomes zero */
478 while(unlikely(GR1_cbn(cc.iregs)))
479 {
480 if(unlikely(ARCH_DEP(cmpsc_compress_single_is)(&cc)))
481 return;
482 }
483
484 /*--------------------------------------------------------------------------*/
485 /* Block processing, cbn stays zero */
486 while(likely(GR_A(cc.r1 + 1, cc.iregs) >= cc.smbsz))
487 {
488 for(i = 0; i < 8; i++)
489 {
490 /* Get the next character, return on end of source */
491 if(unlikely(!cc.src && ARCH_DEP(cmpsc_fetch_ch)(&cc)))
492 {
493 /* Write individual found index symbols */
494 for(j = 0; j < i; j++)
495 ARCH_DEP(cmpsc_store_is)(&cc, cc.is[j]);
496 COMMITREGS(cc.regs, cc.iregs, cc.r1, cc.r2);
497 return;
498 }
499
500 #ifdef OPTION_CMPSC_DEBUG
501 logmsg("fetch_ch : %02X at " F_VADR "\n", *cc.src, GR_A(cc.r2, cc.iregs));
502 #endif /* #ifdef OPTION_CMPSC_DEBUG */
503
504 /* Set the alphabet entry, adjust registers and initiate charcters read */
505 is = *cc.src;
506 ADJUSTREGSC(&cc, cc.r2, cc.regs, cc.iregs, 1);
507 cc.cr = 1;
508
509 /* Check for alphabet entry ch dead end combination */
510 if(unlikely(!(cc.src && BIT_get(cc.deadadm, is, *cc.src))))
511 {
512 /* Get the alphabet entry and try to find a child */
513 cc.cce = ARCH_DEP(cmpsc_fetch_cce)(&cc, is);
514 while(ARCH_DEP(cmpsc_search_cce)(&cc, &is))
515 {
516 /* Check for other dead end combination */
517 if(unlikely(cc.src && BIT_get(cc.deadadm, is, *cc.src)))
518 {
519
520 #ifdef OPTION_CMPSC_DEBUG
521 logmsg("dead end : %04X %02X encountered\n", is, *cc.src);
522 #endif /* #ifdef OPTION_CMPSC_DEBUG */
523
524 break;
525 }
526 }
527
528 /* Registrate possible found dead ends */
529 if(unlikely(cc.deadend && cc.src))
530 {
531
532 #ifdef OPTION_CMPSC_DEBUG
533 logmsg("dead end : %04X in combination with", is);
534 for(j = 0; j < 0x100; j++)
535 {
536 if(!(j % 16))
537 logmsg("\n :");
538 if(BIT_get(cc.searchadm, 0, j))
539 logmsg(" ");
540 else
541 logmsg(" %02X", j);
542 }
543 logmsg("\n");
544 #endif /* #ifdef OPTION_CMPSC_DEBUG */
545
546 /* Registrate all discovered dead ends */
547 for(j = 0; j < 0x100 / 8; j++)
548 cc.deadadm[is][j] = ~cc.searchadm[0][j];
549 }
550 }
551
552 #ifdef OPTION_CMPSC_DEBUG
553 else
554 logmsg("dead end : %04X %02X encountered\n", is, *cc.src);
555 #endif /* #ifdef OPTION_CMPSC_DEBUG */
556
557 /* Write the last match */
558 cc.is[i] = is;
559
560 #ifdef OPTION_CMPSC_DEBUG
561 logmsg("compress : is %04X (%d)\n", is, i);
562 #endif /* #ifdef OPTION_CMPSC_DEBUG */
563
564 }
565
566 /* Write index symbols and commit */
567 ARCH_DEP(cmpsc_store_iss)(&cc);
568 COMMITREGS2(cc.regs, cc.iregs, cc.r1, cc.r2);
569
570 /* Return with cc3 on interrupt pending after a minumum size of processing */
571 if(unlikely(srclen - GR_A(cc.r2 + 1, cc.iregs) >= MINPROC_SIZE && INTERRUPT_PENDING(cc.regs)))
572 {
573
574 #ifdef OPTION_CMPSC_DEBUG
575 logmsg("Interrupt pending, commit and return with cc3\n");
576 #endif /* #ifdef OPTION_CMPSC_DEBUG */
577
578 cc.regs->psw.cc = 3;
579 return;
580 }
581 }
582
583 /*--------------------------------------------------------------------------*/
584 /* Process individual index symbols until end of destination (or source) */
585 while(!likely(ARCH_DEP(cmpsc_compress_single_is)(&cc)));
586 }
587
588 /*----------------------------------------------------------------------------*/
589 /* cmpsc_compress_single_is */
590 /*----------------------------------------------------------------------------*/
ARCH_DEP(cmpsc_compress_single_is)591 static int ARCH_DEP(cmpsc_compress_single_is)(struct cc *cc)
592 {
593 int i; /* Index */
594 U16 is; /* index symbol */
595
596 /* Get the next character, return -1 on end of source */
597 if(unlikely(!cc->src && ARCH_DEP(cmpsc_fetch_ch)(cc)))
598 return(-1);
599
600 #ifdef OPTION_CMPSC_DEBUG
601 logmsg("fetch_ch : %02X at " F_VADR "\n", *cc->src, GR_A(cc->r2, cc->iregs));
602 #endif /* #ifdef OPTION_CMPSC_DEBUG */
603
604 /* Set the alphabet entry, adjust registers and initiate characters read */
605 is = *cc->src;
606 ADJUSTREGSC(cc, cc->r2, cc->regs, cc->iregs, 1);
607 cc->cr = 1;
608
609 /* Search for child when no src and no dead end combination */
610 if(unlikely(!(cc->src && BIT_get(cc->deadadm, is, *cc->src))))
611 {
612 /* Get the alphabet entry and try to find a child */
613 cc->cce = ARCH_DEP(cmpsc_fetch_cce)(cc, is);
614 while(ARCH_DEP(cmpsc_search_cce)(cc, &is))
615 {
616 /* Check for (found cce entry + ch) dead end combination */
617 if(unlikely(cc->src && BIT_get(cc->deadadm, is, *cc->src)))
618 {
619
620 #ifdef OPTION_CMPSC_DEBUG
621 logmsg("dead end : %04X %02X encountered\n", is, *cc->src);
622 #endif /* #ifdef OPTION_CMPSC_DEBUG */
623
624 break;
625 }
626 }
627
628 /* Registrate possible found dead ends */
629 if(unlikely(cc->deadend && cc->src))
630 {
631
632 #ifdef OPTION_CMPSC_DEBUG
633 logmsg("dead end : %04X in combination with", is);
634 for(i = 0; i < 0x100; i++)
635 {
636 if(!(i % 16))
637 logmsg("\n :");
638 if(BIT_get(cc->searchadm, 0, i))
639 logmsg(" ");
640 else
641 logmsg(" %02X", i);
642 }
643 logmsg("\n");
644 #endif /* #ifdef OPTION_CMPSC_DEBUG */
645
646 /* Registrate all discovered dead ends */
647 for(i = 0; i < 0x100 / 8; i++)
648 cc->deadadm[is][i] = ~cc->searchadm[0][i];
649 }
650 }
651
652 #ifdef OPTION_CMPSC_DEBUG
653 else
654 logmsg("dead end : %04X %02X encountered\n", is, *cc->src);
655 #endif /* #ifdef OPTION_CMPSC_DEBUG */
656
657 /* Write the last match, return on end of destination */
658 if(unlikely(ARCH_DEP(cmpsc_store_is)(cc, is)))
659 return(-1);
660
661 /* Commit registers */
662 COMMITREGS(cc->regs, cc->iregs, cc->r1, cc->r2);
663 return(0);
664 }
665
666 /*----------------------------------------------------------------------------*/
667 /* cmpsc_fetch_cce (compression character entry) */
668 /*----------------------------------------------------------------------------*/
ARCH_DEP(cmpsc_fetch_cce)669 static BYTE *ARCH_DEP(cmpsc_fetch_cce)(struct cc *cc, unsigned index)
670 {
671 BYTE *cce; /* Compression child entry */
672 unsigned cct; /* Child count */
673
674 index *= 8;
675 if(unlikely(!cc->dict[index / 0x800]))
676 cc->dict[index / 0x800] = MADDR((cc->dictor + (index / 0x800) * 0x800) & ADDRESS_MAXWRAP(cc->regs), cc->r2, cc->regs, ACCTYPE_READ, cc->regs->psw.pkey);
677 cce = &cc->dict[index / 0x800][index % 0x800];
678 ITIMER_SYNC((cc->dictor + index) & ADDRESS_MAXWRAP(cc->regs), 8 - 1, cc->regs);
679
680 #ifdef OPTION_CMPSC_DEBUG
681 logmsg("fetch_cce: index %04X\n", index / 8);
682 cmpsc_print_cce(cce);
683 #endif /* #ifdef OPTION_CMPSC_DEBUG */
684
685 /* Check for data exception */
686 cct = CCE_cct(cce);
687 if(cct < 2)
688 {
689 if(unlikely(CCE_act(cce) > 4))
690 {
691 cc->regs->dxc = DXC_DECIMAL;
692 ARCH_DEP(program_interrupt)(cc->regs, PGM_DATA_EXCEPTION);
693 }
694 }
695 else
696 {
697 if(!CCE_d(cce))
698 {
699 if(unlikely(cct == 7))
700 {
701 cc->regs->dxc = DXC_DECIMAL;
702 ARCH_DEP(program_interrupt)(cc->regs, PGM_DATA_EXCEPTION);
703 }
704 }
705 else
706 {
707 if(unlikely(cct > 5))
708 {
709 cc->regs->dxc = DXC_DECIMAL;
710 ARCH_DEP(program_interrupt)(cc->regs, PGM_DATA_EXCEPTION);
711 }
712 }
713 }
714 return(cce);
715 }
716
717 /*----------------------------------------------------------------------------*/
718 /* cmpsc_fetch_ch (character) */
719 /*----------------------------------------------------------------------------*/
ARCH_DEP(cmpsc_fetch_ch)720 static int ARCH_DEP(cmpsc_fetch_ch)(struct cc *cc)
721 {
722 /* Check for end of source condition */
723 if(unlikely(!GR_A(cc->r2 + 1, cc->iregs)))
724 {
725
726 #ifdef OPTION_CMPSC_DEBUG
727 logmsg("fetch_ch : reached end of source\n");
728 #endif /* #ifdef OPTION_CMPSC_DEBUG */
729
730 cc->regs->psw.cc = 0;
731 return(-1);
732 }
733
734 /* Calculate source length in page */
735 cc->srclen = 0x800 - (GR_A(cc->r2, cc->iregs) & 0x7ff);
736 if(unlikely(GR_A(cc->r2 + 1, cc->iregs) < cc->srclen))
737 cc->srclen = GR_A(cc->r2 + 1, cc->iregs);
738
739 /* Get address */
740 cc->src = MADDR(GR_A(cc->r2, cc->iregs) & ADDRESS_MAXWRAP(cc->regs), cc->r2, cc->regs, ACCTYPE_READ, cc->regs->psw.pkey);
741 return(0);
742 }
743
744 #ifndef NO_2ND_COMPILE
745 #ifdef OPTION_CMPSC_DEBUG
746 /*----------------------------------------------------------------------------*/
747 /* cmpsc_print_cce (compression character entry) */
748 /*----------------------------------------------------------------------------*/
cmpsc_print_cce(BYTE * cce)749 static void cmpsc_print_cce(BYTE *cce)
750 {
751 int j; /* Index */
752 int prt_detail; /* Switch for detailed printing */
753
754 logmsg(" cce : ");
755 prt_detail = 0;
756 for(j = 0; j < 8; j++)
757 {
758 if(!prt_detail && cce[j])
759 prt_detail = 1;
760 logmsg("%02X", cce[j]);
761 }
762 logmsg("\n");
763 if(prt_detail)
764 {
765 logmsg(" cct : %d\n", CCE_cct(cce));
766 switch(CCE_cct(cce))
767 {
768 case 0:
769 {
770 logmsg(" act : %d\n", (int) CCE_act(cce));
771 if(CCE_act(cce))
772 {
773 logmsg(" ec(s) :");
774 for(j = 0; j < CCE_ecs(cce); j++)
775 logmsg(" %02X", CCE_ec(cce, j));
776 logmsg("\n");
777 }
778 break;
779 }
780 case 1:
781 {
782 logmsg(" x1 : %c\n", (int) (CCE_x(cce, 0) ? '1' : '0'));
783 logmsg(" act : %d\n", (int) CCE_act(cce));
784 logmsg(" cptr : %04X\n", CCE_cptr(cce));
785 if(CCE_act(cce))
786 {
787 logmsg(" ec(s) :");
788 for(j = 0; j < CCE_ecs(cce); j++)
789 logmsg(" %02X", CCE_ec(cce, j));
790 logmsg("\n");
791 }
792 logmsg(" cc : %02X\n", CCE_cc(cce, 0));
793 break;
794 }
795 default:
796 {
797 logmsg(" x1..x5 : ");
798 for(j = 0; j < 5; j++)
799 logmsg("%c", (int) (CCE_x(cce, j) ? '1' : '0'));
800 logmsg("\n y1..y2 : ");
801 for(j = 0; j < 2; j++)
802 logmsg("%c", (int) (CCE_y(cce, j) ? '1' : '0'));
803 logmsg("\n d : %s\n", TRUEFALSE(CCE_d(cce)));
804 logmsg(" cptr : %04X\n", CCE_cptr(cce));
805 if(CCE_d(cce))
806 logmsg(" ec : %02X\n", CCE_ec(cce, 0));
807 logmsg(" ccs :");
808 for(j = 0; j < CCE_ccs(cce); j++)
809 logmsg(" %02X", CCE_cc(cce, j));
810 logmsg("\n");
811 break;
812 }
813 }
814 }
815 }
816
817 /*----------------------------------------------------------------------------*/
818 /* cmpsc_print_sd (sibling descriptor) */
819 /*----------------------------------------------------------------------------*/
cmpsc_print_sd(int f1,BYTE * sd1,BYTE * sd2)820 static void cmpsc_print_sd(int f1, BYTE *sd1, BYTE *sd2)
821 {
822 int j; /* Index */
823 int prt_detail; /* Switch for detailed printing */
824
825 if(f1)
826 {
827 logmsg(" sd1 : ");
828 prt_detail = 0;
829 for(j = 0; j < 8; j++)
830 {
831 if(!prt_detail && sd1[j])
832 prt_detail = 1;
833 logmsg("%02X", sd1[j]);
834 }
835 for(j = 0; j < 8; j++)
836 {
837 if(!prt_detail && sd2[j])
838 prt_detail = 1;
839 logmsg("%02X", sd2[j]);
840 }
841 logmsg("\n");
842 if(prt_detail)
843 {
844 logmsg(" sct : %d\n", SD1_sct(sd1));
845 logmsg(" y1..y12: ");
846 for(j = 0; j < 12; j++)
847 logmsg("%c", (SD1_y(sd1, j) ? '1' : '0'));
848 logmsg("\n sc(s) :");
849 for(j = 0; j < SD1_scs(sd1); j++)
850 logmsg(" %02X", SD1_sc(sd1, sd2, j));
851 logmsg("\n");
852 }
853 }
854 else
855 {
856 logmsg(" sd0 : ");
857 prt_detail = 0;
858 for(j = 0; j < 8; j++)
859 {
860 if(!prt_detail && sd1[j])
861 prt_detail = 1;
862 logmsg("%02X", sd1[j]);
863 }
864 logmsg("\n");
865 if(prt_detail)
866 {
867 logmsg(" sct : %d\n", SD0_sct(sd1));
868 logmsg(" y1..y5 : ");
869 for(j = 0; j < 5; j++)
870 logmsg("%c", (SD0_y(sd1, j) ? '1' : '0'));
871 logmsg("\n sc(s) :");
872 for(j = 0; j < SD0_scs(sd1); j++)
873 logmsg(" %02X", SD0_sc(sd1, j));
874 logmsg("\n");
875 }
876 }
877 }
878 #endif /* #ifdef OPTION_CMPSC_DEBUG */
879 #endif /* #ifndef NO_2ND_COMPILE */
880
881 /*----------------------------------------------------------------------------*/
882 /* cmpsc_search_cce (compression character entry) */
883 /*----------------------------------------------------------------------------*/
ARCH_DEP(cmpsc_search_cce)884 static int ARCH_DEP(cmpsc_search_cce)(struct cc *cc, U16 *is)
885 {
886 BYTE *ccce; /* Child compression character entry */
887 int ccs; /* Number of child characters */
888 int i; /* Child character index */
889 int ind_search_siblings; /* Indicator for searching siblings */
890
891 /* Initialize values */
892 ccs = CCE_ccs(cc->cce);
893
894 /* Get the next character when there are children */
895 if(likely(ccs))
896 {
897 if(unlikely(!cc->src && ARCH_DEP(cmpsc_fetch_ch(cc))))
898 return(0);
899
900 #ifdef OPTION_CMPSC_DEBUG
901 logmsg("fetch_ch : %02X at " F_VADR "\n", *cc->src, GR_A(cc->r2, cc->iregs));
902 #endif /* #ifdef OPTION_CMPSC_DEBUG */
903
904 /* Check for reading character 261 */
905 cc->cr++;
906 if(unlikely(cc->cr > 260))
907 {
908
909 #ifdef OPTION_CMPSC_DEBUG
910 logmsg("Trying to read character #%d\n", cc->cr);
911 #endif /* #ifdef OPTION_CMPSC_DEBUG */
912
913 cc->regs->dxc = DXC_DECIMAL;
914 ARCH_DEP(program_interrupt)(cc->regs, PGM_DATA_EXCEPTION);
915 }
916
917 memset(cc->searchadm, 0, sizeof(cc->searchadm));
918 cc->deadend = 1;
919 ind_search_siblings = 1;
920
921 /* Now check all children in parent */
922 for(i = 0; i < ccs; i++)
923 {
924 /* Stop searching when child tested and no consecutive child character */
925 if(unlikely(!ind_search_siblings && !CCE_ccc(cc->cce, i)))
926 return(0);
927
928 /* Compare character with child */
929 if(unlikely(*cc->src == CCE_cc(cc->cce, i)))
930 {
931 /* Child is tested, so stop searching for siblings and no dead end */
932 ind_search_siblings = 0;
933 cc->deadend = 0;
934
935 /* Check if child should not be examined */
936 if(unlikely(!CCE_x(cc->cce, i)))
937 {
938 /* No need to examine child, found the last match */
939 ADJUSTREGSC(cc, cc->r2, cc->regs, cc->iregs, 1);
940 *is = CCE_cptr(cc->cce) + i;
941 return(0);
942 }
943
944 /* Found a child get the character entry and check if additional extension characters match */
945 ccce = ARCH_DEP(cmpsc_fetch_cce)(cc, CCE_cptr(cc->cce) + i);
946 if(likely(!CCE_ecs(ccce) || !ARCH_DEP(cmpsc_test_ec)(cc, ccce)))
947 {
948 /* Set last match */
949 ADJUSTREGSC(cc, cc->r2, cc->regs, cc->iregs, (U32) CCE_ecs(ccce) + 1);
950 *is = CCE_cptr(cc->cce) + i;
951
952 #ifdef OPTION_CMPSC_DEBUG
953 logmsg("search_cce index %04X parent\n", *is);
954 #endif /* #ifdef OPTION_CMPSC_DEBUG */
955
956 /* Found a matching child, make it parent and keep searching */
957 cc->cce = ccce;
958 return(1);
959 }
960 }
961 BIT_set(cc->searchadm, 0, CCE_cc(cc->cce, i));
962 }
963
964 /* Are there siblings? */
965 if(likely(CCE_mcc(cc->cce)))
966 return(ARCH_DEP(cmpsc_search_sd)(cc, is));
967 }
968 else
969 {
970 /* No children, no extension character, always a dead end */
971 if(!CCE_act(cc->cce))
972 {
973
974 #ifdef OPTION_CMPSC_DEBUG
975 logmsg("dead end : %04X permanent dead end discovered\n", *is);
976 #endif /* #ifdef OPTION_CMPSC_DEBUG */
977
978 memset(&cc->deadadm[*is], 0xff, 0x100 / 8);
979 }
980 cc->deadend = 0;
981 }
982
983 /* No siblings, write found index symbol */
984 return(0);
985 }
986
987 /*----------------------------------------------------------------------------*/
988 /* cmpsc_search_sd (sibling descriptor) */
989 /*----------------------------------------------------------------------------*/
ARCH_DEP(cmpsc_search_sd)990 static int ARCH_DEP(cmpsc_search_sd)(struct cc *cc, U16 *is)
991 {
992 BYTE *ccce; /* Child compression character entry */
993 int i; /* Sibling character index */
994 int ind_search_siblings; /* Indicator for keep searching */
995 U16 index; /* Index within dictionary */
996 int scs; /* Number of sibling characters */
997 BYTE *sd1; /* Sibling descriptor fmt-0|1 part 1 */
998 BYTE *sd2 = NULL; /* Sibling descriptor fmt-1 part 2 */
999 int sd_ptr; /* Pointer to sibling descriptor */
1000 int y_in_parent; /* Indicator if y bits are in parent */
1001
1002 /* Initialize values */
1003 ind_search_siblings = 1;
1004 sd_ptr = CCE_ccs(cc->cce);
1005 y_in_parent = 1;
1006
1007 do
1008 {
1009 /* Get the sibling descriptor */
1010 index = (CCE_cptr(cc->cce) + sd_ptr) * 8;
1011 if(unlikely(!cc->dict[index / 0x800]))
1012 cc->dict[index / 0x800] = MADDR((cc->dictor + (index / 0x800) * 0x800) & ADDRESS_MAXWRAP(cc->regs), cc->r2, cc->regs, ACCTYPE_READ, cc->regs->psw.pkey);
1013 sd1 = &cc->dict[index / 0x800][index % 0x800];
1014 ITIMER_SYNC((cc->dictor + index) & ADDRESS_MAXWRAP(cc->regs), 8 - 1, cc->regs);
1015
1016 /* If format-1, get second half from the expansion dictionary */
1017 if(cc->f1)
1018 {
1019 if(unlikely(!cc->edict[index / 0x800]))
1020 cc->edict[index / 0x800] = MADDR((cc->dictor + cc->dctsz + (index / 0x800) * 0x800) & ADDRESS_MAXWRAP(cc->regs), cc->r2, cc->regs, ACCTYPE_READ, cc->regs->psw.pkey);
1021 sd2 = &cc->edict[index / 0x800][index % 0x800];
1022 ITIMER_SYNC((cc->dictor + cc->dctsz + index) & ADDRESS_MAXWRAP(cc->regs), 8 - 1, cc->regs);
1023
1024 #ifdef OPTION_CMPSC_DEBUG
1025 /* Print before possible exception */
1026 logmsg("fetch_sd1: index %04X\n", CCE_cptr(cc->cce) + sd_ptr);
1027 cmpsc_print_sd(1, sd1, sd2);
1028 #endif /* #ifdef OPTION_CMPSC_DEBUG */
1029
1030 /* Check for data exception */
1031 if(unlikely(!SD1_sct(sd1)))
1032 {
1033 cc->regs->dxc = DXC_DECIMAL;
1034 ARCH_DEP(program_interrupt)((cc->regs), PGM_DATA_EXCEPTION);
1035 }
1036 }
1037
1038 #ifdef OPTION_CMPSC_DEBUG
1039 else
1040 {
1041 logmsg("fetch_sd0: index %04X\n", CCE_cptr(cc->cce) + sd_ptr);
1042 cmpsc_print_sd(0, sd1, sd2);
1043 }
1044 #endif /* #ifdef OPTION_CMPSC_DEBUG */
1045
1046 /* Check all children in sibling descriptor */
1047 scs = SD_scs(cc->f1, sd1);
1048 for(i = 0; i < scs; i++)
1049 {
1050 /* Stop searching when child tested and no consecutive child character */
1051 if(unlikely(!ind_search_siblings && !SD_ccc(cc->f1, sd1, sd2, i)))
1052 return(0);
1053 if(unlikely(*cc->src == SD_sc(cc->f1, sd1, sd2, i)))
1054 {
1055 /* Child is tested, so stop searching for siblings and no dead end */
1056 ind_search_siblings = 0;
1057 cc->deadend = 0;
1058
1059 /* Check if child should not be examined */
1060 if(unlikely(!SD_ecb(cc->f1, sd1, i, cc->cce, y_in_parent)))
1061 {
1062 /* No need to examine child, found the last match */
1063 ADJUSTREGSC(cc, cc->r2, cc->regs, cc->iregs, 1);
1064 *is = CCE_cptr(cc->cce) + sd_ptr + i + 1;
1065 return(0);
1066 }
1067
1068 /* Found a child get the character entry and check if additional extension characters match */
1069 ccce = ARCH_DEP(cmpsc_fetch_cce)(cc, CCE_cptr(cc->cce) + sd_ptr + i + 1);
1070 if(likely(!CCE_ecs(ccce) || !ARCH_DEP(cmpsc_test_ec)(cc, ccce)))
1071 {
1072 /* Set last match */
1073 ADJUSTREGSC(cc, cc->r2, cc->regs, cc->iregs, (U32) CCE_ecs(ccce) + 1);
1074 *is = CCE_cptr(cc->cce) + sd_ptr + i + 1;
1075
1076 #ifdef OPTION_CMPSC_DEBUG
1077 logmsg("search_sd: index %04X parent\n", *is);
1078 #endif /* #ifdef OPTION_CMPSC_DEBUG */
1079
1080 /* Found a matching child, make it parent and keep searching */
1081 cc->cce = ccce;
1082 return(1);
1083 }
1084 }
1085 BIT_set(cc->searchadm, 0, SD_sc(cc->f1, sd1, sd2, i));
1086 }
1087
1088 /* Next sibling follows last possible child */
1089 sd_ptr += scs + 1;
1090
1091 /* We get the next sibling descriptor, no y bits in parent for him */
1092 y_in_parent = 0;
1093 }
1094 while(ind_search_siblings && SD_msc(cc->f1, sd1));
1095 return(0);
1096 }
1097
1098 /*----------------------------------------------------------------------------*/
1099 /* cmpsc_store_is (index symbol) */
1100 /*----------------------------------------------------------------------------*/
ARCH_DEP(cmpsc_store_is)1101 static int ARCH_DEP(cmpsc_store_is)(struct cc *cc, U16 is)
1102 {
1103 unsigned cbn; /* Compressed-data bit number */
1104 U32 set_mask; /* Mask to set the bits */
1105 BYTE work[3]; /* Work bytes */
1106
1107 /* Initialize values */
1108 cbn = GR1_cbn(cc->iregs);
1109
1110 /* Can we write an index or interchange symbol */
1111 if(unlikely(GR_A(cc->r1 + 1, cc->iregs) < 3 && ((cbn + cc->smbsz - 1) / 8) >= GR_A(cc->r1 + 1, cc->iregs)))
1112 {
1113 cc->regs->psw.cc = 1;
1114
1115 #ifdef OPTION_CMPSC_DEBUG
1116 logmsg("store_is : end of output buffer\n");
1117 #endif /* #ifdef OPTION_CMPSC_DEBUG */
1118
1119 return(-1);
1120 }
1121
1122 /* Check if symbol translation is requested */
1123 if(unlikely(cc->st))
1124 {
1125 /* Get the interchange symbol */
1126 ARCH_DEP(vfetchc)(work, 1, (cc->dictor + GR1_sttoff(cc->iregs) + is * 2) & ADDRESS_MAXWRAP(cc->regs), cc->r2, cc->regs);
1127
1128 #ifdef OPTION_CMPSC_DEBUG
1129 logmsg("store_is : %04X -> %02X%02X\n", is, work[0], work[1]);
1130 #endif /* #ifdef OPTION_CMPSC_DEBUG */
1131
1132 /* set index_symbol to interchange symbol */
1133 is = (work[0] << 8) + work[1];
1134 }
1135
1136 /* Allign set mask */
1137 set_mask = ((U32) is) << (24 - cc->smbsz - cbn);
1138
1139 /* Calculate first byte */
1140 if(likely(cbn))
1141 {
1142 work[0] = ARCH_DEP(vfetchb)(GR_A(cc->r1, cc->iregs) & ADDRESS_MAXWRAP(cc->regs), cc->r1, cc->regs);
1143 work[0] |= (set_mask >> 16) & 0xff;
1144 }
1145 else
1146 work[0] = (set_mask >> 16) & 0xff;
1147
1148 /* Calculate second byte */
1149 work[1] = (set_mask >> 8) & 0xff;
1150
1151 /* Calculate possible third byte and store */
1152 if(unlikely((cc->smbsz + cbn) > 16))
1153 {
1154 work[2] = set_mask & 0xff;
1155 ARCH_DEP(vstorec)(work, 2, GR_A(cc->r1, cc->iregs) & ADDRESS_MAXWRAP(cc->regs), cc->r1, cc->regs);
1156 }
1157 else
1158 ARCH_DEP(vstorec)(work, 1, GR_A(cc->r1, cc->iregs) & ADDRESS_MAXWRAP(cc->regs), cc->r1, cc->regs);
1159
1160 /* Adjust destination registers */
1161 ADJUSTREGS(cc->r1, cc->regs, cc->iregs, (cbn + cc->smbsz) / 8);
1162
1163 /* Calculate and set the new Compressed-data Bit Number */
1164 GR1_setcbn(cc->iregs, (cbn + cc->smbsz) % 8);
1165
1166 #ifdef OPTION_CMPSC_DEBUG
1167 logmsg("store_is : %04X, cbn=%d, GR%02d=" F_VADR ", GR%02d=" F_GREG "\n", is, GR1_cbn(cc->iregs), cc->r1, cc->iregs->GR(cc->r1), cc->r1 + 1, cc->iregs->GR(cc->r1 + 1));
1168 #endif /* #ifdef OPTION_CMPSC_DEBUG */
1169
1170 return(0);
1171 }
1172
1173 /*----------------------------------------------------------------------------*/
1174 /* cmpsc_store_iss (index symbols) */
1175 /*----------------------------------------------------------------------------*/
ARCH_DEP(cmpsc_store_iss)1176 static void ARCH_DEP(cmpsc_store_iss)(struct cc *cc)
1177 {
1178 GREG dictor; /* Dictionary origin */
1179 int i;
1180 U16 *is; /* Index symbol array */
1181 unsigned len1; /* Length in first page */
1182 BYTE *main1; /* Address first page */
1183 BYTE mem[13]; /* Build buffer */
1184 unsigned ofst; /* Offset within page */
1185 BYTE *sk; /* Storage key */
1186
1187 /* Check if symbol translation is requested */
1188 if(unlikely(cc->st))
1189 {
1190 dictor = cc->dictor + GR1_sttoff(cc->iregs);
1191 for(i = 0; i < 8; i++)
1192 {
1193 /* Get the interchange symbol */
1194 ARCH_DEP(vfetchc)(mem, 1, (dictor + cc->is[i] * 2) & ADDRESS_MAXWRAP(cc->regs), cc->r2, cc->regs);
1195
1196 #ifdef OPTION_CMPSC_DEBUG
1197 logmsg("store_iss: %04X -> %02X%02X\n", cc->is[i], mem[0], mem[1]);
1198 #endif /* #ifdef OPTION_CMPSC_DEBUG */
1199
1200 /* set index_symbol to interchange symbol */
1201 cc->is[i] = (mem[0] << 8) + mem[1];
1202 }
1203 }
1204
1205 /* Calculate buffer for 8 index symbols */
1206 is = cc->is;
1207 switch(cc->smbsz)
1208 {
1209 case 9: /* 9-bits */
1210 {
1211 /* 0 1 2 3 4 5 6 7 8 */
1212 /* 012345670123456701234567012345670123456701234567012345670123456701234567 */
1213 /* 012345678012345678012345678012345678012345678012345678012345678012345678 */
1214 /* 0 1 2 3 4 5 6 7 */
1215 mem[0] = ( (is[0] >> 1));
1216 mem[1] = ((is[0] << 7) | (is[1] >> 2));
1217 mem[2] = ((is[1] << 6) | (is[2] >> 3));
1218 mem[3] = ((is[2] << 5) | (is[3] >> 4));
1219 mem[4] = ((is[3] << 4) | (is[4] >> 5));
1220 mem[5] = ((is[4] << 3) | (is[5] >> 6));
1221 mem[6] = ((is[5] << 2) | (is[6] >> 7));
1222 mem[7] = ((is[6] << 1) | (is[7] >> 8));
1223 mem[8] = ((is[7]) );
1224 break;
1225 }
1226 case 10: /* 10-bits */
1227 {
1228 /* 0 1 2 3 4 5 6 7 8 9 */
1229 /* 01234567012345670123456701234567012345670123456701234567012345670123456701234567 */
1230 /* 01234567890123456789012345678901234567890123456789012345678901234567890123456789 */
1231 /* 0 1 2 3 4 5 6 7 */
1232 mem[0] = ( (is[0] >> 2));
1233 mem[1] = ((is[0] << 6) | (is[1] >> 4));
1234 mem[2] = ((is[1] << 4) | (is[2] >> 6));
1235 mem[3] = ((is[2] << 2) | (is[3] >> 8));
1236 mem[4] = ((is[3]) );
1237 mem[5] = ( (is[4] >> 2));
1238 mem[6] = ((is[4] << 6) | (is[5] >> 4));
1239 mem[7] = ((is[5] << 4) | (is[6] >> 6));
1240 mem[8] = ((is[6] << 2) | (is[7] >> 8));
1241 mem[9] = ((is[7]) );
1242 break;
1243 }
1244 case 11: /* 11-bits */
1245 {
1246 /* 0 1 2 3 4 5 6 7 8 9 a */
1247 /* 0123456701234567012345670123456701234567012345670123456701234567012345670123456701234567 */
1248 /* 0123456789a0123456789a0123456789a0123456789a0123456789a0123456789a0123456789a0123456789a */
1249 /* 0 1 2 3 4 5 6 7 */
1250 mem[ 0] = ( (is[0] >> 3));
1251 mem[ 1] = ((is[0] << 5) | (is[1] >> 6));
1252 mem[ 2] = ((is[1] << 2) | (is[2] >> 9));
1253 mem[ 3] = ( (is[2] >> 1));
1254 mem[ 4] = ((is[2] << 7) | (is[3] >> 4));
1255 mem[ 5] = ((is[3] << 4) | (is[4] >> 7));
1256 mem[ 6] = ((is[4] << 1) | (is[5] >> 10));
1257 mem[ 7] = ( (is[5] >> 2));
1258 mem[ 8] = ((is[5] << 6) | (is[6] >> 5));
1259 mem[ 9] = ((is[6] << 3) | (is[7] >> 8));
1260 mem[10] = ((is[7]) );
1261 break;
1262 }
1263 case 12: /* 12-bits */
1264 {
1265 /* 0 1 2 3 4 5 6 7 8 9 a b */
1266 /* 012345670123456701234567012345670123456701234567012345670123456701234567012345670123456701234567 */
1267 /* 0123456789ab0123456789ab0123456789ab0123456789ab0123456789ab0123456789ab0123456789ab0123456789ab */
1268 /* 0 1 2 3 4 5 6 7 */
1269 mem[ 0] = ( (is[0] >> 4));
1270 mem[ 1] = ((is[0] << 4) | (is[1] >> 8));
1271 mem[ 2] = ((is[1]) );
1272 mem[ 3] = ( (is[2] >> 4));
1273 mem[ 4] = ((is[2] << 4) | (is[3] >> 8));
1274 mem[ 5] = ((is[3]) );
1275 mem[ 6] = ( (is[4] >> 4));
1276 mem[ 7] = ((is[4] << 4) | (is[5] >> 8));
1277 mem[ 8] = ((is[5]) );
1278 mem[ 9] = ( (is[6] >> 4));
1279 mem[10] = ((is[6] << 4) | (is[7] >> 8));
1280 mem[11] = ((is[7]) );
1281 break;
1282 }
1283 case 13: /* 13-bits */
1284 {
1285 /* 0 1 2 3 4 5 6 7 8 9 a b c */
1286 /* 01234567012345670123456701234567012345670123456701234567012345670123456701234567012345670123456701234567 */
1287 /* 0123456789abc0123456789abc0123456789abc0123456789abc0123456789abc0123456789abc0123456789abc0123456789abc */
1288 /* 0 1 2 3 4 5 6 7 */
1289 mem[ 0] = ( (is[0] >> 5));
1290 mem[ 1] = ((is[0] << 3) | (is[1] >> 10));
1291 mem[ 2] = ( (is[1] >> 2));
1292 mem[ 3] = ((is[1] << 6) | (is[2] >> 7));
1293 mem[ 4] = ((is[2] << 1) | (is[3] >> 12));
1294 mem[ 5] = ( (is[3] >> 4));
1295 mem[ 6] = ((is[3] << 4) | (is[4] >> 9));
1296 mem[ 7] = ( (is[4] >> 1));
1297 mem[ 8] = ((is[4] << 7) | (is[5] >> 6));
1298 mem[ 9] = ((is[5] << 2) | (is[6] >> 11));
1299 mem[10] = ( (is[6] >> 3));
1300 mem[11] = ((is[6] << 5) | (is[7] >> 8));
1301 mem[12] = ((is[7]) );
1302 break;
1303 }
1304 }
1305
1306 /* Fingers crossed that we stay within one page */
1307 ofst = GR_A(cc->r1, cc->iregs) & 0x7ff;
1308 if(likely(ofst + cc->smbsz <= 0x800))
1309 {
1310 if(unlikely(!cc->dest))
1311 cc->dest = MADDR((GR_A(cc->r1, cc->iregs) & ~0x7ff) & ADDRESS_MAXWRAP(cc->regs), cc->r1, cc->regs, ACCTYPE_WRITE, cc->regs->psw.pkey);
1312 memcpy(&cc->dest[ofst], mem, cc->smbsz);
1313 ITIMER_UPDATE(GR_A(cc->r1, cc->iregs) & ADDRESS_MAXWRAP(cc->regs), cc->smbsz - 1, cc->regs);
1314
1315 /* Perfect fit? */
1316 if(unlikely(ofst + cc->smbsz == 0x800))
1317 cc->dest = NULL;
1318 }
1319 else
1320 {
1321 /* We need 2 pages */
1322 if(unlikely(!cc->dest))
1323 main1 = MADDR((GR_A(cc->r1, cc->iregs) & ~0x7ff) & ADDRESS_MAXWRAP(cc->regs), cc->r1, cc->regs, ACCTYPE_WRITE_SKP, cc->regs->psw.pkey);
1324 else
1325 main1 = cc->dest;
1326 sk = cc->regs->dat.storkey;
1327 len1 = 0x800 - ofst;
1328 cc->dest = MADDR((GR_A(cc->r1, cc->iregs) + len1) & ADDRESS_MAXWRAP(cc->regs), cc->r1, cc->regs, ACCTYPE_WRITE, cc->regs->psw.pkey);
1329 memcpy(&main1[ofst], mem, len1);
1330 memcpy(cc->dest, &mem[len1], cc->smbsz - len1);
1331 *sk |= (STORKEY_REF | STORKEY_CHANGE);
1332 }
1333 ADJUSTREGS(cc->r1, cc->regs, cc->iregs, cc->smbsz);
1334
1335 #ifdef OPTION_CMPSC_DEBUG
1336 logmsg("store_iss:");
1337 for(i = 0; i < 8; i++)
1338 logmsg(" %04X", cc->is[i]);
1339 logmsg(", GR%02d=" F_VADR ", GR%02d=" F_GREG "\n", cc->r1, cc->iregs->GR(cc->r1), cc->r1 + 1, cc->iregs->GR(cc->r1 + 1));
1340 #endif /* #ifdef OPTION_CMPSC_DEBUG */
1341
1342 }
1343
1344 /*----------------------------------------------------------------------------*/
1345 /* cmpsc_test_ec (extension characters) */
1346 /*----------------------------------------------------------------------------*/
ARCH_DEP(cmpsc_test_ec)1347 static int ARCH_DEP(cmpsc_test_ec)(struct cc *cc, BYTE *cce)
1348 {
1349 BYTE buf[4]; /* Cross page buffer */
1350 BYTE *src; /* Source pointer */
1351
1352 /* No dead end */
1353 cc->deadend = 0;
1354
1355 /* Get address of source */
1356 if(likely(cc->srclen > (unsigned) CCE_ecs(cce)))
1357 {
1358 src = &cc->src[1];
1359 ITIMER_SYNC((GR_A(cc->r2, cc->iregs) + 1) & ADDRESS_MAXWRAP(cc->regs), CCE_ecs(cce) - 1, cc->regs);
1360 }
1361 else
1362 {
1363 /* Return nomatch on end of source condition */
1364 if(unlikely(GR_A(cc->r2 + 1, cc->iregs) <= (unsigned) CCE_ecs(cce)))
1365 return(1);
1366
1367 /* Get the cross page data */
1368 ARCH_DEP(vfetchc)(buf, CCE_ecs(cce) - 1, (GR_A(cc->r2, cc->iregs) + 1) & ADDRESS_MAXWRAP(cc->regs), cc->r2, cc->regs);
1369 src = buf;
1370 }
1371
1372 /* Compare additional extension characters */
1373 if(!memcmp(src, &CCE_ec(cce, 0), CCE_ecs(cce)))
1374 {
1375 /* Check for reading character 261 */
1376 cc->cr += CCE_ecs(cce);
1377 if(unlikely(cc->cr > 260))
1378 {
1379
1380 #ifdef OPTION_CMPSC_DEBUG
1381 logmsg("Trying to read character #%d\n", cc->cr);
1382 #endif /* #ifdef OPTION_CMSPC_DEBUG */
1383
1384 cc->regs->dxc = DXC_DECIMAL;
1385 ARCH_DEP(program_interrupt)(cc->regs, PGM_DATA_EXCEPTION);
1386 }
1387 return(0);
1388 }
1389 else
1390 return(1);
1391 }
1392
1393 /*============================================================================*/
1394 /* Expand */
1395 /*============================================================================*/
1396
1397 /*----------------------------------------------------------------------------*/
1398 /* Expansion Character Entry macro's (ECE) */
1399 /*----------------------------------------------------------------------------*/
1400 /* bit34 : indication of bits 3 and 4 (what else ;-) */
1401 /* csl : complete symbol length */
1402 /* ofst : offset from current position in output area */
1403 /* pptr : predecessor pointer */
1404 /* psl : partial symbol length */
1405 /*----------------------------------------------------------------------------*/
1406 #define ECE_bit34(ece) ((ece)[0] & 0x18)
1407 #define ECE_csl(ece) ((ece)[0] & 0x07)
1408 #define ECE_ofst(ece) ((ece)[7])
1409 #define ECE_pptr(ece) ((((ece)[0] & 0x1f) << 8) | (ece)[1])
1410 #define ECE_psl(ece) ((ece)[0] >> 5)
1411
1412 /*----------------------------------------------------------------------------*/
1413 /* cmpsc_expand */
1414 /*----------------------------------------------------------------------------*/
ARCH_DEP(cmpsc_expand)1415 static void ARCH_DEP(cmpsc_expand)(int r1, int r2, REGS *regs, REGS *iregs)
1416 {
1417 GREG destlen; /* Destination length */
1418 struct ec ec; /* Expand cache */
1419 int i; /* Index */
1420 U16 iss[8] = {0}; /* Index symbols */
1421
1422 /* Initialize values */
1423 destlen = GR_A(r1 + 1, iregs);
1424
1425 /* Initialize expansion context */
1426 ec.dest = NULL;
1427 ec.dictor = GR1_dictor(iregs);
1428 memset(ec.dict, 0, sizeof(ec.dict));
1429
1430 /* Initialize expanded index symbol cache and prefill with alphabet entries */
1431 memset(ec.ecl, 0, sizeof(ec.ecl));
1432 for(i = 0; i < 256; i++) /* Alphabet entries */
1433 {
1434 ec.ec[i] = i;
1435 ec.eci[i] = i;
1436 ec.ecl[i] = 1;
1437 }
1438 ec.ecwm = 256; /* Set watermark after alphabet part */
1439
1440 ec.iregs = iregs;
1441 ec.r1 = r1;
1442 ec.r2 = r2;
1443 ec.regs = regs;
1444 ec.smbsz = GR0_smbsz(regs);
1445 ec.src = NULL;
1446
1447 #ifdef OPTION_CMPSC_DEBUG
1448 ec.dbgac = 0;
1449 ec.dbgbi = 0;
1450 ec.dbgbo = 0;
1451 ec.dbgch = 0;
1452 ec.dbgiss = 0;
1453 #endif /* #ifdef OPTION_CMPSC_DEBUG */
1454
1455 /*--------------------------------------------------------------------------*/
1456 /* Process individual index symbols until cbn becomes zero */
1457 while(unlikely(GR1_cbn(ec.iregs)))
1458 {
1459 if(unlikely(ARCH_DEP(cmpsc_expand_single_is)(&ec)))
1460 return;
1461 }
1462
1463 /*--------------------------------------------------------------------------*/
1464 /* Block processing, cbn stays zero */
1465 while(likely(GR_A(ec.r2 + 1, ec.iregs) >= ec.smbsz))
1466 {
1467 ARCH_DEP(cmpsc_fetch_iss)(&ec, iss);
1468 ec.ocl = 0; /* Initialize output cache */
1469 for(i = 0; i < 8; i++)
1470 {
1471
1472 #ifdef OPTION_CMPSC_DEBUG
1473 logmsg("expand : is %04X (%d)\n", iss[i], i);
1474 ec.dbgiss++;
1475 #endif /* #ifdef OPTION_CMPSC_DEBUG */
1476
1477 if(unlikely(!ec.ecl[iss[i]]))
1478 ARCH_DEP(cmpsc_expand_is)(&ec, iss[i]);
1479 else
1480 {
1481 memcpy(&ec.oc[ec.ocl], &ec.ec[ec.eci[iss[i]]], ec.ecl[iss[i]]);
1482 ec.ocl += ec.ecl[iss[i]];
1483
1484 #ifdef OPTION_CMPSC_DEBUG
1485 if(iss[i] < 0x100)
1486 ec.dbgac++;
1487 else
1488 ec.dbgch++;
1489 #endif /* #ifdef OPTION_CMPSC_DEBUG */
1490
1491 }
1492 }
1493
1494 #ifdef OPTION_CMPSC_DEBUG
1495 ec.dbgbi += ec.smbsz;
1496 ec.dbgbo += ec.ocl;
1497 logmsg("Stats: iss %6u; ach %6u: %3d%; hts %6u: %3d%; bin %6u, out %6u: %6d%\n", ec.dbgiss, ec.dbgac, ec.dbgac * 100 / ec.dbgiss, ec.dbgch, ec.dbgch * 100 / ec.dbgiss, ec.dbgbi, ec.dbgbo, ec.dbgbo * 100 / ec.dbgbi);
1498 #endif /* #ifdef OPTION_CMPSC_DEBUG */
1499
1500 /* Write and commit, cbn unchanged, so no commit for GR1 needed */
1501 if(unlikely(ARCH_DEP(cmpsc_vstore)(&ec, ec.oc, ec.ocl)))
1502 return;
1503
1504 /* Commit registers */
1505 COMMITREGS2(ec.regs, ec.iregs, ec.r1, ec.r2);
1506
1507 /* Return with cc3 on interrupt pending */
1508 if(unlikely(destlen - GR_A(ec.r1 + 1, ec.iregs) >= MINPROC_SIZE && INTERRUPT_PENDING(ec.regs)))
1509 {
1510
1511 #ifdef OPTION_CMPSC_DEBUG
1512 logmsg("Interrupt pending, commit and return with cc3\n");
1513 #endif /* #ifdef OPTION_CMPSC_DEBUG */
1514
1515 ec.regs->psw.cc = 3;
1516 return;
1517 }
1518 }
1519
1520 /*--------------------------------------------------------------------------*/
1521 /* Process individual index symbols until end of source (or destination) */
1522 while(likely(!ARCH_DEP(cmpsc_expand_single_is)(&ec)));
1523 }
1524
1525 /*----------------------------------------------------------------------------*/
1526 /* cmpsc_expand_is (index symbol) */
1527 /*----------------------------------------------------------------------------*/
ARCH_DEP(cmpsc_expand_is)1528 static void ARCH_DEP(cmpsc_expand_is)(struct ec *ec, U16 is)
1529 {
1530 int csl; /* Complete symbol length */
1531 unsigned cw; /* Characters written */
1532 BYTE *ece; /* Expansion Character Entry */
1533 U16 index; /* Index within dictionary */
1534 int psl; /* Partial symbol length */
1535
1536 /* Initialize values */
1537 cw = 0;
1538
1539 /* Get expansion character entry */
1540 index = is * 8;
1541 if(unlikely(!ec->dict[index / 0x800]))
1542 ec->dict[index / 0x800] = MADDR((ec->dictor + (index / 0x800) * 0x800) & ADDRESS_MAXWRAP(ec->regs), ec->r2, ec->regs, ACCTYPE_READ, ec->regs->psw.pkey);
1543 ece = &ec->dict[index / 0x800][index % 0x800];
1544 ITIMER_SYNC((ec->dictor + index) & ADDRESS_MAXWRAP(ec->regs), 8 - 1, ec->regs);
1545
1546 #ifdef OPTION_CMPSC_DEBUG
1547 logmsg("fetch_ece: index %04X\n", is);
1548 cmpsc_print_ece(ece);
1549 #endif /* #ifdef OPTION_CMPSC_DEBUG */
1550
1551 /* Process preceded entries */
1552 psl = ECE_psl(ece);
1553 while(likely(psl))
1554 {
1555 /* Count and check for writing child 261 and check valid psl */
1556 cw += psl;
1557 if(unlikely(cw > 260 || psl > 5))
1558 {
1559
1560 #ifdef OPTION_CMPSC_DEBUG
1561 if(cw > 260)
1562 logmsg("Trying to write character #%d\n", cw);
1563 #endif /* #ifdef OPTION_CMPSC_DEBUG */
1564
1565 ec->regs->dxc = DXC_DECIMAL;
1566 ARCH_DEP(program_interrupt)((ec->regs), PGM_DATA_EXCEPTION);
1567 }
1568
1569 /* Process extension characters in preceded entry */
1570 memcpy(&ec->oc[ec->ocl + ECE_ofst(ece)], &ece[2], psl);
1571
1572 /* Get preceding entry */
1573 index = ECE_pptr(ece) * 8;
1574 if(unlikely(!ec->dict[index / 0x800]))
1575 ec->dict[index / 0x800] = MADDR((ec->dictor + (index / 0x800) * 0x800) & ADDRESS_MAXWRAP(ec->regs), ec->r2, ec->regs, ACCTYPE_READ, ec->regs->psw.pkey);
1576 ece = &ec->dict[index / 0x800][index % 0x800];
1577 ITIMER_SYNC((ec->dictor + index) & ADDRESS_MAXWRAP(ec->regs), 8 - 1, ec->regs);
1578
1579 #ifdef OPTION_CMPSC_DEBUG
1580 logmsg("fetch_ece: index %04X\n", index / 8);
1581 cmpsc_print_ece(ece);
1582 #endif /* #ifdef OPTION_CMPSC_DEBUG */
1583
1584 /* Calculate partial symbol length */
1585 psl = ECE_psl(ece);
1586 }
1587
1588 /* Count and check for writing child 261, valid csl and invalid bits */
1589 csl = ECE_csl(ece);
1590 cw += csl;
1591 if(unlikely(cw > 260 || !csl || ECE_bit34(ece)))
1592 {
1593
1594 #ifdef OPTION_CMPSC_DEBUG
1595 if(cw > 260)
1596 logmsg("Trying to write character #%d\n", cw);
1597 #endif /* #ifdef OPTION_CMPSC_DEBUG */
1598
1599 ec->regs->dxc = DXC_DECIMAL;
1600 ARCH_DEP(program_interrupt)((ec->regs), PGM_DATA_EXCEPTION);
1601 }
1602
1603 /* Process extension characters in unpreceded entry */
1604 memcpy(&ec->oc[ec->ocl], &ece[1], csl);
1605
1606 /* Place within cache */
1607 memcpy(&ec->ec[ec->ecwm], &ec->oc[ec->ocl], cw);
1608 ec->eci[is] = ec->ecwm;
1609 ec->ecl[is] = cw;
1610 ec->ecwm += cw;
1611
1612 /* Commit in output buffer */
1613 ec->ocl += cw;
1614 }
1615
1616 /*----------------------------------------------------------------------------*/
1617 /* cmpsc_expand_single_is (index symbol) */
1618 /*----------------------------------------------------------------------------*/
ARCH_DEP(cmpsc_expand_single_is)1619 static int ARCH_DEP(cmpsc_expand_single_is)(struct ec *ec)
1620 {
1621 U16 is; /* Index symbol */
1622
1623 if(unlikely(ARCH_DEP(cmpsc_fetch_is)(ec, &is)))
1624 return(-1);
1625 if(!ec->ecl[is])
1626 {
1627 ec->ocl = 0; /* Initialize output cache */
1628 ARCH_DEP(cmpsc_expand_is)(ec, is);
1629 if(unlikely(ARCH_DEP(cmpsc_vstore)(ec, ec->oc, ec->ocl)))
1630 return(-1);
1631 }
1632 else
1633 {
1634 if(unlikely(ARCH_DEP(cmpsc_vstore)(ec, &ec->ec[ec->eci[is]], ec->ecl[is])))
1635 return(-1);
1636 }
1637
1638 /* Commit, including GR1 */
1639 COMMITREGS(ec->regs, ec->iregs, ec->r1, ec->r2);
1640 return(0);
1641 }
1642
1643 /*----------------------------------------------------------------------------*/
1644 /* cmpsc_fetch_is (index symbol) */
1645 /*----------------------------------------------------------------------------*/
ARCH_DEP(cmpsc_fetch_is)1646 static int ARCH_DEP(cmpsc_fetch_is)(struct ec *ec, U16 *is)
1647 {
1648 unsigned cbn; /* Compressed-data bit number */
1649 U32 mask; /* Working mask */
1650 BYTE work[3]; /* Working field */
1651
1652 /* Initialize values */
1653 cbn = GR1_cbn(ec->iregs);
1654
1655 /* Check if we can read an index symbol */
1656 if(unlikely(GR_A(ec->r2 + 1, ec->iregs) < 3 && ((cbn + ec->smbsz - 1) / 8) >= GR_A(ec->r2 + 1, ec->iregs)))
1657 {
1658
1659 #ifdef OPTION_CMPSC_DEBUG
1660 logmsg("fetch_is : reached end of source\n");
1661 #endif /* #ifdef OPTION_CMPSC_DEBUG */
1662
1663 ec->regs->psw.cc = 0;
1664 return(-1);
1665 }
1666
1667 /* Clear possible fetched 3rd byte */
1668 work[2] = 0;
1669 ARCH_DEP(vfetchc)(&work, (ec->smbsz + cbn - 1) / 8, GR_A(ec->r2, ec->iregs) & ADDRESS_MAXWRAP(ec->regs), ec->r2, ec->regs);
1670
1671 /* Get the bits */
1672 mask = work[0] << 16 | work[1] << 8 | work[2];
1673 mask >>= (24 - ec->smbsz - cbn);
1674 mask &= 0xFFFF >> (16 - ec->smbsz);
1675 *is = mask;
1676
1677 /* Adjust source registers */
1678 ADJUSTREGS(ec->r2, ec->regs, ec->iregs, (cbn + ec->smbsz) / 8);
1679
1680 /* Calculate and set the new compressed-data bit number */
1681 GR1_setcbn(ec->iregs, (cbn + ec->smbsz) % 8);
1682
1683 #ifdef OPTION_CMPSC_DEBUG
1684 logmsg("fetch_is : %04X, cbn=%d, GR%02d=" F_VADR ", GR%02d=" F_GREG "\n", *is, GR1_cbn(ec->iregs), ec->r2, ec->iregs->GR(ec->r2), ec->r2 + 1, ec->iregs->GR(ec->r2 + 1));
1685 #endif /* #ifdef OPTION_CMPSC_DEBUG */
1686
1687 return(0);
1688 }
1689
1690 /*----------------------------------------------------------------------------*/
1691 /* cmpsc_fetch_iss */
1692 /*----------------------------------------------------------------------------*/
ARCH_DEP(cmpsc_fetch_iss)1693 static void ARCH_DEP(cmpsc_fetch_iss)(struct ec *ec, U16 is[8])
1694 {
1695 BYTE buf[13]; /* Buffer for Index Symbols */
1696
1697 #ifdef OPTION_CMPSC_DEBUG
1698 int i;
1699 #endif /* #ifdef OPTION_CMPSC_DEBUG */
1700
1701 unsigned len1; /* Lenght in first page */
1702 BYTE *mem; /* Pointer to maddr or buf */
1703 unsigned ofst; /* Offset in first page */
1704
1705 /* Fingers crossed that we stay within one page */
1706 ofst = GR_A(ec->r2, ec->iregs) & 0x7ff;
1707 if(unlikely(!ec->src))
1708 ec->src = MADDR((GR_A(ec->r2, ec->iregs) & ~0x7ff) & ADDRESS_MAXWRAP(ec->regs), ec->r2, ec->regs, ACCTYPE_READ, ec->regs->psw.pkey);
1709 if(likely(ofst + ec->smbsz <= 0x800))
1710 {
1711 ITIMER_SYNC(GR_A(ec->r2, ec->iregs) & ADDRESS_MAXWRAP(ec->regs), ec->smbsz - 1, ec->regs);
1712 mem = &ec->src[ofst];
1713
1714 /* Perfect fit? */
1715 if(unlikely(ofst + ec->smbsz == 0x800))
1716 ec->src = NULL;
1717 }
1718 else
1719 {
1720 /* We need data spread over 2 pages */
1721 len1 = 0x800 - ofst;
1722 memcpy(buf, &ec->src[ofst], len1);
1723 ec->src = MADDR((GR_A(ec->r2, ec->iregs) + len1) & ADDRESS_MAXWRAP(ec->regs), ec->r2, ec->regs, ACCTYPE_READ, ec->regs->psw.pkey);
1724 memcpy(&buf[len1], ec->src, ec->smbsz - len1);
1725 mem = buf;
1726 }
1727
1728 /* Calculate the 8 index symbols */
1729 switch(ec->smbsz)
1730 {
1731 case 9: /* 9-bits */
1732 {
1733 /* 0 1 2 3 4 5 6 7 8 */
1734 /* 012345670123456701234567012345670123456701234567012345670123456701234567 */
1735 /* 012345678012345678012345678012345678012345678012345678012345678012345678 */
1736 /* 0 1 2 3 4 5 6 7 */
1737 is[0] = ((mem[0] << 1) | (mem[1] >> 7));
1738 is[1] = ((mem[1] << 2) | (mem[2] >> 6)) & 0x01ff;
1739 is[2] = ((mem[2] << 3) | (mem[3] >> 5)) & 0x01ff;
1740 is[3] = ((mem[3] << 4) | (mem[4] >> 4)) & 0x01ff;
1741 is[4] = ((mem[4] << 5) | (mem[5] >> 3)) & 0x01ff;
1742 is[5] = ((mem[5] << 6) | (mem[6] >> 2)) & 0x01ff;
1743 is[6] = ((mem[6] << 7) | (mem[7] >> 1)) & 0x01ff;
1744 is[7] = ((mem[7] << 8) | (mem[8] )) & 0x01ff;
1745 break;
1746 }
1747 case 10: /* 10-bits */
1748 {
1749 /* 0 1 2 3 4 5 6 7 8 9 */
1750 /* 01234567012345670123456701234567012345670123456701234567012345670123456701234567 */
1751 /* 01234567890123456789012345678901234567890123456789012345678901234567890123456789 */
1752 /* 0 1 2 3 4 5 6 7 */
1753 is[0] = ((mem[0] << 2) | (mem[1] >> 6));
1754 is[1] = ((mem[1] << 4) | (mem[2] >> 4)) & 0x03ff;
1755 is[2] = ((mem[2] << 6) | (mem[3] >> 2)) & 0x03ff;
1756 is[3] = ((mem[3] << 8) | (mem[4] )) & 0x03ff;
1757 is[4] = ((mem[5] << 2) | (mem[6] >> 6));
1758 is[5] = ((mem[6] << 4) | (mem[7] >> 4)) & 0x03ff;
1759 is[6] = ((mem[7] << 6) | (mem[8] >> 2)) & 0x03ff;
1760 is[7] = ((mem[8] << 8) | (mem[9] )) & 0x03ff;
1761 break;
1762 }
1763 case 11: /* 11-bits */
1764 {
1765 /* 0 1 2 3 4 5 6 7 8 9 a */
1766 /* 0123456701234567012345670123456701234567012345670123456701234567012345670123456701234567 */
1767 /* 0123456789a0123456789a0123456789a0123456789a0123456789a0123456789a0123456789a0123456789a */
1768 /* 0 1 2 3 4 5 6 7 */
1769 is[0] = ((mem[0] << 3) | (mem[ 1] >> 5) );
1770 is[1] = ((mem[1] << 6) | (mem[ 2] >> 2) ) & 0x07ff;
1771 is[2] = ((mem[2] << 9) | (mem[ 3] << 1) | (mem[4] >> 7)) & 0x07ff;
1772 is[3] = ((mem[4] << 4) | (mem[ 5] >> 4) ) & 0x07ff;
1773 is[4] = ((mem[5] << 7) | (mem[ 6] >> 1) ) & 0x07ff;
1774 is[5] = ((mem[6] << 10) | (mem[ 7] << 2) | (mem[8] >> 6)) & 0x07ff;
1775 is[6] = ((mem[8] << 5) | (mem[ 9] >> 3) ) & 0x07ff;
1776 is[7] = ((mem[9] << 8) | (mem[10] ) ) & 0x07ff;
1777 break;
1778 }
1779 case 12: /* 12-bits */
1780 {
1781 /* 0 1 2 3 4 5 6 7 8 9 a b */
1782 /* 012345670123456701234567012345670123456701234567012345670123456701234567012345670123456701234567 */
1783 /* 0123456789ab0123456789ab0123456789ab0123456789ab0123456789ab0123456789ab0123456789ab0123456789ab */
1784 /* 0 1 2 3 4 5 6 7 */
1785 is[0] = ((mem[ 0] << 4) | (mem[ 1] >> 4));
1786 is[1] = ((mem[ 1] << 8) | (mem[ 2] )) & 0x0fff;
1787 is[2] = ((mem[ 3] << 4) | (mem[ 4] >> 4));
1788 is[3] = ((mem[ 4] << 8) | (mem[ 5] )) & 0x0fff;
1789 is[4] = ((mem[ 6] << 4) | (mem[ 7] >> 4));
1790 is[5] = ((mem[ 7] << 8) | (mem[ 8] )) & 0x0fff;
1791 is[6] = ((mem[ 9] << 4) | (mem[10] >> 4));
1792 is[7] = ((mem[10] << 8) | (mem[11] )) & 0x0fff;
1793 break;
1794 }
1795 case 13: /* 13-bits */
1796 {
1797 /* 0 1 2 3 4 5 6 7 8 9 a b c */
1798 /* 01234567012345670123456701234567012345670123456701234567012345670123456701234567012345670123456701234567 */
1799 /* 0123456789abc0123456789abc0123456789abc0123456789abc0123456789abc0123456789abc0123456789abc0123456789abc */
1800 /* 0 1 2 3 4 5 6 7 */
1801 is[0] = ((mem[ 0] << 5) | (mem[ 1] >> 3) );
1802 is[1] = ((mem[ 1] << 10) | (mem[ 2] << 2) | (mem[ 3] >> 6)) & 0x1fff;
1803 is[2] = ((mem[ 3] << 7) | (mem[ 4] >> 1) ) & 0x1fff;
1804 is[3] = ((mem[ 4] << 12) | (mem[ 5] << 4) | (mem[ 6] >> 4)) & 0x1fff;
1805 is[4] = ((mem[ 6] << 9) | (mem[ 7] << 1) | (mem[ 8] >> 7)) & 0x1fff;
1806 is[5] = ((mem[ 8] << 6) | (mem[ 9] >> 2) ) & 0x1fff;
1807 is[6] = ((mem[ 9] << 11) | (mem[10] << 3) | (mem[11] >> 5)) & 0x1fff;
1808 is[7] = ((mem[11] << 8) | (mem[12] ) ) & 0x1fff;
1809 break;
1810 }
1811 }
1812
1813 /* Adjust source registers */
1814 ADJUSTREGS(ec->r2, ec->regs, ec->iregs, ec->smbsz);
1815
1816 #ifdef OPTION_CMPSC_DEBUG
1817 logmsg("fetch_iss:");
1818 for(i = 0; i < 8; i++)
1819 logmsg(" %04X", is[i]);
1820 logmsg(", GR%02d=" F_VADR ", GR%02d=" F_GREG "\n", ec->r2, ec->iregs->GR(ec->r2), ec->r2 + 1, ec->iregs->GR(ec->r2 + 1));
1821 #endif /* #ifdef OPTION_CMPSC_DEBUG */
1822 }
1823
1824 #ifndef NO_2ND_COMPILE
1825 #ifdef OPTION_CMPSC_DEBUG
1826 /*----------------------------------------------------------------------------*/
1827 /* cmpsc_print_ece (expansion character entry) */
1828 /*----------------------------------------------------------------------------*/
cmpsc_print_ece(BYTE * ece)1829 static void cmpsc_print_ece(BYTE *ece)
1830 {
1831 int i; /* Index */
1832 int prt_detail; /* Switch detailed printing */
1833
1834 logmsg(" ece : ");
1835 prt_detail = 0;
1836 for(i = 0; i < 8; i++)
1837 {
1838 if(!prt_detail && ece[i])
1839 prt_detail = 1;
1840 logmsg("%02X", ece[i]);
1841 }
1842 logmsg("\n");
1843 if(prt_detail)
1844 {
1845 if(ECE_psl(ece))
1846 {
1847 logmsg(" psl : %d\n", ECE_psl(ece));
1848 logmsg(" pptr : %04X\n", ECE_pptr(ece));
1849 logmsg(" ecs :");
1850 for(i = 0; i < ECE_psl(ece); i++)
1851 logmsg(" %02X", ece[i + 2]);
1852 logmsg("\n");
1853 logmsg(" ofst : %02X\n", ECE_ofst(ece));
1854 }
1855 else
1856 {
1857 logmsg(" psl : %d\n", ECE_psl(ece));
1858 logmsg(" bit34 : %s\n", TRUEFALSE(ECE_bit34(ece)));
1859 logmsg(" csl : %d\n", ECE_csl(ece));
1860 logmsg(" ecs :");
1861 for(i = 0; i < ECE_csl(ece); i++)
1862 logmsg(" %02X", ece[i + 1]);
1863 logmsg("\n");
1864 }
1865 }
1866 }
1867 #endif /* #ifdef OPTION_CMPSC_DEBUG */
1868 #endif /* #ifndef NO_2ND_COMPILE */
1869
1870 /*----------------------------------------------------------------------------*/
1871 /* cmpsc_vstore */
1872 /*----------------------------------------------------------------------------*/
ARCH_DEP(cmpsc_vstore)1873 static int ARCH_DEP(cmpsc_vstore)(struct ec *ec, BYTE *buf, unsigned len)
1874 {
1875 unsigned len1; /* Length in first page */
1876 unsigned len2; /* Length in second page */
1877 BYTE *main1; /* Address first page */
1878 unsigned ofst; /* Offset within page */
1879 BYTE *sk; /* Storage key */
1880
1881 #ifdef OPTION_CMPSC_DEBUG
1882 unsigned i; /* Index */
1883 unsigned j; /* Index */
1884 static BYTE pbuf[2060]; /* Print buffer */
1885 static unsigned plen = 2061; /* Impossible value */
1886 #endif /* #ifdef OPTION_CMPSC_DEBUG */
1887
1888 /* Check destination size */
1889 if(unlikely(GR_A(ec->r1 + 1, ec->iregs) < len))
1890 {
1891
1892 #ifdef OPTION_CMPSC_DEBUG
1893 logmsg("vstore : Reached end of destination\n");
1894 #endif /* #ifdef OPTION_CMPSC_DEBUG */
1895
1896 /* Indicate end of destination */
1897 ec->regs->psw.cc = 1;
1898 return(-1);
1899 }
1900
1901 #ifdef OPTION_CMPSC_DEBUG
1902 if(plen == len && !memcmp(pbuf, buf, plen))
1903 logmsg(F_GREG " - " F_GREG " Same buffer as previously shown\n", ec->iregs->GR(ec->r1), ec->iregs->GR(ec->r1) + len - 1);
1904 else
1905 {
1906 for(i = 0; i < len; i += 32)
1907 {
1908 logmsg(F_GREG, ec->iregs->GR(ec->r1) + i);
1909 if(i && i + 32 < len && !memcmp(&buf[i], &buf[i - 32], 32))
1910 {
1911 for(j = i + 32; j + 32 < len && !memcmp(&buf[j], &buf[j - 32], 32); j += 32);
1912 if(j > 32)
1913 {
1914 logmsg(": Same line as above\n" F_GREG, ec->iregs->GR(ec->r1) + j);
1915 i = j;
1916 }
1917 }
1918 logmsg(": ");
1919 for(j = 0; j < 32; j++)
1920 {
1921 if(!(j % 8))
1922 logmsg(" ");
1923 if(i + j >= len)
1924 logmsg(" ");
1925 else
1926 logmsg("%02X", buf[i + j]);
1927 }
1928 logmsg(" | ");
1929 for(j = 0; j < 32; j++)
1930 {
1931 if(i + j >= len)
1932 logmsg(" ");
1933 else
1934 {
1935 if(isprint(guest_to_host(buf[i + j])))
1936 logmsg("%c", guest_to_host(buf[i + j]));
1937 else
1938 logmsg(".");
1939 }
1940 }
1941 logmsg(" |\n");
1942 }
1943 memcpy(pbuf, buf, len);
1944 plen = len;
1945 }
1946 #endif /* #ifdef OPTION_CMPSC_DEBUG */
1947
1948 /* Fingers crossed that we stay within one page */
1949 ofst = GR_A(ec->r1, ec->iregs) & 0x7ff;
1950 if(likely(ofst + len <= 0x800))
1951 {
1952 if(unlikely(!ec->dest))
1953 ec->dest = MADDR((GR_A(ec->r1, ec->iregs) & ~0x7ff) & ADDRESS_MAXWRAP(ec->regs), ec->r1, ec->regs, ACCTYPE_WRITE, ec->regs->psw.pkey);
1954 memcpy(&ec->dest[ofst], buf, len);
1955 ITIMER_UPDATE(GR_A(ec->r1, ec->iregs) & ADDRESS_MAXWRAP(ec->regs), len - 1, ec->regs);
1956
1957 /* Perfect fit? */
1958 if(unlikely(ofst + len == 0x800))
1959 ec->dest = NULL;
1960 }
1961 else
1962 {
1963 /* We need multiple pages */
1964 if(unlikely(!ec->dest))
1965 main1 = MADDR((GR_A(ec->r1, ec->iregs) & ~0x7ff) & ADDRESS_MAXWRAP(ec->regs), ec->r1, ec->regs, ACCTYPE_WRITE_SKP, ec->regs->psw.pkey);
1966 else
1967 main1 = ec->dest;
1968 sk = ec->regs->dat.storkey;
1969 len1 = 0x800 - ofst;
1970 ec->dest = MADDR((GR_A(ec->r1, ec->iregs) + len1) & ADDRESS_MAXWRAP(ec->regs), ec->r1, ec->regs, ACCTYPE_WRITE, ec->regs->psw.pkey);
1971 memcpy(&main1[ofst], buf, len1);
1972 len2 = len - len1; /* We always start with a len2 */
1973 do
1974 {
1975 memcpy(ec->dest, &buf[len1], (len2 > 0x800 ? 0x800 : len2));
1976 *sk |= (STORKEY_REF | STORKEY_CHANGE);
1977 if(unlikely(len2 >= 0x800))
1978 {
1979 len1 += 0x800;
1980 len2 -= 0x800;
1981
1982 /* Perfect fit? */
1983 if(unlikely(!len2))
1984 ec->dest = NULL;
1985 else
1986 ec->dest = MADDR((GR_A(ec->r1, ec->iregs) + len1) & ADDRESS_MAXWRAP(ec->regs), ec->r1, ec->regs, ACCTYPE_WRITE, ec->regs->psw.pkey);
1987 sk = ec->regs->dat.storkey;
1988 }
1989 else
1990 len2 = 0;
1991 }
1992 while(len2);
1993 }
1994
1995 ADJUSTREGS(ec->r1, ec->regs, ec->iregs, len);
1996 return(0);
1997 }
1998
1999 #define NO_2ND_COMPILE
2000 #endif /* FEATURE_COMPRESSION */
2001
2002 #ifndef _GEN_ARCH
2003 #ifdef _ARCHMODE2
2004 #define _GEN_ARCH _ARCHMODE2
2005 #include "cmpsc.c"
2006 #endif /* #ifdef _ARCHMODE2 */
2007 #ifdef _ARCHMODE3
2008 #undef _GEN_ARCH
2009 #define _GEN_ARCH _ARCHMODE3
2010 #include "cmpsc.c"
2011 #endif /* #ifdef _ARCHMODE3 */
2012 #endif /* #ifndef _GEN_ARCH */
2013