| #include<stdio.h> |
| #include<stdlib.h> |
| #include<stdint.h> |
| #include<inttypes.h> |
| #include<string.h> |
| #include "table.h" |
| |
| /* Register contents after executing an TRE insn */ |
| typedef struct { |
| uint64_t addr; |
| uint64_t len; |
| uint64_t tabaddr; |
| uint8_t testbyte; |
| uint64_t cc; |
| } tre_regs; |
| |
| uint8_t buff[40]; |
| |
| tre_regs tre(uint8_t *codepage, uint8_t *addr, uint64_t len, uint8_t test_byte) |
| { |
| int cc; |
| tre_regs regs; |
| |
| register uint64_t param asm("0") = test_byte; |
| register uint64_t a2 asm ("4") = (uint64_t)codepage; |
| register uint64_t a1 asm ("2") = (uint64_t)addr; |
| register uint64_t l1 asm ("3") = len; |
| |
| asm volatile( |
| " tre %1,%2\n" |
| " ipm %0\n" |
| " srl %0,28\n" |
| :"=d"(cc),"+&d"(a1) |
| :"d"(a2),"d"(param),"d"(l1),"d"(test_byte): "memory" ); |
| |
| regs.addr = a1; |
| regs.len = l1; |
| regs.tabaddr = a2; |
| regs.testbyte = param; |
| regs.cc = cc; |
| |
| return regs; |
| } |
| |
| void run_test(void *tran_table, void *srcaddr, uint64_t len, uint8_t test) |
| { |
| tre_regs regs; |
| int i; |
| |
| regs = tre(tran_table, srcaddr, len, test); |
| |
| if ((uint64_t)tran_table != regs.tabaddr) |
| printf("translation table address changed\n"); |
| if (test != regs.testbyte) |
| printf("test byte changed\n"); |
| if ((uint64_t)srcaddr + (len - regs.len) != regs.addr) |
| printf("source address/length not updated properly\n"); |
| |
| printf("Resulting cc is %"PRIu64" and the string is ", regs.cc); |
| for ( i = 0; i < len; i++) { |
| printf("%c", buff[i]); |
| } |
| |
| printf("\n"); |
| } |
| |
| int main() |
| { |
| |
| /* Test 1: length = 0 */ |
| run_test(NULL, NULL, 0, 0x0); |
| run_test((char *)&touppercase, &buff, 0, 0x0); |
| run_test((char *)&touppercase, &buff, 0, 'b'); |
| |
| /* Test 2 : length > 0 */ |
| memset(buff, 'a', 1); |
| run_test((char *)&touppercase, &buff, 1, 'a'); //cc = 1 |
| run_test((char *)&touppercase, &buff, 1, 'b'); |
| |
| memcpy(buff, "abcdefgh", 8); |
| run_test((char *)&touppercase, &buff, 3, 'a'); //cc = 1 |
| run_test((char *)&touppercase, &buff, 3, 'f'); //cc = 0 |
| run_test((char *)&touppercase, &buff, 8, 'l'); //cc = 0 |
| |
| memcpy(buff, "ABCDEFGH", 8); |
| run_test((char *)&tolowercase, &buff, 3, 'A'); // cc = 1 |
| run_test((char *)&tolowercase, &buff, 3, 'C'); // cc = 0 |
| run_test((char *)&tolowercase, &buff, 8, 0x0); // cc = 0 |
| |
| memcpy(buff, "01234567", 8); |
| run_test((char *)&touppercase, &buff, 8, 'A'); |
| run_test((char *)&tolowercase, &buff, 8, 'A'); |
| return 0; |
| } |