332
s390x_dirtyhelper_STFLE(VexGuestS390XState *guest_state, HWord addr)
321
s390x_dirtyhelper_STFLE(VexGuestS390XState *guest_state, ULong *addr)
336
325
#endif /* VGA_s390x */
338
327
/*------------------------------------------------------------*/
328
/*--- Dirty helper for the "convert unicode" insn family. ---*/
329
/*------------------------------------------------------------*/
331
s390x_dirtyhelper_CUxy(UChar *address, ULong data, ULong num_bytes)
335
vassert(num_bytes >= 1 && num_bytes <= 4);
337
/* Store the least significant NUM_BYTES bytes in DATA left to right
339
for (i = 1; i <= num_bytes; ++i) {
340
address[num_bytes - i] = data & 0xff;
346
/*------------------------------------------------------------*/
347
/*--- Clean helper for CU21. ---*/
348
/*------------------------------------------------------------*/
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
357
+-------+-----------------+-----------+-----------------------+
358
| 0x0 | converted bytes | num_bytes | invalid_low_surrogate |
359
+-------+-----------------+-----------+-----------------------+
362
s390_do_cu21(UInt srcval, UInt low_surrogate)
364
ULong retval = 0; // shut up gcc
365
UInt b1, b2, b3, b4, num_bytes, invalid_low_surrogate = 0;
369
/* Determine the number of bytes in the converted value */
370
if (srcval <= 0x007f)
372
else if (srcval >= 0x0080 && srcval <= 0x07ff)
374
else if ((srcval >= 0x0800 && srcval <= 0xd7ff) ||
375
(srcval >= 0xdc00 && srcval <= 0xffff))
380
/* Determine UTF-8 bytes according to calculated num_bytes */
387
/* order of bytes left to right: b1, b2 */
394
retval = (b1 << 8) | b2;
398
/* order of bytes left to right: b1, b2, b3 */
403
b2 |= (srcval >> 6) & 0x3f;
408
retval = (b1 << 16) | (b2 << 8) | b3;
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
417
b1 |= uvwxy >> 2; // uvw
420
b2 |= (uvwxy & 0x3) << 4; // xy
421
b2 |= (high_surrogate >> 2) & 0xf; // efgh
424
b3 |= (high_surrogate & 0x3) << 4; // ij
425
b3 |= (low_surrogate >> 6) & 0xf; // klmn
428
b4 |= low_surrogate & 0x3f;
430
retval = (b1 << 24) | (b2 << 16) | (b3 << 8) | b4;
432
invalid_low_surrogate = (low_surrogate & 0xfc00) != 0xdc00;
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;
443
/*------------------------------------------------------------*/
444
/*--- Clean helper for CU24. ---*/
445
/*------------------------------------------------------------*/
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
453
+------------------------+-----------------------+
454
| 0x0 | converted bytes | invalid_low_surrogate |
455
+------------------------+-----------------------+
458
s390_do_cu24(UInt srcval, UInt low_surrogate)
461
UInt invalid_low_surrogate = 0;
465
if ((srcval >= 0x0000 && srcval <= 0xd7ff) ||
466
(srcval >= 0xdc00 && srcval <= 0xffff)) {
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;
475
retval = (uvwxy << 16) | (efghij << 10) | klmnoprst;
477
invalid_low_surrogate = (low_surrogate & 0xfc00) != 0xdc00;
480
/* At this point RETVAL contains the converted bytes.
481
Build up the final return value. */
482
return (retval << 8) | invalid_low_surrogate;
486
/*------------------------------------------------------------*/
487
/*--- Clean helper for CU42. ---*/
488
/*------------------------------------------------------------*/
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
497
+-------+-----------------+-----------+-------------------+
498
| 0x0 | converted bytes | num_bytes | invalid_character |
499
+-------+-----------------+-----------+-------------------+
502
s390_do_cu42(UInt srcval)
505
UInt num_bytes, invalid_character = 0;
507
if ((srcval >= 0x0000 && srcval <= 0xd7ff) ||
508
(srcval >= 0xdc00 && srcval <= 0xffff)) {
511
} else if (srcval >= 0x00010000 && srcval <= 0x0010FFFF) {
512
UInt uvwxy = srcval >> 16;
513
UInt abcd = (uvwxy - 1) & 0xf;
514
UInt efghij = (srcval >> 10) & 0x3f;
516
UInt high_surrogate = (0xd8 << 8) | (abcd << 6) | efghij;
517
UInt low_surrogate = (0xdc << 8) | (srcval & 0x3ff);
519
retval = (high_surrogate << 16) | low_surrogate;
522
/* D800 - DBFF or 00110000 - FFFFFFFF */
523
invalid_character = 1;
524
retval = num_bytes = 0; /* does not matter; not used */
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;
533
/*------------------------------------------------------------*/
534
/*--- Clean helper for CU41. ---*/
535
/*------------------------------------------------------------*/
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
544
+-------+-----------------+-----------+-------------------+
545
| 0x0 | converted bytes | num_bytes | invalid_character |
546
+-------+-----------------+-----------+-------------------+
549
s390_do_cu41(UInt srcval)
552
UInt num_bytes, invalid_character = 0;
554
if (srcval <= 0x7f) {
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);
563
retval = (byte1 << 8) | byte2;
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;
574
retval = (byte1 << 16) | (byte2 << 8) | byte3;
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;
587
retval = (byte1 << 24) | (byte2 << 16) | (byte3 << 8) | byte4;
590
/* d800 ... dbff or 00110000 ... ffffffff */
591
invalid_character = 1;
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;
603
/*------------------------------------------------------------*/
604
/*--- Clean helpers for CU12. ---*/
605
/*------------------------------------------------------------*/
607
/* The function looks at the first byte of an UTF-8 character and returns
608
two things encoded in an ULong value:
610
- the number of bytes that need to be read
611
- an indication whether the UTF-8 character is invalid
614
+-------------------+-------------------+
615
| 0x0 | num_bytes | invalid_character |
616
+-------+-----------+-------------------+
619
s390_do_cu12_cu14_helper1(UInt byte, UInt etf3_and_m3_is_1)
621
vassert(byte <= 0xff);
623
/* Check whether the character is invalid */
624
if (byte >= 0x80 && byte <= 0xbf) return 1;
625
if (byte >= 0xf8) return 1;
627
if (etf3_and_m3_is_1) {
628
if (byte == 0xc0 || byte == 0xc1) return 1;
629
if (byte >= 0xf5 && byte <= 0xf7) return 1;
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
637
return 4 << 8; // 4 bytes
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:
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
649
+-------+-----------------+-----------+-------------------+
650
| 0x0 | converted bytes | num_bytes | invalid_character |
651
+-------+-----------------+-----------+-------------------+
654
s390_do_cu12_cu14_helper2(UInt byte1, UInt byte2, UInt byte3, UInt byte4,
655
ULong stuff, Bool is_cu12)
657
UInt num_src_bytes = stuff >> 1, etf3_and_m3_is_1 = stuff & 0x1;
658
UInt num_bytes = 0, invalid_character = 0;
661
vassert(num_src_bytes <= 4);
663
switch (num_src_bytes) {
671
if (etf3_and_m3_is_1) {
672
if (byte2 < 0x80 || byte2 > 0xbf) {
673
invalid_character = 1;
679
UInt fghij = byte1 & 0x1f;
680
UInt klmnop = byte2 & 0x3f;
683
retval = (fghij << 6) | klmnop;
689
if (etf3_and_m3_is_1) {
691
if ((byte2 < 0xa0 || byte2 > 0xbf) ||
692
(byte3 < 0x80 || byte3 > 0xbf)) {
693
invalid_character = 1;
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;
706
if ((byte2 < 0x80 || byte2 > 0x9f) ||
707
(byte3 < 0x80 || byte3 > 0xbf)) {
708
invalid_character = 1;
715
UInt abcd = byte1 & 0xf;
716
UInt efghij = byte2 & 0x3f;
717
UInt klmnop = byte3 & 0x3f;
720
retval = (abcd << 12) | (efghij << 6) | klmnop;
726
if (etf3_and_m3_is_1) {
728
if ((byte2 < 0x90 || byte2 > 0xbf) ||
729
(byte3 < 0x80 || byte3 > 0xbf) ||
730
(byte4 < 0x80 || byte4 > 0xbf)) {
731
invalid_character = 1;
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;
744
if ((byte2 < 0x80 || byte2 > 0x8f) ||
745
(byte3 < 0x80 || byte3 > 0xbf) ||
746
(byte4 < 0x80 || byte4 > 0xbf)) {
747
invalid_character = 1;
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;
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;
768
retval = (high_surrogate << 16) | low_surrogate;
772
(uvwxy << 16) | (efgh << 12) | (ij << 10) | (klmn << 6) | opqrst;
778
if (! is_cu12) num_bytes = 4; // for CU14, by definition
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;
786
s390_do_cu12_helper2(UInt byte1, UInt byte2, UInt byte3, UInt byte4,
789
return s390_do_cu12_cu14_helper2(byte1, byte2, byte3, byte4, stuff,
794
s390_do_cu14_helper2(UInt byte1, UInt byte2, UInt byte3, UInt byte4,
797
return s390_do_cu12_cu14_helper2(byte1, byte2, byte3, byte4, stuff,
802
/*------------------------------------------------------------*/
803
/*--- Clean helper for "convert to binary". ---*/
804
/*------------------------------------------------------------*/
805
#if defined(VGA_s390x)
807
s390_do_cvb(ULong decimal)
812
"cvb %[result],%[input]\n\t"
813
: [result] "=d"(binary)
814
: [input] "m"(decimal)
821
UInt s390_do_cvb(ULong decimal) { return 0; }
825
/*------------------------------------------------------------*/
826
/*--- Clean helper for "convert to decimal". ---*/
827
/*------------------------------------------------------------*/
828
#if defined(VGA_s390x)
830
s390_do_cvd(ULong binary_in)
832
UInt binary = binary_in & 0xffffffffULL;
836
"cvd %[input],%[result]\n\t"
837
: [result] "=m"(decimal)
838
: [input] "d"(binary)
845
ULong s390_do_cvd(ULong binary) { return 0; }
849
/*------------------------------------------------------------*/
339
850
/*--- Helper for condition code. ---*/
340
851
/*------------------------------------------------------------*/