Home | History | Annotate | Download | only in s390x
      1 #include<stdio.h>
      2 #include<stdlib.h>
      3 #include<stdint.h>
      4 #include<inttypes.h>
      5 #include<string.h>
      6 #include "table.h"
      7 
      8 /* Register contents after executing an TRE insn */
      9 typedef struct {
     10    uint64_t addr;
     11    uint64_t len;
     12    uint64_t tabaddr;
     13    uint8_t testbyte;
     14    uint64_t cc;
     15 } tre_regs;
     16 
     17 uint8_t buff[40];
     18 
     19 tre_regs tre(uint8_t *codepage, uint8_t *addr, uint64_t len, uint8_t test_byte)
     20 {
     21    int cc;
     22    tre_regs regs;
     23 
     24    register uint64_t param asm("0") = test_byte;
     25    register uint64_t a2 asm ("4") = (uint64_t)codepage;
     26    register uint64_t a1 asm ("2") = (uint64_t)addr;
     27    register uint64_t l1 asm ("3") = len;
     28 
     29    asm volatile(
     30                 " tre  %1,%2\n"
     31                 " ipm  %0\n"
     32                 " srl  %0,28\n"
     33 		:"=d"(cc),"+&d"(a1)
     34                 :"d"(a2),"d"(param),"d"(l1),"d"(test_byte):  "memory" );
     35 
     36    regs.addr = a1;
     37    regs.len = l1;
     38    regs.tabaddr = a2;
     39    regs.testbyte = param;
     40    regs.cc = cc;
     41 
     42    return regs;
     43 }
     44 
     45 void run_test(void *tran_table, void *srcaddr, uint64_t len, uint8_t test)
     46 {
     47    tre_regs regs;
     48    int i;
     49 
     50    regs = tre(tran_table, srcaddr, len, test);
     51 
     52    if ((uint64_t)tran_table != regs.tabaddr)
     53       printf("translation table address changed\n");
     54    if (test != regs.testbyte)
     55       printf("test byte changed\n");
     56    if ((uint64_t)srcaddr + (len - regs.len) != regs.addr)
     57       printf("source address/length not updated properly\n");
     58 
     59    printf("Resulting cc is %"PRIu64" and the string is ", regs.cc);
     60    for ( i = 0; i < len; i++) {
     61       printf("%c", buff[i]);
     62    }
     63 
     64    printf("\n");
     65 }
     66 
     67 int main()
     68 {
     69 
     70    /* Test 1: length = 0 */
     71    run_test(NULL, NULL, 0, 0x0);
     72    run_test((char *)&touppercase, &buff, 0, 0x0);
     73    run_test((char *)&touppercase, &buff, 0, 'b');
     74 
     75    /* Test 2 : length > 0 */
     76    memset(buff, 'a', 1);
     77    run_test((char *)&touppercase, &buff, 1, 'a');   //cc = 1
     78    run_test((char *)&touppercase, &buff, 1, 'b');
     79 
     80    memcpy(buff, "abcdefgh", 8);
     81    run_test((char *)&touppercase, &buff, 3, 'a');   //cc = 1
     82    run_test((char *)&touppercase, &buff, 3, 'f');   //cc = 0
     83    run_test((char *)&touppercase, &buff, 8, 'l');   //cc = 0
     84 
     85    memcpy(buff, "ABCDEFGH", 8);
     86    run_test((char *)&tolowercase, &buff, 3, 'A');   // cc = 1
     87    run_test((char *)&tolowercase, &buff, 3, 'C');   // cc = 0
     88    run_test((char *)&tolowercase, &buff, 8, 0x0);   // cc = 0
     89 
     90    memcpy(buff, "01234567", 8);
     91    run_test((char *)&touppercase, &buff, 8, 'A');
     92    run_test((char *)&tolowercase, &buff, 8, 'A');
     93    return 0;
     94 }
     95