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 */
9typedef 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
17uint8_t buff[40];
18
19tre_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
45void 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
67int 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