• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
tre(uint8_t * codepage,uint8_t * addr,uint64_t len,uint8_t test_byte)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 
run_test(void * tran_table,void * srcaddr,uint64_t len,uint8_t test)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 
main()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