~bkerensa/ubuntu/raring/valgrind/merge-from-deb

« back to all changes in this revision

Viewing changes to VEX/priv/guest_s390_helpers.c

  • Committer: Benjamin Kerensa
  • Date: 2012-11-21 23:57:58 UTC
  • mfrom: (1.1.16)
  • Revision ID: bkerensa@ubuntu.com-20121121235758-bd1rv5uc5vzov2p6
Merge from debian unstable

Show diffs side-by-side

added added

removed removed

Lines of Context:
8
8
   This file is part of Valgrind, a dynamic binary instrumentation
9
9
   framework.
10
10
 
11
 
   Copyright IBM Corp. 2010-2011
 
11
   Copyright IBM Corp. 2010-2012
12
12
 
13
13
   This program is free software; you can redistribute it and/or
14
14
   modify it under the terms of the GNU General Public License as
130
130
   state->guest_TILEN = 0;
131
131
   state->guest_IP_AT_SYSCALL = 0;
132
132
   state->guest_EMWARN = EmWarn_NONE;
 
133
   state->host_EvC_COUNTER = 0;
 
134
   state->host_EvC_FAILADDR = 0;
133
135
 
134
136
/*------------------------------------------------------------*/
135
137
/*--- Initialise thunk                                     ---*/
139
141
   state->guest_CC_DEP1 = 0;
140
142
   state->guest_CC_DEP2 = 0;
141
143
   state->guest_CC_NDEP = 0;
 
144
 
 
145
   __builtin_memset(state->padding, 0x0, sizeof(state->padding));
142
146
}
143
147
 
144
148
 
227
231
};
228
232
 
229
233
/*------------------------------------------------------------*/
230
 
/*--- Dirty helper for invalid opcode 00                   ---*/
231
 
/*------------------------------------------------------------*/
232
 
#if defined(VGA_s390x)
233
 
void
234
 
s390x_dirtyhelper_00(VexGuestS390XState *guest_state)
235
 
{
236
 
   /* Avoid infinite loop in case SIGILL is caught. See also
237
 
      none/tests/s390x/op_exception.c */
238
 
   guest_state->guest_IA += 2;
239
 
 
240
 
   asm volatile(".hword 0\n");
241
 
}
242
 
#else
243
 
void s390x_dirtyhelper_00(VexGuestS390XState *guest_state) { }
244
 
#endif
245
 
 
246
 
/*------------------------------------------------------------*/
247
234
/*--- Dirty helper for EXecute                             ---*/
248
235
/*------------------------------------------------------------*/
249
236
void
257
244
/*--- Dirty helper for Clock instructions                  ---*/
258
245
/*------------------------------------------------------------*/
259
246
#if defined(VGA_s390x)
260
 
ULong s390x_dirtyhelper_STCK(ULong *addr)
 
247
ULong
 
248
s390x_dirtyhelper_STCK(ULong *addr)
261
249
{
262
250
   int cc;
263
251
 
268
256
   return cc;
269
257
}
270
258
 
271
 
ULong s390x_dirtyhelper_STCKE(ULong *addr)
 
259
ULong
 
260
s390x_dirtyhelper_STCKE(ULong *addr)
272
261
{
273
262
   int cc;
274
263
 
300
289
/*------------------------------------------------------------*/
301
290
#if defined(VGA_s390x)
302
291
ULong
303
 
s390x_dirtyhelper_STFLE(VexGuestS390XState *guest_state, HWord addr)
 
292
s390x_dirtyhelper_STFLE(VexGuestS390XState *guest_state, ULong *addr)
304
293
{
305
294
   ULong hoststfle[S390_NUM_FACILITY_DW], cc, num_dw, i;
306
295
   register ULong reg0 asm("0") = guest_state->guest_r0 & 0xF;  /* r0[56:63] */
321
310
   guest_state->guest_r0 = reg0;
322
311
 
323
312
   for (i = 0; i < num_dw; ++i)
324
 
      ((ULong *)addr)[i] = hoststfle[i];
 
313
      addr[i] = hoststfle[i];
325
314
 
326
315
   return cc;
327
316
}
329
318
#else
330
319
 
331
320
ULong
332
 
s390x_dirtyhelper_STFLE(VexGuestS390XState *guest_state, HWord addr)
 
321
s390x_dirtyhelper_STFLE(VexGuestS390XState *guest_state, ULong *addr)
333
322
{
334
323
   return 3;
335
324
}
336
325
#endif /* VGA_s390x */
337
326
 
338
327
/*------------------------------------------------------------*/
 
328
/*--- Dirty helper for the "convert unicode" insn family.  ---*/
 
329
/*------------------------------------------------------------*/
 
330
void
 
331
s390x_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
*/
 
361
ULong
 
362
s390_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
*/
 
457
ULong
 
458
s390_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
*/
 
501
ULong
 
502
s390_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
*/
 
548
ULong
 
549
s390_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
*/
 
618
ULong
 
619
s390_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
*/
 
653
static ULong
 
654
s390_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
 
 
785
ULong
 
786
s390_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
 
 
793
ULong
 
794
s390_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)
 
806
UInt
 
807
s390_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
 
821
UInt 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)
 
829
ULong
 
830
s390_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
 
845
ULong s390_do_cvd(ULong binary) { return 0; }
 
846
#endif
 
847
 
 
848
 
 
849
/*------------------------------------------------------------*/
339
850
/*--- Helper for condition code.                           ---*/
340
851
/*------------------------------------------------------------*/
341
852
 
512
1023
      /* Like signed comparison with 0 */
513
1024
      return S390_CC_FOR_BINARY("cgr", cc_dep1, (Long)0);
514
1025
 
515
 
   case S390_CC_OP_TEST_AND_SET:
516
 
      /* Shift the sign bit into the LSB. Note, that the tested value is an
517
 
         8-bit value which has been zero-extended to 32/64 bit. */
518
 
      return cc_dep1 >> 7;
519
 
 
520
1026
   case S390_CC_OP_LOAD_POSITIVE_32:
521
1027
      __asm__ volatile (
522
1028
           "lpr  %[result],%[op]\n\t"
523
 
           "ipm  %[psw]\n\t"            : [psw] "=d"(psw), [result] "=d"(cc_dep1)
524
 
                                        : [op] "d"(cc_dep1)
525
 
                                        : "cc");
 
1029
           "ipm  %[psw]\n\t"         : [psw] "=d"(psw), [result] "=d"(cc_dep1)
 
1030
                                     : [op] "d"(cc_dep1)
 
1031
                                     : "cc");
526
1032
      return psw >> 28;   /* cc */
527
1033
 
528
1034
   case S390_CC_OP_LOAD_POSITIVE_64:
529
1035
      __asm__ volatile (
530
1036
           "lpgr %[result],%[op]\n\t"
531
 
           "ipm  %[psw]\n\t"            : [psw] "=d"(psw), [result] "=d"(cc_dep1)
532
 
                                        : [op] "d"(cc_dep1)
533
 
                                        : "cc");
 
1037
           "ipm  %[psw]\n\t"         : [psw] "=d"(psw), [result] "=d"(cc_dep1)
 
1038
                                     : [op] "d"(cc_dep1)
 
1039
                                     : "cc");
534
1040
      return psw >> 28;   /* cc */
535
1041
 
536
1042
   case S390_CC_OP_TEST_UNDER_MASK_8: {
578
1084
           "lr   2,%[high]\n\t"
579
1085
           "lr   3,%[low]\n\t"
580
1086
           "slda 2,0(%[amount])\n\t"
581
 
           "ipm %[psw]\n\t"             : [psw] "=d"(psw), [high] "+d"(high), [low] "+d"(low)
 
1087
           "ipm %[psw]\n\t"             : [psw] "=d"(psw), [high] "+d"(high),
 
1088
                                          [low] "+d"(low)
582
1089
                                        : [amount] "a"(cc_dep2)
583
1090
                                        : "cc", "r2", "r3");
584
1091
      return psw >> 28;   /* cc */
659
1166
}
660
1167
 
661
1168
 
662
 
UInt
663
 
s390_calculate_icc(ULong op, ULong dep1, ULong dep2)
664
 
{
665
 
   return s390_calculate_cc(op, dep1, dep2, 0 /* unused */);
666
 
}
667
 
 
668
 
 
669
1169
/* Note that this does *not* return a Boolean value. The result needs to be
670
1170
   explicitly tested against zero. */
671
1171
UInt
1231
1731
                          mkU64(0)));
1232
1732
      }
1233
1733
 
1234
 
      /* S390_CC_OP_TEST_AND_SET */
1235
 
      if (cc_op == S390_CC_OP_TEST_AND_SET) {
1236
 
         /* cc_dep1 is the zero-extended loaded value
1237
 
 
1238
 
            cc == 0  --> leftmost bit is zero  (cond == 8)
1239
 
            cc == 1  --> leftmost bit is one   (cond == 4)
1240
 
 
1241
 
            As cc is either 0 or 1, only the two leftmost bits of the mask
1242
 
            are relevant. */
1243
 
         IRExpr *bit = binop(Iop_Shr64, cc_dep1, mkU8(7));
1244
 
 
1245
 
         switch (cond & (8 + 4)) {
1246
 
         case 0:     return mkU32(0);
1247
 
         case 4:     return unop(Iop_1Uto32, binop(Iop_CmpNE64, bit, mkU64(0)));
1248
 
         case 8:     return unop(Iop_1Uto32, binop(Iop_CmpEQ64, bit, mkU64(0)));
1249
 
         case 8 + 4: return mkU32(1);
1250
 
         }
1251
 
         /* not reached */
1252
 
      }
1253
 
 
1254
1734
missed:
1255
1735
      ;
1256
1736
   }