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