1/* -*- mode: C; c-basic-offset: 3; -*- */
2
3/*---------------------------------------------------------------*/
4/*--- begin                              guest_s390_helpers.c ---*/
5/*---------------------------------------------------------------*/
6
7/*
8   This file is part of Valgrind, a dynamic binary instrumentation
9   framework.
10
11   Copyright IBM Corp. 2010-2012
12
13   This program is free software; you can redistribute it and/or
14   modify it under the terms of the GNU General Public License as
15   published by the Free Software Foundation; either version 2 of the
16   License, or (at your option) any later version.
17
18   This program is distributed in the hope that it will be useful, but
19   WITHOUT ANY WARRANTY; without even the implied warranty of
20   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
21   General Public License for more details.
22
23   You should have received a copy of the GNU General Public License
24   along with this program; if not, write to the Free Software
25   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
26   02110-1301, USA.
27
28   The GNU General Public License is contained in the file COPYING.
29*/
30
31/* Contributed by Florian Krohm */
32
33#include "libvex_basictypes.h"
34#include "libvex_emwarn.h"
35#include "libvex_guest_s390x.h"
36#include "libvex_ir.h"
37#include "libvex.h"
38#include "libvex_s390x_common.h"
39
40#include "main_util.h"
41#include "guest_generic_bb_to_IR.h"
42#include "guest_s390_defs.h"
43
44void
45LibVEX_GuestS390X_initialise(VexGuestS390XState *state)
46{
47/*------------------------------------------------------------*/
48/*--- Initialise ar registers                              ---*/
49/*------------------------------------------------------------*/
50
51   state->guest_a0 = 0;
52   state->guest_a1 = 0;
53   state->guest_a2 = 0;
54   state->guest_a3 = 0;
55   state->guest_a4 = 0;
56   state->guest_a5 = 0;
57   state->guest_a6 = 0;
58   state->guest_a7 = 0;
59   state->guest_a8 = 0;
60   state->guest_a9 = 0;
61   state->guest_a10 = 0;
62   state->guest_a11 = 0;
63   state->guest_a12 = 0;
64   state->guest_a13 = 0;
65   state->guest_a14 = 0;
66   state->guest_a15 = 0;
67
68/*------------------------------------------------------------*/
69/*--- Initialise fpr registers                             ---*/
70/*------------------------------------------------------------*/
71
72   state->guest_f0 = 0;
73   state->guest_f1 = 0;
74   state->guest_f2 = 0;
75   state->guest_f3 = 0;
76   state->guest_f4 = 0;
77   state->guest_f5 = 0;
78   state->guest_f6 = 0;
79   state->guest_f7 = 0;
80   state->guest_f8 = 0;
81   state->guest_f9 = 0;
82   state->guest_f10 = 0;
83   state->guest_f11 = 0;
84   state->guest_f12 = 0;
85   state->guest_f13 = 0;
86   state->guest_f14 = 0;
87   state->guest_f15 = 0;
88
89/*------------------------------------------------------------*/
90/*--- Initialise gpr registers                             ---*/
91/*------------------------------------------------------------*/
92
93   state->guest_r0 = 0;
94   state->guest_r1 = 0;
95   state->guest_r2 = 0;
96   state->guest_r3 = 0;
97   state->guest_r4 = 0;
98   state->guest_r5 = 0;
99   state->guest_r6 = 0;
100   state->guest_r7 = 0;
101   state->guest_r8 = 0;
102   state->guest_r9 = 0;
103   state->guest_r10 = 0;
104   state->guest_r11 = 0;
105   state->guest_r12 = 0;
106   state->guest_r13 = 0;
107   state->guest_r14 = 0;
108   state->guest_r15 = 0;
109
110/*------------------------------------------------------------*/
111/*--- Initialise S390 miscellaneous registers              ---*/
112/*------------------------------------------------------------*/
113
114   state->guest_counter = 0;
115   state->guest_fpc = 0;
116   state->guest_IA = 0;
117
118/*------------------------------------------------------------*/
119/*--- Initialise S390 pseudo registers                     ---*/
120/*------------------------------------------------------------*/
121
122   state->guest_SYSNO = 0;
123
124/*------------------------------------------------------------*/
125/*--- Initialise generic pseudo registers                  ---*/
126/*------------------------------------------------------------*/
127
128   state->guest_NRADDR = 0;
129   state->guest_TISTART = 0;
130   state->guest_TILEN = 0;
131   state->guest_IP_AT_SYSCALL = 0;
132   state->guest_EMWARN = EmWarn_NONE;
133   state->host_EvC_COUNTER = 0;
134   state->host_EvC_FAILADDR = 0;
135
136/*------------------------------------------------------------*/
137/*--- Initialise thunk                                     ---*/
138/*------------------------------------------------------------*/
139
140   state->guest_CC_OP = 0;
141   state->guest_CC_DEP1 = 0;
142   state->guest_CC_DEP2 = 0;
143   state->guest_CC_NDEP = 0;
144
145   __builtin_memset(state->padding, 0x0, sizeof(state->padding));
146}
147
148
149/* Figure out if any part of the guest state contained in minoff
150   .. maxoff requires precise memory exceptions.  If in doubt return
151   True (but this is generates significantly slower code).  */
152Bool
153guest_s390x_state_requires_precise_mem_exns(Int minoff, Int maxoff)
154{
155   Int lr_min = S390X_GUEST_OFFSET(guest_LR);
156   Int lr_max = lr_min + 8 - 1;
157   Int sp_min = S390X_GUEST_OFFSET(guest_SP);
158   Int sp_max = sp_min + 8 - 1;
159   Int fp_min = S390X_GUEST_OFFSET(guest_FP);
160   Int fp_max = fp_min + 8 - 1;
161   Int ia_min = S390X_GUEST_OFFSET(guest_IA);
162   Int ia_max = ia_min + 8 - 1;
163
164   if (maxoff < lr_min || minoff > lr_max) {
165      /* No overlap with LR */
166   } else {
167      return True;
168   }
169
170   if (maxoff < sp_min || minoff > sp_max) {
171      /* No overlap with SP */
172   } else {
173      return True;
174   }
175
176   if (maxoff < fp_min || minoff > fp_max) {
177      /* No overlap with FP */
178   } else {
179      return True;
180   }
181
182   if (maxoff < ia_min || minoff > ia_max) {
183      /* No overlap with IA */
184   } else {
185      return True;
186   }
187
188   return False;
189}
190
191
192#define ALWAYSDEFD(field)                             \
193    { S390X_GUEST_OFFSET(field),            \
194      (sizeof ((VexGuestS390XState*)0)->field) }
195
196VexGuestLayout s390xGuest_layout = {
197
198   /* Total size of the guest state, in bytes. */
199   .total_sizeB = sizeof(VexGuestS390XState),
200
201   /* Describe the stack pointer. */
202   .offset_SP = S390X_GUEST_OFFSET(guest_SP),
203   .sizeof_SP = 8,
204
205   /* Describe the frame pointer. */
206   .offset_FP = S390X_GUEST_OFFSET(guest_FP),
207   .sizeof_FP = 8,
208
209   /* Describe the instruction pointer. */
210   .offset_IP = S390X_GUEST_OFFSET(guest_IA),
211   .sizeof_IP = 8,
212
213   /* Describe any sections to be regarded by Memcheck as
214      'always-defined'. */
215   .n_alwaysDefd = 9,
216
217   /* Flags thunk: OP and NDEP are always defined, whereas DEP1
218      and DEP2 have to be tracked.  See detailed comment in
219      gdefs.h on meaning of thunk fields. */
220   .alwaysDefd = {
221      /*  0 */ ALWAYSDEFD(guest_CC_OP),     /* generic */
222      /*  1 */ ALWAYSDEFD(guest_CC_NDEP),   /* generic */
223      /*  2 */ ALWAYSDEFD(guest_EMWARN),    /* generic */
224      /*  3 */ ALWAYSDEFD(guest_TISTART),   /* generic */
225      /*  4 */ ALWAYSDEFD(guest_TILEN),     /* generic */
226      /*  5 */ ALWAYSDEFD(guest_IP_AT_SYSCALL), /* generic */
227      /*  6 */ ALWAYSDEFD(guest_IA),        /* control reg */
228      /*  7 */ ALWAYSDEFD(guest_fpc),       /* control reg */
229      /*  8 */ ALWAYSDEFD(guest_counter),   /* internal usage register */
230   }
231};
232
233/*------------------------------------------------------------*/
234/*--- Dirty helper for EXecute                             ---*/
235/*------------------------------------------------------------*/
236void
237s390x_dirtyhelper_EX(ULong torun)
238{
239   last_execute_target = torun;
240}
241
242
243/*------------------------------------------------------------*/
244/*--- Dirty helper for Clock instructions                  ---*/
245/*------------------------------------------------------------*/
246#if defined(VGA_s390x)
247ULong
248s390x_dirtyhelper_STCK(ULong *addr)
249{
250   int cc;
251
252   asm volatile("stck %0\n"
253                "ipm %1\n"
254                "srl %1,28\n"
255                : "+Q" (*addr), "=d" (cc) : : "cc");
256   return cc;
257}
258
259ULong
260s390x_dirtyhelper_STCKE(ULong *addr)
261{
262   int cc;
263
264   asm volatile("stcke %0\n"
265                "ipm %1\n"
266                "srl %1,28\n"
267                : "+Q" (*addr), "=d" (cc) : : "cc");
268   return cc;
269}
270
271ULong s390x_dirtyhelper_STCKF(ULong *addr)
272{
273   int cc;
274
275   asm volatile(".insn s,0xb27c0000,%0\n"
276                "ipm %1\n"
277                "srl %1,28\n"
278                : "+Q" (*addr), "=d" (cc) : : "cc");
279   return cc;
280}
281#else
282ULong s390x_dirtyhelper_STCK(ULong *addr)  {return 3;}
283ULong s390x_dirtyhelper_STCKF(ULong *addr) {return 3;}
284ULong s390x_dirtyhelper_STCKE(ULong *addr) {return 3;}
285#endif /* VGA_s390x */
286
287/*------------------------------------------------------------*/
288/*--- Dirty helper for Store Facility instruction          ---*/
289/*------------------------------------------------------------*/
290#if defined(VGA_s390x)
291ULong
292s390x_dirtyhelper_STFLE(VexGuestS390XState *guest_state, ULong *addr)
293{
294   ULong hoststfle[S390_NUM_FACILITY_DW], cc, num_dw, i;
295   register ULong reg0 asm("0") = guest_state->guest_r0 & 0xF;  /* r0[56:63] */
296
297   /* We cannot store more than S390_NUM_FACILITY_DW
298      (and it makes not much sense to do so anyhow) */
299   if (reg0 > S390_NUM_FACILITY_DW - 1)
300      reg0 = S390_NUM_FACILITY_DW - 1;
301
302   num_dw = reg0 + 1;  /* number of double words written */
303
304   asm volatile(" .insn s,0xb2b00000,%0\n"   /* stfle */
305                "ipm    %2\n"
306                "srl    %2,28\n"
307                : "=m" (hoststfle), "+d"(reg0), "=d"(cc) : : "cc", "memory");
308
309   /* Update guest register 0  with what STFLE set r0 to */
310   guest_state->guest_r0 = reg0;
311
312   for (i = 0; i < num_dw; ++i)
313      addr[i] = hoststfle[i];
314
315   return cc;
316}
317
318#else
319
320ULong
321s390x_dirtyhelper_STFLE(VexGuestS390XState *guest_state, ULong *addr)
322{
323   return 3;
324}
325#endif /* VGA_s390x */
326
327/*------------------------------------------------------------*/
328/*--- Dirty helper for the "convert unicode" insn family.  ---*/
329/*------------------------------------------------------------*/
330void
331s390x_dirtyhelper_CUxy(UChar *address, ULong data, ULong num_bytes)
332{
333   UInt i;
334
335   vassert(num_bytes >= 1 && num_bytes <= 4);
336
337   /* Store the least significant NUM_BYTES bytes in DATA left to right
338      at ADDRESS. */
339   for (i = 1; i <= num_bytes; ++i) {
340      address[num_bytes - i] = data & 0xff;
341      data >>= 8;
342   }
343}
344
345
346/*------------------------------------------------------------*/
347/*--- Clean helper for CU21.                               ---*/
348/*------------------------------------------------------------*/
349
350/* The function performs a CU21 operation. It returns three things
351   encoded in an ULong value:
352   - the converted bytes (at most 4)
353   - the number of converted bytes
354   - an indication whether LOW_SURROGATE, if any, is invalid
355
356   64      48                16           8                       0
357    +-------+-----------------+-----------+-----------------------+
358    |  0x0  | converted bytes | num_bytes | invalid_low_surrogate |
359    +-------+-----------------+-----------+-----------------------+
360*/
361ULong
362s390_do_cu21(UInt srcval, UInt low_surrogate)
363{
364   ULong retval = 0;   // shut up gcc
365   UInt b1, b2, b3, b4, num_bytes, invalid_low_surrogate = 0;
366
367   srcval &= 0xffff;
368
369   /* Determine the number of bytes in the converted value */
370   if (srcval <= 0x007f)
371      num_bytes = 1;
372   else if (srcval >= 0x0080 && srcval <= 0x07ff)
373      num_bytes = 2;
374   else if ((srcval >= 0x0800 && srcval <= 0xd7ff) ||
375            (srcval >= 0xdc00 && srcval <= 0xffff))
376      num_bytes = 3;
377   else
378      num_bytes = 4;
379
380   /* Determine UTF-8 bytes according to calculated num_bytes */
381   switch (num_bytes){
382   case 1:
383      retval = srcval;
384      break;
385
386   case 2:
387      /* order of bytes left to right: b1, b2 */
388      b1  = 0xc0;
389      b1 |= srcval >> 6;
390
391      b2  = 0x80;
392      b2 |= srcval & 0x3f;
393
394      retval = (b1 << 8) | b2;
395      break;
396
397   case 3:
398      /* order of bytes left to right: b1, b2, b3 */
399      b1  = 0xe0;
400      b1 |= srcval >> 12;
401
402      b2  = 0x80;
403      b2 |= (srcval >> 6) & 0x3f;
404
405      b3  = 0x80;
406      b3 |= srcval & 0x3f;
407
408      retval = (b1 << 16) | (b2 << 8) | b3;
409      break;
410
411   case 4: {
412      /* order of bytes left to right: b1, b2, b3, b4 */
413      UInt high_surrogate = srcval;
414      UInt uvwxy = ((high_surrogate >> 6) & 0xf) + 1;   // abcd + 1
415
416      b1  = 0xf0;
417      b1 |= uvwxy >> 2;     // uvw
418
419      b2  = 0x80;
420      b2 |= (uvwxy & 0x3) << 4;           // xy
421      b2 |= (high_surrogate >> 2) & 0xf;  // efgh
422
423      b3  = 0x80;
424      b3 |= (high_surrogate & 0x3) << 4;   // ij
425      b3 |= (low_surrogate >> 6) & 0xf;    // klmn
426
427      b4  = 0x80;
428      b4 |= low_surrogate & 0x3f;
429
430      retval = (b1 << 24) | (b2 << 16) | (b3 << 8) | b4;
431
432      invalid_low_surrogate = (low_surrogate & 0xfc00) != 0xdc00;
433      break;
434   }
435   }
436
437   /* At this point RETVAL contains the converted bytes.
438      Build up the final return value. */
439   return (retval << 16) | (num_bytes << 8) | invalid_low_surrogate;
440}
441
442
443/*------------------------------------------------------------*/
444/*--- Clean helper for CU24.                               ---*/
445/*------------------------------------------------------------*/
446
447/* The function performs a CU24 operation. It returns two things
448   encoded in an ULong value:
449   - the 4 converted bytes
450   - an indication whether LOW_SURROGATE, if any, is invalid
451
452   64     40                 8                       0
453    +------------------------+-----------------------+
454    |  0x0 | converted bytes | invalid_low_surrogate |
455    +------------------------+-----------------------+
456*/
457ULong
458s390_do_cu24(UInt srcval, UInt low_surrogate)
459{
460   ULong retval;
461   UInt invalid_low_surrogate = 0;
462
463   srcval &= 0xffff;
464
465   if ((srcval >= 0x0000 && srcval <= 0xd7ff) ||
466       (srcval >= 0xdc00 && srcval <= 0xffff)) {
467      retval = srcval;
468   } else {
469      /* D800 - DBFF */
470      UInt high_surrogate = srcval;
471      UInt uvwxy  = ((high_surrogate >> 6) & 0xf) + 1;   // abcd + 1
472      UInt efghij = high_surrogate & 0x3f;
473      UInt klmnoprst = low_surrogate & 0x3ff;
474
475      retval = (uvwxy << 16) | (efghij << 10) | klmnoprst;
476
477      invalid_low_surrogate = (low_surrogate & 0xfc00) != 0xdc00;
478   }
479
480   /* At this point RETVAL contains the converted bytes.
481      Build up the final return value. */
482   return (retval << 8) | invalid_low_surrogate;
483}
484
485
486/*------------------------------------------------------------*/
487/*--- Clean helper for CU42.                               ---*/
488/*------------------------------------------------------------*/
489
490/* The function performs a CU42 operation. It returns three things
491   encoded in an ULong value:
492   - the converted bytes (at most 4)
493   - the number of converted bytes (2 or 4; 0 if invalid character)
494   - an indication whether the UTF-32 character is invalid
495
496   64      48                16           8                   0
497    +-------+-----------------+-----------+-------------------+
498    |  0x0  | converted bytes | num_bytes | invalid_character |
499    +-------+-----------------+-----------+-------------------+
500*/
501ULong
502s390_do_cu42(UInt srcval)
503{
504   ULong retval;
505   UInt num_bytes, invalid_character = 0;
506
507   if ((srcval >= 0x0000 && srcval <= 0xd7ff) ||
508       (srcval >= 0xdc00 && srcval <= 0xffff)) {
509      retval = srcval;
510      num_bytes = 2;
511   } else if (srcval >= 0x00010000 && srcval <= 0x0010FFFF) {
512      UInt uvwxy  = srcval >> 16;
513      UInt abcd   = (uvwxy - 1) & 0xf;
514      UInt efghij = (srcval >> 10) & 0x3f;
515
516      UInt high_surrogate = (0xd8 << 8) | (abcd << 6) | efghij;
517      UInt low_surrogate  = (0xdc << 8) | (srcval & 0x3ff);
518
519      retval = (high_surrogate << 16) | low_surrogate;
520      num_bytes = 4;
521   } else {
522      /* D800 - DBFF or 00110000 - FFFFFFFF */
523      invalid_character = 1;
524      retval = num_bytes = 0;   /* does not matter; not used */
525   }
526
527   /* At this point RETVAL contains the converted bytes.
528      Build up the final return value. */
529   return (retval << 16) | (num_bytes << 8) | invalid_character;
530}
531
532
533/*------------------------------------------------------------*/
534/*--- Clean helper for CU41.                               ---*/
535/*------------------------------------------------------------*/
536
537/* The function performs a CU41 operation. It returns three things
538   encoded in an ULong value:
539   - the converted bytes (at most 4)
540   - the number of converted bytes (1, 2, 3, or 4; 0 if invalid character)
541   - an indication whether the UTF-32 character is invalid
542
543   64      48                16           8                   0
544    +-------+-----------------+-----------+-------------------+
545    |  0x0  | converted bytes | num_bytes | invalid_character |
546    +-------+-----------------+-----------+-------------------+
547*/
548ULong
549s390_do_cu41(UInt srcval)
550{
551   ULong retval;
552   UInt num_bytes, invalid_character = 0;
553
554   if (srcval <= 0x7f) {
555      retval = srcval;
556      num_bytes = 1;
557   } else if (srcval >= 0x80 && srcval <= 0x7ff) {
558      UInt fghij  = srcval >> 6;
559      UInt klmnop = srcval & 0x3f;
560      UInt byte1  = (0xc0 | fghij);
561      UInt byte2  = (0x80 | klmnop);
562
563      retval = (byte1 << 8) | byte2;
564      num_bytes = 2;
565   } else if ((srcval >= 0x800  && srcval <= 0xd7ff) ||
566              (srcval >= 0xdc00 && srcval <= 0xffff)) {
567      UInt abcd   = srcval >> 12;
568      UInt efghij = (srcval >> 6) & 0x3f;
569      UInt klmnop = srcval & 0x3f;
570      UInt byte1  = 0xe0 | abcd;
571      UInt byte2  = 0x80 | efghij;
572      UInt byte3  = 0x80 | klmnop;
573
574      retval = (byte1 << 16) | (byte2 << 8) | byte3;
575      num_bytes = 3;
576   } else if (srcval >= 0x10000 && srcval <= 0x10ffff) {
577      UInt uvw    = (srcval >> 18) & 0x7;
578      UInt xy     = (srcval >> 16) & 0x3;
579      UInt efgh   = (srcval >> 12) & 0xf;
580      UInt ijklmn = (srcval >>  6) & 0x3f;
581      UInt opqrst = srcval & 0x3f;
582      UInt byte1  = 0xf0 | uvw;
583      UInt byte2  = 0x80 | (xy << 4) | efgh;
584      UInt byte3  = 0x80 | ijklmn;
585      UInt byte4  = 0x80 | opqrst;
586
587      retval = (byte1 << 24) | (byte2 << 16) | (byte3 << 8) | byte4;
588      num_bytes = 4;
589   } else {
590      /* d800 ... dbff or 00110000 ... ffffffff */
591      invalid_character = 1;
592
593      retval = 0;
594      num_bytes = 0;
595   }
596
597   /* At this point RETVAL contains the converted bytes.
598      Build up the final return value. */
599   return (retval << 16) | (num_bytes << 8) | invalid_character;
600}
601
602
603/*------------------------------------------------------------*/
604/*--- Clean helpers for CU12.                              ---*/
605/*------------------------------------------------------------*/
606
607/* The function looks at the first byte of an UTF-8 character and returns
608   two things encoded in an ULong value:
609
610   - the number of bytes that need to be read
611   - an indication whether the UTF-8 character is invalid
612
613   64      16           8                   0
614    +-------------------+-------------------+
615    |  0x0  | num_bytes | invalid_character |
616    +-------+-----------+-------------------+
617*/
618ULong
619s390_do_cu12_cu14_helper1(UInt byte, UInt etf3_and_m3_is_1)
620{
621   vassert(byte <= 0xff);
622
623   /* Check whether the character is invalid */
624   if (byte >= 0x80 && byte <= 0xbf) return 1;
625   if (byte >= 0xf8) return 1;
626
627   if (etf3_and_m3_is_1) {
628      if (byte == 0xc0 || byte == 0xc1) return 1;
629      if (byte >= 0xf5 && byte <= 0xf7) return 1;
630   }
631
632   /* Character is valid */
633   if (byte <= 0x7f) return 1 << 8;   // 1 byte
634   if (byte <= 0xdf) return 2 << 8;   // 2 bytes
635   if (byte <= 0xef) return 3 << 8;   // 3 bytes
636
637   return 4 << 8;  // 4 bytes
638}
639
640/* The function performs a CU12 or CU14 operation. BYTE1, BYTE2, etc are the
641   bytes as read from the input stream, left to right. BYTE1 is a valid
642   byte. The function returns three things encoded in an ULong value:
643
644   - the converted bytes
645   - the number of converted bytes (2 or 4; 0 if invalid character)
646   - an indication whether the UTF-16 character is invalid
647
648   64      48                16           8                   0
649    +-------+-----------------+-----------+-------------------+
650    |  0x0  | converted bytes | num_bytes | invalid_character |
651    +-------+-----------------+-----------+-------------------+
652*/
653static ULong
654s390_do_cu12_cu14_helper2(UInt byte1, UInt byte2, UInt byte3, UInt byte4,
655                          ULong stuff, Bool is_cu12)
656{
657   UInt num_src_bytes = stuff >> 1, etf3_and_m3_is_1 = stuff & 0x1;
658   UInt num_bytes = 0, invalid_character = 0;
659   ULong retval = 0;
660
661   vassert(num_src_bytes <= 4);
662
663   switch (num_src_bytes) {
664   case 1:
665      num_bytes = 2;
666      retval = byte1;
667      break;
668
669   case 2: {
670      /* Test validity */
671      if (etf3_and_m3_is_1) {
672         if (byte2 < 0x80 || byte2 > 0xbf) {
673            invalid_character = 1;
674            break;
675         }
676      }
677
678      /* OK */
679      UInt fghij  = byte1 & 0x1f;
680      UInt klmnop = byte2 & 0x3f;
681
682      num_bytes = 2;
683      retval = (fghij << 6) | klmnop;
684      break;
685   }
686
687   case 3: {
688      /* Test validity */
689      if (etf3_and_m3_is_1) {
690         if (byte1 == 0xe0) {
691            if ((byte2 < 0xa0 || byte2 > 0xbf) ||
692                (byte3 < 0x80 || byte3 > 0xbf)) {
693               invalid_character = 1;
694               break;
695            }
696         }
697         if ((byte1 >= 0xe1 && byte1 <= 0xec) ||
698             byte1 == 0xee || byte1 == 0xef) {
699            if ((byte2 < 0x80 || byte2 > 0xbf) ||
700                (byte3 < 0x80 || byte3 > 0xbf)) {
701               invalid_character = 1;
702               break;
703            }
704         }
705         if (byte1 == 0xed) {
706            if ((byte2 < 0x80 || byte2 > 0x9f) ||
707                (byte3 < 0x80 || byte3 > 0xbf)) {
708               invalid_character = 1;
709               break;
710            }
711         }
712      }
713
714      /* OK */
715      UInt abcd   = byte1 & 0xf;
716      UInt efghij = byte2 & 0x3f;
717      UInt klmnop = byte3 & 0x3f;
718
719      num_bytes = 2;
720      retval = (abcd << 12) | (efghij << 6) | klmnop;
721      break;
722   }
723
724   case 4: {
725      /* Test validity */
726      if (etf3_and_m3_is_1) {
727         if (byte1 == 0xf0) {
728            if ((byte2 < 0x90 || byte2 > 0xbf) ||
729                (byte3 < 0x80 || byte3 > 0xbf) ||
730                (byte4 < 0x80 || byte4 > 0xbf)) {
731               invalid_character = 1;
732               break;
733            }
734         }
735         if (byte1 == 0xf1 || byte1 == 0xf2 || byte1 == 0xf3) {
736            if ((byte2 < 0x80 || byte2 > 0xbf) ||
737                (byte3 < 0x80 || byte3 > 0xbf) ||
738                (byte4 < 0x80 || byte4 > 0xbf)) {
739               invalid_character = 1;
740               break;
741            }
742         }
743         if (byte1 == 0xf4) {
744            if ((byte2 < 0x80 || byte2 > 0x8f) ||
745                (byte3 < 0x80 || byte3 > 0xbf) ||
746                (byte4 < 0x80 || byte4 > 0xbf)) {
747               invalid_character = 1;
748               break;
749            }
750         }
751      }
752
753      /* OK */
754      UInt uvw    = byte1 & 0x7;
755      UInt xy     = (byte2 >> 4) & 0x3;
756      UInt uvwxy  = (uvw << 2) | xy;
757      UInt efgh   = byte2 & 0xf;
758      UInt ij     = (byte3 >> 4) & 0x3;
759      UInt klmn   = byte3 & 0xf;
760      UInt opqrst = byte4 & 0x3f;
761
762      if (is_cu12) {
763         UInt abcd = (uvwxy - 1) & 0xf;
764         UInt high_surrogate = (0xd8 << 8) | (abcd << 6) | (efgh << 2) | ij;
765         UInt low_surrogate  = (0xdc << 8) | (klmn << 6) | opqrst;
766
767         num_bytes = 4;
768         retval = (high_surrogate << 16) | low_surrogate;
769      } else {
770         num_bytes = 4;
771         retval =
772            (uvwxy << 16) | (efgh << 12) | (ij << 10) | (klmn << 6) | opqrst;
773      }
774      break;
775   }
776   }
777
778   if (! is_cu12) num_bytes = 4;   // for CU14, by definition
779
780   /* At this point RETVAL contains the converted bytes.
781      Build up the final return value. */
782   return (retval << 16) | (num_bytes << 8) | invalid_character;
783}
784
785ULong
786s390_do_cu12_helper2(UInt byte1, UInt byte2, UInt byte3, UInt byte4,
787                     ULong stuff)
788{
789   return s390_do_cu12_cu14_helper2(byte1, byte2, byte3, byte4, stuff,
790                                    /* is_cu12 = */ 1);
791}
792
793ULong
794s390_do_cu14_helper2(UInt byte1, UInt byte2, UInt byte3, UInt byte4,
795                     ULong stuff)
796{
797   return s390_do_cu12_cu14_helper2(byte1, byte2, byte3, byte4, stuff,
798                                    /* is_cu12 = */ 0);
799}
800
801
802/*------------------------------------------------------------*/
803/*--- Clean helper for "convert to binary".                ---*/
804/*------------------------------------------------------------*/
805#if defined(VGA_s390x)
806UInt
807s390_do_cvb(ULong decimal)
808{
809   UInt binary;
810
811   __asm__ volatile (
812        "cvb %[result],%[input]\n\t"
813          : [result] "=d"(binary)
814          : [input] "m"(decimal)
815   );
816
817   return binary;
818}
819
820#else
821UInt s390_do_cvb(ULong decimal) { return 0; }
822#endif
823
824
825/*------------------------------------------------------------*/
826/*--- Clean helper for "convert to decimal".                ---*/
827/*------------------------------------------------------------*/
828#if defined(VGA_s390x)
829ULong
830s390_do_cvd(ULong binary_in)
831{
832   UInt binary = binary_in & 0xffffffffULL;
833   ULong decimal;
834
835   __asm__ volatile (
836        "cvd %[input],%[result]\n\t"
837          : [result] "=m"(decimal)
838          : [input] "d"(binary)
839   );
840
841   return decimal;
842}
843
844#else
845ULong s390_do_cvd(ULong binary) { return 0; }
846#endif
847
848
849/*------------------------------------------------------------*/
850/*--- Helper for condition code.                           ---*/
851/*------------------------------------------------------------*/
852
853#define S390_CC_FOR_BINARY(opcode,cc_dep1,cc_dep2) \
854({ \
855   __asm__ volatile ( \
856        opcode " %[op1],%[op2]\n\t" \
857        "ipm %[psw]\n\t"           : [psw] "=d"(psw), [op1] "+d"(cc_dep1) \
858                                   : [op2] "d"(cc_dep2) \
859                                   : "cc");\
860   psw >> 28;   /* cc */ \
861})
862
863#define S390_CC_FOR_TERNARY_SUBB(opcode,cc_dep1,cc_dep2,cc_ndep) \
864({ \
865   /* Recover the original DEP2 value. See comment near s390_cc_thunk_put3 \
866      for rationale. */ \
867   cc_dep2 = cc_dep2 ^ cc_ndep; \
868   __asm__ volatile ( \
869	"lghi 0,1\n\t" \
870	"sr 0,%[op3]\n\t" /* borrow to cc */ \
871        opcode " %[op1],%[op2]\n\t" /* then redo the op */\
872        "ipm %[psw]\n\t"           : [psw] "=d"(psw), [op1] "+&d"(cc_dep1) \
873                                   : [op2] "d"(cc_dep2), [op3] "d"(cc_ndep) \
874                                   : "0", "cc");\
875   psw >> 28;   /* cc */ \
876})
877
878#define S390_CC_FOR_TERNARY_ADDC(opcode,cc_dep1,cc_dep2,cc_ndep) \
879({ \
880   /* Recover the original DEP2 value. See comment near s390_cc_thunk_put3 \
881      for rationale. */ \
882   cc_dep2 = cc_dep2 ^ cc_ndep; \
883   __asm__ volatile ( \
884	"lgfr 0,%[op3]\n\t" /* first load cc_ndep */ \
885	"aghi 0,0\n\t" /* and convert it into a cc */ \
886        opcode " %[op1],%[op2]\n\t" /* then redo the op */\
887        "ipm %[psw]\n\t"           : [psw] "=d"(psw), [op1] "+&d"(cc_dep1) \
888                                   : [op2] "d"(cc_dep2), [op3] "d"(cc_ndep) \
889                                   : "0", "cc");\
890   psw >> 28;   /* cc */ \
891})
892
893
894#define S390_CC_FOR_BFP_RESULT(opcode,cc_dep1) \
895({ \
896   __asm__ volatile ( \
897        opcode " 0,%[op]\n\t" \
898        "ipm %[psw]\n\t"           : [psw] "=d"(psw) \
899                                   : [op]  "f"(cc_dep1) \
900                                   : "cc", "f0");\
901   psw >> 28;   /* cc */ \
902})
903
904#define S390_CC_FOR_BFP128_RESULT(hi,lo) \
905({ \
906   __asm__ volatile ( \
907        "ldr   4,%[high]\n\t" \
908        "ldr   6,%[low]\n\t" \
909        "ltxbr 0,4\n\t" \
910        "ipm %[psw]\n\t"           : [psw] "=d"(psw) \
911                                   : [high] "f"(hi), [low] "f"(lo) \
912                                   : "cc", "f0", "f2", "f4", "f6");\
913   psw >> 28;   /* cc */ \
914})
915
916#define S390_CC_FOR_BFP_CONVERT(opcode,cc_dep1) \
917({ \
918   __asm__ volatile ( \
919        opcode " 0,0,%[op]\n\t" \
920        "ipm %[psw]\n\t"           : [psw] "=d"(psw) \
921                                   : [op]  "f"(cc_dep1) \
922                                   : "cc", "r0");\
923   psw >> 28;   /* cc */ \
924})
925
926#define S390_CC_FOR_BFP128_CONVERT(opcode,hi,lo) \
927({ \
928   __asm__ volatile ( \
929        "ldr   4,%[high]\n\t" \
930        "ldr   6,%[low]\n\t" \
931        opcode " 0,0,4\n\t" \
932        "ipm %[psw]\n\t"           : [psw] "=d"(psw) \
933                                   : [high] "f"(hi), [low] "f"(lo) \
934                                   : "cc", "r0", "f4", "f6");\
935   psw >> 28;   /* cc */ \
936})
937
938#define S390_CC_FOR_BFP_TDC(opcode,cc_dep1,cc_dep2) \
939({ \
940   __asm__ volatile ( \
941        opcode " %[value],0(%[class])\n\t" \
942        "ipm %[psw]\n\t"           : [psw] "=d"(psw) \
943                                   : [value] "f"(cc_dep1), \
944                                     [class] "a"(cc_dep2)  \
945                                   : "cc");\
946   psw >> 28;   /* cc */ \
947})
948
949#define S390_CC_FOR_BFP128_TDC(cc_dep1,cc_dep2,cc_ndep) \
950({ \
951   /* Recover the original DEP2 value. See comment near s390_cc_thunk_put1f128Z \
952      for rationale. */ \
953   cc_dep2 = cc_dep2 ^ cc_ndep; \
954   __asm__ volatile ( \
955        "ldr  4,%[high]\n\t" \
956        "ldr  6,%[low]\n\t" \
957        "tcxb 4,0(%[class])\n\t" \
958        "ipm  %[psw]\n\t"          : [psw] "=d"(psw) \
959                                   : [high] "f"(cc_dep1), [low] "f"(cc_dep2), \
960                                     [class] "a"(cc_ndep)  \
961                                   : "cc", "f4", "f6");\
962   psw >> 28;   /* cc */ \
963})
964
965
966/* Return the value of the condition code from the supplied thunk parameters.
967   This is not the value of the PSW. It is the value of the 2 CC bits within
968   the PSW. The returned value is thusly in the interval [0:3]. */
969UInt
970s390_calculate_cc(ULong cc_op, ULong cc_dep1, ULong cc_dep2, ULong cc_ndep)
971{
972#if defined(VGA_s390x)
973   UInt psw;
974
975   switch (cc_op) {
976
977   case S390_CC_OP_BITWISE:
978      return S390_CC_FOR_BINARY("ogr", cc_dep1, (ULong)0);
979
980   case S390_CC_OP_SIGNED_COMPARE:
981      return S390_CC_FOR_BINARY("cgr", cc_dep1, cc_dep2);
982
983   case S390_CC_OP_UNSIGNED_COMPARE:
984      return S390_CC_FOR_BINARY("clgr", cc_dep1, cc_dep2);
985
986   case S390_CC_OP_SIGNED_ADD_64:
987      return S390_CC_FOR_BINARY("agr", cc_dep1, cc_dep2);
988
989   case S390_CC_OP_SIGNED_ADD_32:
990      return S390_CC_FOR_BINARY("ar", cc_dep1, cc_dep2);
991
992   case S390_CC_OP_SIGNED_SUB_64:
993      return S390_CC_FOR_BINARY("sgr", cc_dep1, cc_dep2);
994
995   case S390_CC_OP_SIGNED_SUB_32:
996      return S390_CC_FOR_BINARY("sr", cc_dep1, cc_dep2);
997
998   case S390_CC_OP_UNSIGNED_ADD_64:
999      return S390_CC_FOR_BINARY("algr", cc_dep1, cc_dep2);
1000
1001   case S390_CC_OP_UNSIGNED_ADD_32:
1002      return S390_CC_FOR_BINARY("alr", cc_dep1, cc_dep2);
1003
1004   case S390_CC_OP_UNSIGNED_ADDC_64:
1005      return S390_CC_FOR_TERNARY_ADDC("alcgr", cc_dep1, cc_dep2, cc_ndep);
1006
1007   case S390_CC_OP_UNSIGNED_ADDC_32:
1008      return S390_CC_FOR_TERNARY_ADDC("alcr", cc_dep1, cc_dep2, cc_ndep);
1009
1010   case S390_CC_OP_UNSIGNED_SUB_64:
1011      return S390_CC_FOR_BINARY("slgr", cc_dep1, cc_dep2);
1012
1013   case S390_CC_OP_UNSIGNED_SUB_32:
1014      return S390_CC_FOR_BINARY("slr", cc_dep1, cc_dep2);
1015
1016   case S390_CC_OP_UNSIGNED_SUBB_64:
1017      return S390_CC_FOR_TERNARY_SUBB("slbgr", cc_dep1, cc_dep2, cc_ndep);
1018
1019   case S390_CC_OP_UNSIGNED_SUBB_32:
1020      return S390_CC_FOR_TERNARY_SUBB("slbr", cc_dep1, cc_dep2, cc_ndep);
1021
1022   case S390_CC_OP_LOAD_AND_TEST:
1023      /* Like signed comparison with 0 */
1024      return S390_CC_FOR_BINARY("cgr", cc_dep1, (Long)0);
1025
1026   case S390_CC_OP_LOAD_POSITIVE_32:
1027      __asm__ volatile (
1028           "lpr  %[result],%[op]\n\t"
1029           "ipm  %[psw]\n\t"         : [psw] "=d"(psw), [result] "=d"(cc_dep1)
1030                                     : [op] "d"(cc_dep1)
1031                                     : "cc");
1032      return psw >> 28;   /* cc */
1033
1034   case S390_CC_OP_LOAD_POSITIVE_64:
1035      __asm__ volatile (
1036           "lpgr %[result],%[op]\n\t"
1037           "ipm  %[psw]\n\t"         : [psw] "=d"(psw), [result] "=d"(cc_dep1)
1038                                     : [op] "d"(cc_dep1)
1039                                     : "cc");
1040      return psw >> 28;   /* cc */
1041
1042   case S390_CC_OP_TEST_UNDER_MASK_8: {
1043      UChar value  = cc_dep1;
1044      UChar mask   = cc_dep2;
1045
1046      __asm__ volatile (
1047           "bras %%r2,1f\n\t"             /* %r2 = address of next insn */
1048           "tm %[value],0\n\t"            /* this is skipped, then EXecuted */
1049           "1: ex %[mask],0(%%r2)\n\t"    /* EXecute TM after modifying mask */
1050           "ipm %[psw]\n\t"             : [psw] "=d"(psw)
1051                                        : [value] "m"(value), [mask] "a"(mask)
1052                                        : "r2", "cc");
1053      return psw >> 28;   /* cc */
1054   }
1055
1056   case S390_CC_OP_TEST_UNDER_MASK_16: {
1057      /* Create a TMLL insn with the mask as given by cc_dep2 */
1058      UInt insn  = (0xA701 << 16) | cc_dep2;
1059      UInt value = cc_dep1;
1060
1061      __asm__ volatile (
1062           "lr   1,%[value]\n\t"
1063           "lhi  2,0x10\n\t"
1064           "ex   2,%[insn]\n\t"
1065           "ipm  %[psw]\n\t"       : [psw] "=d"(psw)
1066                                   : [value] "d"(value), [insn] "m"(insn)
1067                                   : "r1", "r2", "cc");
1068      return psw >> 28;   /* cc */
1069   }
1070
1071   case S390_CC_OP_SHIFT_LEFT_32:
1072      __asm__ volatile (
1073           "sla  %[op],0(%[amount])\n\t"
1074           "ipm  %[psw]\n\t"            : [psw] "=d"(psw), [op] "+d"(cc_dep1)
1075                                        : [amount] "a"(cc_dep2)
1076                                        : "cc");
1077      return psw >> 28;   /* cc */
1078
1079   case S390_CC_OP_SHIFT_LEFT_64: {
1080      Int high = (Int)(cc_dep1 >> 32);
1081      Int low  = (Int)(cc_dep1 & 0xFFFFFFFF);
1082
1083      __asm__ volatile (
1084           "lr   2,%[high]\n\t"
1085           "lr   3,%[low]\n\t"
1086           "slda 2,0(%[amount])\n\t"
1087           "ipm %[psw]\n\t"             : [psw] "=d"(psw), [high] "+d"(high),
1088                                          [low] "+d"(low)
1089                                        : [amount] "a"(cc_dep2)
1090                                        : "cc", "r2", "r3");
1091      return psw >> 28;   /* cc */
1092   }
1093
1094   case S390_CC_OP_INSERT_CHAR_MASK_32: {
1095      Int inserted = 0;
1096      Int msb = 0;
1097
1098      if (cc_dep2 & 1) {
1099         inserted |= cc_dep1 & 0xff;
1100         msb = 0x80;
1101      }
1102      if (cc_dep2 & 2) {
1103         inserted |= cc_dep1 & 0xff00;
1104         msb = 0x8000;
1105      }
1106      if (cc_dep2 & 4) {
1107         inserted |= cc_dep1 & 0xff0000;
1108         msb = 0x800000;
1109      }
1110      if (cc_dep2 & 8) {
1111         inserted |= cc_dep1 & 0xff000000;
1112         msb = 0x80000000;
1113      }
1114
1115      if (inserted & msb)  // MSB is 1
1116         return 1;
1117      if (inserted > 0)
1118         return 2;
1119      return 0;
1120   }
1121
1122   case S390_CC_OP_BFP_RESULT_32:
1123      return S390_CC_FOR_BFP_RESULT("ltebr", cc_dep1);
1124
1125   case S390_CC_OP_BFP_RESULT_64:
1126      return S390_CC_FOR_BFP_RESULT("ltdbr", cc_dep1);
1127
1128   case S390_CC_OP_BFP_RESULT_128:
1129      return S390_CC_FOR_BFP128_RESULT(cc_dep1, cc_dep2);
1130
1131   case S390_CC_OP_BFP_32_TO_INT_32:
1132      return S390_CC_FOR_BFP_CONVERT("cfebr", cc_dep1);
1133
1134   case S390_CC_OP_BFP_64_TO_INT_32:
1135      return S390_CC_FOR_BFP_CONVERT("cfdbr", cc_dep1);
1136
1137   case S390_CC_OP_BFP_128_TO_INT_32:
1138      return S390_CC_FOR_BFP128_CONVERT("cfxbr", cc_dep1, cc_dep2);
1139
1140   case S390_CC_OP_BFP_32_TO_INT_64:
1141      return S390_CC_FOR_BFP_CONVERT("cgebr", cc_dep1);
1142
1143   case S390_CC_OP_BFP_64_TO_INT_64:
1144      return S390_CC_FOR_BFP_CONVERT("cgdbr", cc_dep1);
1145
1146   case S390_CC_OP_BFP_128_TO_INT_64:
1147      return S390_CC_FOR_BFP128_CONVERT("cgxbr", cc_dep1, cc_dep2);
1148
1149   case S390_CC_OP_BFP_TDC_32:
1150      return S390_CC_FOR_BFP_TDC("tceb", cc_dep1, cc_dep2);
1151
1152   case S390_CC_OP_BFP_TDC_64:
1153      return S390_CC_FOR_BFP_TDC("tcdb", cc_dep1, cc_dep2);
1154
1155   case S390_CC_OP_BFP_TDC_128:
1156      return S390_CC_FOR_BFP128_TDC(cc_dep1, cc_dep2, cc_ndep);
1157
1158   case S390_CC_OP_SET:
1159      return cc_dep1;
1160
1161   default:
1162      break;
1163   }
1164#endif
1165   vpanic("s390_calculate_cc");
1166}
1167
1168
1169/* Note that this does *not* return a Boolean value. The result needs to be
1170   explicitly tested against zero. */
1171UInt
1172s390_calculate_cond(ULong mask, ULong op, ULong dep1, ULong dep2, ULong ndep)
1173{
1174   UInt cc = s390_calculate_cc(op, dep1, dep2, ndep);
1175
1176   return ((mask << cc) & 0x8);
1177}
1178
1179/*------------------------------------------------------------*/
1180/*--- spechelper for performance                           ---*/
1181/*------------------------------------------------------------*/
1182
1183
1184/* Convenience macros */
1185#define unop(op,a1) IRExpr_Unop((op),(a1))
1186#define binop(op,a1,a2) IRExpr_Binop((op),(a1),(a2))
1187#define mkU64(v) IRExpr_Const(IRConst_U64(v))
1188#define mkU32(v) IRExpr_Const(IRConst_U32(v))
1189#define mkU8(v)  IRExpr_Const(IRConst_U8(v))
1190
1191
1192static inline Bool
1193isC64(IRExpr *expr)
1194{
1195   return expr->tag == Iex_Const && expr->Iex.Const.con->tag == Ico_U64;
1196}
1197
1198
1199/* The returned expression is NULL if no specialization was found. In that
1200   case the helper function will be called. Otherwise, the expression has
1201   type Ity_I32 and a Boolean value. */
1202IRExpr *
1203guest_s390x_spechelper(HChar *function_name, IRExpr **args,
1204                       IRStmt **precedingStmts, Int n_precedingStmts)
1205{
1206   UInt i, arity = 0;
1207
1208   for (i = 0; args[i]; i++)
1209      arity++;
1210
1211#  if 0
1212   vex_printf("spec request:\n");
1213   vex_printf("   %s  ", function_name);
1214   for (i = 0; i < arity; i++) {
1215      vex_printf("  ");
1216      ppIRExpr(args[i]);
1217   }
1218   vex_printf("\n");
1219#  endif
1220
1221   /* --------- Specialising "s390_calculate_cond" --------- */
1222
1223   if (vex_streq(function_name, "s390_calculate_cond")) {
1224      IRExpr *cond_expr, *cc_op_expr, *cc_dep1, *cc_dep2;
1225      ULong cond, cc_op;
1226
1227      vassert(arity == 5);
1228
1229      cond_expr  = args[0];
1230      cc_op_expr = args[1];
1231
1232      /* The necessary requirement for all optimizations here is that the
1233         condition and the cc_op are constant. So check that upfront. */
1234      if (! isC64(cond_expr))  return NULL;
1235      if (! isC64(cc_op_expr)) return NULL;
1236
1237      cond    = cond_expr->Iex.Const.con->Ico.U64;
1238      cc_op   = cc_op_expr->Iex.Const.con->Ico.U64;
1239
1240      vassert(cond <= 15);
1241
1242      /*
1243        +------+---+---+---+---+
1244        | cc   | 0 | 1 | 2 | 3 |
1245        | cond | 8 | 4 | 2 | 1 |
1246        +------+---+---+---+---+
1247      */
1248      cc_dep1 = args[2];
1249      cc_dep2 = args[3];
1250
1251      /* S390_CC_OP_SIGNED_COMPARE */
1252      if (cc_op == S390_CC_OP_SIGNED_COMPARE) {
1253         /*
1254            cc == 0  --> cc_dep1 == cc_dep2   (cond == 8)
1255            cc == 1  --> cc_dep1 <  cc_dep2   (cond == 4)
1256            cc == 2  --> cc_dep1 >  cc_dep2   (cond == 2)
1257
1258            Because cc == 3 cannot occur the rightmost bit of cond is
1259            a don't care.
1260         */
1261         if (cond == 8 || cond == 8 + 1) {
1262            return unop(Iop_1Uto32, binop(Iop_CmpEQ64, cc_dep1, cc_dep2));
1263         }
1264         if (cond == 4 + 2 || cond == 4 + 2 + 1) {
1265            return unop(Iop_1Uto32, binop(Iop_CmpNE64, cc_dep1, cc_dep2));
1266         }
1267         if (cond == 4 || cond == 4 + 1) {
1268            return unop(Iop_1Uto32, binop(Iop_CmpLT64S, cc_dep1, cc_dep2));
1269         }
1270         if (cond == 8 + 4 || cond == 8 + 4 + 1) {
1271            return unop(Iop_1Uto32, binop(Iop_CmpLE64S, cc_dep1, cc_dep2));
1272         }
1273         /* cc_dep1 > cc_dep2  ---->  cc_dep2 < cc_dep1 */
1274         if (cond == 2 || cond == 2 + 1) {
1275            return unop(Iop_1Uto32, binop(Iop_CmpLT64S, cc_dep2, cc_dep1));
1276         }
1277         if (cond == 8 + 2 || cond == 8 + 2 + 1) {
1278            return unop(Iop_1Uto32, binop(Iop_CmpLE64S, cc_dep2, cc_dep1));
1279         }
1280         if (cond == 8 + 4 + 2 || cond == 8 + 4 + 2 + 1) {
1281            return mkU32(1);
1282         }
1283         /* Remaining case */
1284         return mkU32(0);
1285      }
1286
1287      /* S390_CC_OP_UNSIGNED_COMPARE */
1288      if (cc_op == S390_CC_OP_UNSIGNED_COMPARE) {
1289         /*
1290            cc == 0  --> cc_dep1 == cc_dep2   (cond == 8)
1291            cc == 1  --> cc_dep1 <  cc_dep2   (cond == 4)
1292            cc == 2  --> cc_dep1 >  cc_dep2   (cond == 2)
1293
1294            Because cc == 3 cannot occur the rightmost bit of cond is
1295            a don't care.
1296         */
1297         if (cond == 8 || cond == 8 + 1) {
1298            return unop(Iop_1Uto32, binop(Iop_CmpEQ64, cc_dep1, cc_dep2));
1299         }
1300         if (cond == 4 + 2 || cond == 4 + 2 + 1) {
1301            return unop(Iop_1Uto32, binop(Iop_CmpNE64, cc_dep1, cc_dep2));
1302         }
1303         if (cond == 4 || cond == 4 + 1) {
1304            return unop(Iop_1Uto32, binop(Iop_CmpLT64U, cc_dep1, cc_dep2));
1305         }
1306         if (cond == 8 + 4 || cond == 8 + 4 + 1) {
1307            return unop(Iop_1Uto32, binop(Iop_CmpLE64U, cc_dep1, cc_dep2));
1308         }
1309         /* cc_dep1 > cc_dep2  ---->  cc_dep2 < cc_dep1 */
1310         if (cond == 2 || cond == 2 + 1) {
1311            return unop(Iop_1Uto32, binop(Iop_CmpLT64U, cc_dep2, cc_dep1));
1312         }
1313         if (cond == 8 + 2 || cond == 8 + 2 + 1) {
1314            return unop(Iop_1Uto32, binop(Iop_CmpLE64U, cc_dep2, cc_dep1));
1315         }
1316         if (cond == 8 + 4 + 2 || cond == 8 + 4 + 2 + 1) {
1317            return mkU32(1);
1318         }
1319         /* Remaining case */
1320         return mkU32(0);
1321      }
1322
1323      /* S390_CC_OP_LOAD_AND_TEST */
1324      if (cc_op == S390_CC_OP_LOAD_AND_TEST) {
1325         /*
1326            cc == 0  --> cc_dep1 == 0   (cond == 8)
1327            cc == 1  --> cc_dep1 <  0   (cond == 4)
1328            cc == 2  --> cc_dep1 >  0   (cond == 2)
1329
1330            Because cc == 3 cannot occur the rightmost bit of cond is
1331            a don't care.
1332         */
1333         if (cond == 8 || cond == 8 + 1) {
1334            return unop(Iop_1Uto32, binop(Iop_CmpEQ64, cc_dep1, mkU64(0)));
1335         }
1336         if (cond == 4 + 2 || cond == 4 + 2 + 1) {
1337            return unop(Iop_1Uto32, binop(Iop_CmpNE64, cc_dep1, mkU64(0)));
1338         }
1339         if (cond == 4 || cond == 4 + 1) {
1340            return unop(Iop_1Uto32, binop(Iop_CmpLT64S, cc_dep1, mkU64(0)));
1341         }
1342         if (cond == 8 + 4 || cond == 8 + 4 + 1) {
1343            return unop(Iop_1Uto32, binop(Iop_CmpLE64S, cc_dep1, mkU64(0)));
1344         }
1345         /* cc_dep1 > 0  ---->  0 < cc_dep1 */
1346         if (cond == 2 || cond == 2 + 1) {
1347            return unop(Iop_1Uto32, binop(Iop_CmpLT64S, mkU64(0), cc_dep1));
1348         }
1349         if (cond == 8 + 2 || cond == 8 + 2 + 1) {
1350            return unop(Iop_1Uto32, binop(Iop_CmpLE64S, mkU64(0), cc_dep1));
1351         }
1352         if (cond == 8 + 4 + 2 || cond == 8 + 4 + 2 + 1) {
1353            return mkU32(1);
1354         }
1355         /* Remaining case */
1356         return mkU32(0);
1357      }
1358
1359      /* S390_CC_OP_BITWISE */
1360      if (cc_op == S390_CC_OP_BITWISE) {
1361         /*
1362            cc_dep1 is the result of the boolean operation.
1363
1364            cc == 0  --> cc_dep1 == 0   (cond == 8)
1365            cc == 1  --> cc_dep1 != 0   (cond == 4)
1366
1367            Because cc == 2 and cc == 3 cannot occur the two rightmost bits of
1368            cond are don't cares. Therefore:
1369
1370            cond == 00xx  -> always false
1371            cond == 01xx  -> not equal
1372            cond == 10xx  -> equal
1373            cond == 11xx  -> always true
1374         */
1375         if ((cond & (8 + 4)) == 8 + 4) {
1376            return mkU32(1);
1377         }
1378         if (cond & 8) {
1379            return unop(Iop_1Uto32, binop(Iop_CmpEQ64, cc_dep1, mkU64(0)));
1380         }
1381         if (cond & 4) {
1382            return unop(Iop_1Uto32, binop(Iop_CmpNE64, cc_dep1, mkU64(0)));
1383         }
1384         /* Remaining case */
1385         return mkU32(0);
1386      }
1387
1388      /* S390_CC_OP_INSERT_CHAR_MASK_32
1389         Since the mask comes from an immediate field in the opcode, we
1390         expect the mask to be a constant here. That simplifies matters. */
1391      if (cc_op == S390_CC_OP_INSERT_CHAR_MASK_32) {
1392         ULong mask;
1393         UInt imask = 0, shift = 0;
1394         IRExpr *word;
1395
1396         if (! isC64(cc_dep2)) goto missed;
1397
1398         mask = cc_dep2->Iex.Const.con->Ico.U64;
1399
1400         /* Extract the 32-bit value from the thunk */
1401
1402         word = unop(Iop_64to32, cc_dep1);
1403
1404         switch (mask) {
1405         case 0:  shift =  0; imask = 0x00000000; break;
1406         case 1:  shift = 24; imask = 0x000000FF; break;
1407         case 2:  shift = 16; imask = 0x0000FF00; break;
1408         case 3:  shift = 16; imask = 0x0000FFFF; break;
1409         case 4:  shift =  8; imask = 0x00FF0000; break;
1410         case 5:  shift =  8; imask = 0x00FF00FF; break;
1411         case 6:  shift =  8; imask = 0x00FFFF00; break;
1412         case 7:  shift =  8; imask = 0x00FFFFFF; break;
1413         case 8:  shift =  0; imask = 0xFF000000; break;
1414         case 9:  shift =  0; imask = 0xFF0000FF; break;
1415         case 10: shift =  0; imask = 0xFF00FF00; break;
1416         case 11: shift =  0; imask = 0xFF00FFFF; break;
1417         case 12: shift =  0; imask = 0xFFFF0000; break;
1418         case 13: shift =  0; imask = 0xFFFF00FF; break;
1419         case 14: shift =  0; imask = 0xFFFFFF00; break;
1420         case 15: shift =  0; imask = 0xFFFFFFFF; break;
1421         }
1422
1423         /* Select the bits that were inserted */
1424         word = binop(Iop_And32, word, mkU32(imask));
1425
1426         /* cc == 0  --> all inserted bits zero or mask == 0   (cond == 8)
1427            cc == 1  --> leftmost inserted bit is one          (cond == 4)
1428            cc == 2  --> leftmost inserted bit is zero and not (cond == 2)
1429                         all inserted bits are zero
1430
1431            Because cc == 0,1,2 the rightmost bit of the mask is a don't care */
1432         if (cond == 8 || cond == 8 + 1) {
1433            return unop(Iop_1Uto32, binop(Iop_CmpEQ32, word, mkU32(0)));
1434         }
1435         if (cond == 4 + 2 || cond == 4 + 2 + 1) {
1436            return unop(Iop_1Uto32, binop(Iop_CmpNE32, word, mkU32(0)));
1437         }
1438
1439         /* Sign extend */
1440         if (shift != 0) {
1441            word = binop(Iop_Sar32, binop(Iop_Shl32, word, mkU8(shift)),
1442                         mkU8(shift));
1443         }
1444
1445         if (cond == 4 || cond == 4 + 1) {  /* word < 0 */
1446            return unop(Iop_1Uto32, binop(Iop_CmpLT32S, word, mkU32(0)));
1447         }
1448         if (cond == 2 || cond == 2 + 1) {  /* word > 0 */
1449            return unop(Iop_1Uto32, binop(Iop_CmpLT32S, mkU32(0), word));
1450         }
1451         if (cond == 8 + 4 || cond == 8 + 4 + 1) {
1452            return unop(Iop_1Uto32, binop(Iop_CmpLE32S, word, mkU32(0)));
1453         }
1454         if (cond == 8 + 2 || cond == 8 + 2 + 1) {
1455            return unop(Iop_1Uto32, binop(Iop_CmpLE32S, mkU32(0), word));
1456         }
1457         if (cond == 8 + 4 + 2 || cond == 8 + 4 + 2 + 1) {
1458            return mkU32(1);
1459         }
1460         /* Remaining case */
1461         return mkU32(0);
1462      }
1463
1464      /* S390_CC_OP_TEST_UNDER_MASK_8
1465         Since the mask comes from an immediate field in the opcode, we
1466         expect the mask to be a constant here. That simplifies matters. */
1467      if (cc_op == S390_CC_OP_TEST_UNDER_MASK_8) {
1468         ULong mask16;
1469
1470         if (! isC64(cc_dep2)) goto missed;
1471
1472         mask16 = cc_dep2->Iex.Const.con->Ico.U64;
1473
1474         /* Get rid of the mask16 == 0 case first. Some of the simplifications
1475            below (e.g. for OVFL) only hold if mask16 == 0.  */
1476         if (mask16 == 0) {   /* cc == 0 */
1477            if (cond & 0x8) return mkU32(1);
1478            return mkU32(0);
1479         }
1480
1481         /* cc == 2 is a don't care */
1482         if (cond == 8 || cond == 8 + 2) {
1483            return unop(Iop_1Uto32, binop(Iop_CmpEQ64,
1484                                          binop(Iop_And64, cc_dep1, cc_dep2),
1485                                          mkU64(0)));
1486         }
1487         if (cond == 7 || cond == 7 - 2) {
1488            return unop(Iop_1Uto32, binop(Iop_CmpNE64,
1489                                          binop(Iop_And64, cc_dep1, cc_dep2),
1490                                          mkU64(0)));
1491         }
1492         if (cond == 1 || cond == 1 + 2) {
1493            return unop(Iop_1Uto32, binop(Iop_CmpEQ64,
1494                                          binop(Iop_And64, cc_dep1, cc_dep2),
1495                                          cc_dep2));
1496         }
1497         if (cond == 14 || cond == 14 - 2) {  /* ! OVFL */
1498            return unop(Iop_1Uto32, binop(Iop_CmpNE64,
1499                                          binop(Iop_And64, cc_dep1, cc_dep2),
1500                                          cc_dep2));
1501         }
1502         goto missed;
1503      }
1504
1505      /* S390_CC_OP_TEST_UNDER_MASK_16
1506         Since the mask comes from an immediate field in the opcode, we
1507         expect the mask to be a constant here. That simplifies matters. */
1508      if (cc_op == S390_CC_OP_TEST_UNDER_MASK_16) {
1509         ULong mask16;
1510         UInt msb;
1511
1512         if (! isC64(cc_dep2)) goto missed;
1513
1514         mask16 = cc_dep2->Iex.Const.con->Ico.U64;
1515
1516         /* Get rid of the mask16 == 0 case first. Some of the simplifications
1517            below (e.g. for OVFL) only hold if mask16 == 0.  */
1518         if (mask16 == 0) {   /* cc == 0 */
1519            if (cond & 0x8) return mkU32(1);
1520            return mkU32(0);
1521         }
1522
1523         if (cond == 8) {
1524            return unop(Iop_1Uto32, binop(Iop_CmpEQ64,
1525                                          binop(Iop_And64, cc_dep1, cc_dep2),
1526                                          mkU64(0)));
1527         }
1528         if (cond == 7) {
1529            return unop(Iop_1Uto32, binop(Iop_CmpNE64,
1530                                          binop(Iop_And64, cc_dep1, cc_dep2),
1531                                          mkU64(0)));
1532         }
1533         if (cond == 1) {
1534            return unop(Iop_1Uto32, binop(Iop_CmpEQ64,
1535                                          binop(Iop_And64, cc_dep1, cc_dep2),
1536                                          mkU64(mask16)));
1537         }
1538         if (cond == 14) {  /* ! OVFL */
1539            return unop(Iop_1Uto32, binop(Iop_CmpNE64,
1540                                          binop(Iop_And64, cc_dep1, cc_dep2),
1541                                          mkU64(mask16)));
1542         }
1543
1544         /* Find MSB in mask */
1545         msb = 0x8000;
1546         while (msb > mask16)
1547            msb >>= 1;
1548
1549         if (cond == 2) {  /* cc == 2 */
1550            IRExpr *c1, *c2;
1551
1552            /* (cc_dep & msb) != 0 && (cc_dep & mask16) != mask16 */
1553            c1 = binop(Iop_CmpNE64,
1554                       binop(Iop_And64, cc_dep1, mkU64(msb)), mkU64(0));
1555            c2 = binop(Iop_CmpNE64,
1556                       binop(Iop_And64, cc_dep1, cc_dep2),
1557                       mkU64(mask16));
1558            return binop(Iop_And32, unop(Iop_1Uto32, c1),
1559                         unop(Iop_1Uto32, c2));
1560         }
1561
1562         if (cond == 4) {  /* cc == 1 */
1563            IRExpr *c1, *c2;
1564
1565            /* (cc_dep & msb) == 0 && (cc_dep & mask16) != 0 */
1566            c1 = binop(Iop_CmpEQ64,
1567                       binop(Iop_And64, cc_dep1, mkU64(msb)), mkU64(0));
1568            c2 = binop(Iop_CmpNE64,
1569                       binop(Iop_And64, cc_dep1, cc_dep2),
1570                       mkU64(0));
1571            return binop(Iop_And32, unop(Iop_1Uto32, c1),
1572                         unop(Iop_1Uto32, c2));
1573         }
1574
1575         if (cond == 11) {  /* cc == 0,2,3 */
1576            IRExpr *c1, *c2;
1577
1578            c1 = binop(Iop_CmpNE64,
1579                       binop(Iop_And64, cc_dep1, mkU64(msb)), mkU64(0));
1580            c2 = binop(Iop_CmpEQ64,
1581                       binop(Iop_And64, cc_dep1, cc_dep2),
1582                       mkU64(0));
1583            return binop(Iop_Or32, unop(Iop_1Uto32, c1),
1584                         unop(Iop_1Uto32, c2));
1585         }
1586
1587         if (cond == 3) {  /* cc == 2 || cc == 3 */
1588            return unop(Iop_1Uto32,
1589                        binop(Iop_CmpNE64,
1590                              binop(Iop_And64, cc_dep1, mkU64(msb)),
1591                              mkU64(0)));
1592         }
1593         if (cond == 12) { /* cc == 0 || cc == 1 */
1594            return unop(Iop_1Uto32,
1595                        binop(Iop_CmpEQ64,
1596                              binop(Iop_And64, cc_dep1, mkU64(msb)),
1597                              mkU64(0)));
1598         }
1599         // vex_printf("TUM mask = 0x%llx\n", mask16);
1600         goto missed;
1601      }
1602
1603      /* S390_CC_OP_UNSIGNED_SUB_64/32 */
1604      if (cc_op == S390_CC_OP_UNSIGNED_SUB_64 ||
1605          cc_op == S390_CC_OP_UNSIGNED_SUB_32) {
1606         /*
1607            cc_dep1, cc_dep2 are the zero extended left and right operands
1608
1609            cc == 1  --> result != 0, borrow    (cond == 4)
1610            cc == 2  --> result == 0, no borrow (cond == 2)
1611            cc == 3  --> result != 0, no borrow (cond == 1)
1612
1613            cc = (cc_dep1 == cc_dep2) ? 2
1614                                      : (cc_dep1 > cc_dep2) ? 3 : 1;
1615
1616            Because cc == 0 cannot occur the leftmost bit of cond is
1617            a don't care.
1618         */
1619         if (cond == 1 || cond == 1 + 8) {  /* cc == 3   op2 < op1 */
1620            return unop(Iop_1Uto32, binop(Iop_CmpLT64U, cc_dep2, cc_dep1));
1621         }
1622         if (cond == 2 || cond == 2 + 8) {  /* cc == 2 */
1623            return unop(Iop_1Uto32, binop(Iop_CmpEQ64, cc_dep1, cc_dep2));
1624         }
1625         if (cond == 4 || cond == 4 + 8) {  /* cc == 1 */
1626            return unop(Iop_1Uto32, binop(Iop_CmpLT64U, cc_dep1, cc_dep2));
1627         }
1628         if (cond == 3 || cond == 3 + 8) {  /* cc == 2 || cc == 3 */
1629            return unop(Iop_1Uto32, binop(Iop_CmpLE64U, cc_dep2, cc_dep1));
1630         }
1631         if (cond == 6 || cond == 6 + 8) {  /* cc == 2 || cc == 1 */
1632            return unop(Iop_1Uto32, binop(Iop_CmpLE64U, cc_dep1, cc_dep2));
1633         }
1634
1635         if (cond == 5 || cond == 5 + 8) {  /* cc == 3 || cc == 1 */
1636            return unop(Iop_1Uto32, binop(Iop_CmpNE64, cc_dep1, cc_dep2));
1637         }
1638         if (cond == 7 || cond == 7 + 8) {
1639            return mkU32(1);
1640         }
1641         /* Remaining case */
1642         return mkU32(0);
1643      }
1644
1645      /* S390_CC_OP_UNSIGNED_ADD_64 */
1646      if (cc_op == S390_CC_OP_UNSIGNED_ADD_64) {
1647         /*
1648            cc_dep1, cc_dep2 are the zero extended left and right operands
1649
1650            cc == 0  --> result == 0, no carry  (cond == 8)
1651            cc == 1  --> result != 0, no carry  (cond == 4)
1652            cc == 2  --> result == 0, carry     (cond == 2)
1653            cc == 3  --> result != 0, carry     (cond == 1)
1654         */
1655         if (cond == 8) { /* cc == 0 */
1656            /* Both inputs are 0 */
1657            return unop(Iop_1Uto32, binop(Iop_CmpEQ64,
1658                                          binop(Iop_Or64, cc_dep1, cc_dep2),
1659                                          mkU64(0)));
1660         }
1661         if (cond == 7) { /* cc == 1,2,3 */
1662            /* Not both inputs are 0 */
1663            return unop(Iop_1Uto32, binop(Iop_CmpNE64,
1664                                          binop(Iop_Or64, cc_dep1, cc_dep2),
1665                                          mkU64(0)));
1666         }
1667         if (cond == 8 + 2) {  /* cc == 0,2  -> result is zero */
1668            return unop(Iop_1Uto32, binop(Iop_CmpEQ64,
1669                                          binop(Iop_Add64, cc_dep1, cc_dep2),
1670                                          mkU64(0)));
1671         }
1672         if (cond == 4 + 1) {  /* cc == 1,3  -> result is not zero */
1673            return unop(Iop_1Uto32, binop(Iop_CmpNE64,
1674                                          binop(Iop_Add64, cc_dep1, cc_dep2),
1675                                          mkU64(0)));
1676         }
1677         goto missed;
1678      }
1679
1680      /* S390_CC_OP_UNSIGNED_ADD_32 */
1681      if (cc_op == S390_CC_OP_UNSIGNED_ADD_32) {
1682         /*
1683            cc_dep1, cc_dep2 are the zero extended left and right operands
1684
1685            cc == 0  --> result == 0, no carry  (cond == 8)
1686            cc == 1  --> result != 0, no carry  (cond == 4)
1687            cc == 2  --> result == 0, carry     (cond == 2)
1688            cc == 3  --> result != 0, carry     (cond == 1)
1689         */
1690         if (cond == 8) { /* cc == 0 */
1691            /* Both inputs are 0 */
1692            return unop(Iop_1Uto32, binop(Iop_CmpEQ64,
1693                                          binop(Iop_Or64, cc_dep1, cc_dep2),
1694                                          mkU64(0)));
1695         }
1696         if (cond == 7) { /* cc == 1,2,3 */
1697            /* Not both inputs are 0 */
1698            return unop(Iop_1Uto32, binop(Iop_CmpNE64,
1699                                          binop(Iop_Or64, cc_dep1, cc_dep2),
1700                                          mkU64(0)));
1701         }
1702         if (cond == 8 + 2) {  /* cc == 0,2  -> result is zero */
1703            return unop(Iop_1Uto32, binop(Iop_CmpEQ32,
1704                                          binop(Iop_Add32,
1705                                                unop(Iop_64to32, cc_dep1),
1706                                                unop(Iop_64to32, cc_dep2)),
1707                                          mkU32(0)));
1708         }
1709         if (cond == 4 + 1) {  /* cc == 1,3  -> result is not zero */
1710            return unop(Iop_1Uto32, binop(Iop_CmpNE32,
1711                                          binop(Iop_Add32,
1712                                                unop(Iop_64to32, cc_dep1),
1713                                                unop(Iop_64to32, cc_dep2)),
1714                                          mkU32(0)));
1715         }
1716         goto missed;
1717      }
1718
1719      /* S390_CC_OP_SET */
1720      if (cc_op == S390_CC_OP_SET) {
1721         /* cc_dep1 is the condition code
1722
1723            Return 1, if ((cond << cc_dep1) & 0x8) != 0 */
1724
1725        return unop(Iop_1Uto32,
1726                    binop(Iop_CmpNE64,
1727                          binop(Iop_And64,
1728                                binop(Iop_Shl64, cond_expr,
1729                                      unop(Iop_64to8, cc_dep1)),
1730                                mkU64(8)),
1731                          mkU64(0)));
1732      }
1733
1734missed:
1735      ;
1736   }
1737
1738   return NULL;
1739}
1740
1741/*---------------------------------------------------------------*/
1742/*--- end                                guest_s390_helpers.c ---*/
1743/*---------------------------------------------------------------*/
1744