Home | History | Annotate | Download | only in s390x
      1 #include <stdint.h>
      2 #include <inttypes.h>
      3 #include <stdlib.h>
      4 #include <string.h>
      5 #include <stdio.h>
      6 #include "../../../none/tests/s390x/opcodes.h"
      7 
      8 /* Define various input buffers. */
      9 
     10 /* U+0000 to U+007f:  Result is 1 byte for each uint16_t */
     11 uint16_t pattern1[] = {
     12    0x0000, 0x007f,    /* corner cases */
     13    0x0047, 0x0056, 0x0045, 0x0021, 0x007b, 0x003a /* misc */
     14 };
     15 
     16 /* U+0080 to U+07ff:  Result is 2 bytes for each uint16_t */
     17 uint16_t pattern2[] = {
     18    0x0080, 0x07ff,    /* corner cases */
     19    0x07df, 0x008f, 0x0100, 0x017f, 0x052f, 0x0600, 0x06ff /* misc */
     20 };
     21 
     22 /* U+0800 to U+d7ff:  Result is 3 bytes for each uint16_t
     23    U+dc00 to U+ffff:  Result is 3 bytes for each uint16_t */
     24 uint16_t pattern3[] = {
     25    0x0800, 0xd7ff,    /* corner cases */
     26    0xdc00, 0xffff,    /* corner cases */
     27    0x083f, 0x1a21, 0x1b10, 0x2200, 0x225e, 0x22c9, 0xe001  /* misc */
     28 };
     29 
     30 /* U+d800 to U+dbff:  Result is 4 bytes for each uint16_t pair */
     31 uint16_t pattern4[] = {
     32    0xd800, 0xdc00,    /* left  corner case */
     33    0xdbff, 0xdfff,    /* right corner case */
     34    0xdada, 0xdddd, 0xdeaf, 0xdcdc  /* misc */
     35 };
     36 
     37 
     38 void
     39 do_cu21(uint8_t *dst, uint64_t dst_len, uint16_t *src, uint64_t src_len)
     40 {
     41    /* build up the register pairs */
     42    register uint16_t *source     asm("4") = src;
     43    register uint64_t  source_len asm("5") = src_len;
     44    register uint8_t  *dest       asm("2") = dst;
     45    register uint64_t  dest_len   asm("3") = dst_len;
     46 
     47    asm volatile(
     48                 CU21(0,2,4)
     49                 : "+d"(dest), "+d"(source), "+d"(source_len), "+d"(dest_len)
     50                 :
     51                 : "memory", "cc");
     52    return;
     53 }
     54 
     55 int main()
     56 {
     57    /*------------------------------------------------------------*/
     58    /* Write to a too small buffer                                */
     59    /*------------------------------------------------------------*/
     60 
     61    /* Write 2 bytes into buffer of length 1 */
     62    do_cu21(malloc(1), 10, pattern2, 2);             // complaint (2 bytes)
     63 
     64    /* Write 2 bytes into buffer of length 2 */
     65    do_cu21(malloc(2), 10, pattern2, 2);             // no complaint
     66 
     67    /* Write 3 bytes into buffer of length 1 */
     68    do_cu21(malloc(1), 10, pattern3, 2);             // 2 complaints (3 = 2+1)
     69 
     70    /* Write 3 bytes into buffer of length 2 */
     71    do_cu21(malloc(2), 10, pattern3, 2);             // complaint (1 byte)
     72 
     73    /* Write 3 bytes into buffer of length 3 */
     74    do_cu21(malloc(3), 10, pattern3, 2);             // no complaint
     75 
     76    /* Write 4 bytes into buffer of length 1 */
     77    do_cu21(malloc(1), 10, pattern4, 4);             // complaint (4 bytes)
     78 
     79    /* Write 4 bytes into buffer of length 2 */
     80    do_cu21(malloc(2), 10, pattern4, 4);             // complaint (4 bytes)
     81 
     82    /* Write 4 bytes into buffer of length 3 */
     83    do_cu21(malloc(3), 10, pattern4, 4);             // complaint (4 bytes)
     84 
     85    /* Write 4 bytes into buffer of length 4 */
     86    do_cu21(malloc(4), 10, pattern4, 4);             // no complaint
     87 
     88    /*------------------------------------------------------------*/
     89    /* Read uninitialised data                                    */
     90    /*------------------------------------------------------------*/
     91    uint8_t *input = malloc(10);
     92 
     93    /* Input buffer is completely uninitialised */
     94    do_cu21(malloc(4), 4, (void *)input, 2);         // complaint
     95 
     96    /* Read 2 bytes from input buffer. First byte is uninitialised */
     97    input = malloc(10);
     98    input[1] = 0x0;
     99    do_cu21(malloc(4), 4, (void *)input, 2);          // complaint
    100 
    101    /* Read 2 bytes from input buffer. Second byte is uninitialised */
    102    input = malloc(10);
    103    input[0] = 0x0;
    104    do_cu21(malloc(4), 4, (void *)input, 2);          // complaint
    105 
    106    /* Read 2 bytes from input buffer. All bytes are initialised */
    107    input = malloc(10);
    108    input[0] = input[1] = 0x0;
    109    do_cu21(malloc(4), 4, (void *)input, 2);          // no complaint
    110 
    111    /* Read 4 bytes from input buffer. This iterates once. In the 1st
    112       iteration all input bytes are initialised in the 2nd iteration all
    113       input bytes are uninitialised. */
    114    input = malloc(10);
    115    input[0] = input[1] = 0x0;
    116    do_cu21(malloc(4), 4, (void *)input, 4);          // complaint
    117 
    118    /* Write to NULL */
    119    //   do_cu21(NULL, 10, pattern1, sizeof pattern1);    // complaint
    120 
    121    return 0;
    122 }
    123