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