Fixes #273114. Patch by Divya Vyas (divyvyas@linux.vnet.ibm.com).
git-svn-id: svn://svn.valgrind.org/valgrind/trunk@12368
247386 make perf does not run all performance tests
270796 s390x: Removed broken support for the TS insn
271438 Fix configure for proper SSE4.2 detection
+273114 s390x: Support TR, TRE, TROO, TROT, TRTO, and TRTT instructions
276993 fix mremap 'no thrash checks'
281482 valgrind's memcheck incorrect byte allocation count in realloc() for silly argument
282230 group allocator for small fixed size, use it for MC_Chunk/SEc vbit
INSN_TESTS = clc clcle cvb cvd icm lpr tcxb lam_stam xc mvst add sub mul \
and or xor insert div srst fold_And16 flogr sub_EI add_EI \
and_EI or_EI xor_EI insert_EI mul_GE add_GE condloadstore \
- op_exception fgx stck stckf stcke stfle cksm mvcl clcl troo
+ op_exception fgx stck stckf stcke stfle cksm mvcl clcl troo \
+ trto trot trtt tr tre
check_PROGRAMS = $(INSN_TESTS) \
allexec \
ex_clone.stdout.exp ex_clone.stderr.exp ex_clone.vgtest \
op00.stderr.exp1 op00.stderr.exp2 op00.vgtest \
test.h opcodes.h add.h and.h div.h insert.h \
- mul.h or.h sub.h test.h xor.h
+ mul.h or.h sub.h test.h xor.h table.h
AM_CFLAGS += @FLAG_M64@
AM_CXXFLAGS += @FLAG_M64@
AM_CCASFLAGS += @FLAG_M64@
-allexec_CFLAGS = $(AM_CFLAGS) @FLAG_W_NO_NONNULL@
+allexec_CFLAGS = $(AM_CFLAGS) @FLAG_W_NO_NONNULL@
ex_clone_LDFLAGS = -lpthread
tcxb_CFLAGS = $(AM_CFLAGS) -std=gnu99
--- /dev/null
+char touppercase[256] =
+{
+
+ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+ 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
+ 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
+ 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F,
+ 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
+ 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F,
+ 0x30, 0x31, 0x32/*50*/, 0x33, 0x34, 0x35, 0x36, 0x37,
+ 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F,
+ 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
+ 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F,
+ 0x50/*80*/, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57,
+ 0x58, 0x59, 0x5A, 0x5B, 0x5C, 0x5D, 0x5E, 0x5F,
+ 0x60, 0x41/*97*/, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
+ 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F,
+ 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57,
+ 0x58, 0x59, 0x5A, 0x5B, 0x5C, 0x5D, 0x5E, 0x5F,
+ 0x80, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7,
+ 0xC8, 0xC9, 0x8A, 0x8B, 0xAC, 0xAD, 0xAE, 0x8F,
+ 0x90, 0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7,
+ 0xD8, 0xD9, 0x9A, 0x9B, 0x9E, 0x9D, 0x9E, 0x9F,
+ 0xA0, 0xA1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7,
+ 0xE8, 0xE9, 0xAA, 0xAB, 0xAC, 0xAD, 0xAE, 0xAF,
+ 0xB0, 0xB1, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xB7,
+ 0xB8, 0xB9, 0xBA, 0xBB, 0xBC, 0xBD, 0xBE, 0xBF,
+ 0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7,
+ 0xC8, 0xC9, 0xCA, 0xEB, 0xEC, 0xED, 0xEE, 0xEF,
+ 0xD0, 0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7,
+ 0xD8, 0xD9, 0xDA, 0xFB, 0xFC, 0xFD, 0xFE, 0xDF,
+ 0xE0, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7,
+ 0xE8, 0xE9, 0xEA, 0xEB, 0xEC, 0xED, 0xEE, 0xEF,
+ 0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7,
+ 0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0xFF
+
+};
+
+char tolowercase[256] =
+{
+ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+ 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
+ 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
+ 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F,
+ 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
+ 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F,
+ 0x30, 0x31, 0x32/*50*/, 0x33, 0x34, 0x35, 0x36, 0x37,
+ 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F,
+ 0x40, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
+ 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F,
+ 0x70/*80*/, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77,
+ 0x78, 0x79, 0x7A, 0x5B, 0x5C, 0x5D, 0x5E, 0x5F,
+ 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
+ 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F,
+ 0x70, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57,
+ 0x58, 0x79, 0x7A, 0x7B, 0x7C, 0x7D, 0x7E, 0x7F,
+ 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
+ 0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E, 0x8F,
+ 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97,
+ 0x98, 0x99, 0x9A, 0x9B, 0x9C, 0x9D, 0x9C, 0x9F,
+ 0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7,
+ 0xA8, 0xA9, 0xAA, 0xAB, 0x8C, 0x8D, 0x8E, 0xAF,
+ 0xB0, 0xB1, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xB7,
+ 0xB8, 0xB9, 0xBA, 0xBB, 0xBC, 0xBD, 0xBE, 0xBF,
+ 0xC0, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
+ 0x88, 0x89, 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF,
+ 0xD0, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97,
+ 0x98, 0x99, 0xDA, 0xDB, 0xDC, 0xDD, 0xDE, 0xDF,
+ 0xE0, 0xE1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7,
+ 0xA8, 0xA9, 0xEA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF,
+ 0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7,
+ 0xF8, 0xF9, 0xFA, 0xDB, 0xDC, 0xDD, 0xDE, 0xFF
+};
+
+
--- /dev/null
+#include<stdio.h>
+#include<stdlib.h>
+#include<asm/types.h>
+#include<stdint.h>
+#include<string.h>
+#include "table.h"
+
+uint8_t buff[40];
+
+void tr(uint8_t *codepage, uint8_t *addr, uint64_t len)
+{
+ asm volatile(
+ " larl 1,1f\n"
+ "1: tr 0(1,%0),0(%2)\n"
+ " ex %1,0(1)"
+ : "+&a" (addr), "+d" (len)
+ : "a" (codepage) : "cc", "memory", "1");
+}
+
+void run_test(void *tran_table, void *srcaddr, uint64_t len)
+{
+ int i;
+
+ tr(tran_table, buff, len);
+ printf("the translated string is ");
+ for (i = 0; i < len; i++) {
+ printf("%c", buff[i]);
+ }
+ printf("\n");
+}
+
+int main()
+{
+ /* Test 1: length = 0 */
+ run_test((char *)&touppercase, &buff, 0);
+ run_test((char *)&touppercase, &buff, 0);
+
+ /* Test 2 : length > 0 */
+ memset(buff, 'a', 1);
+ run_test((char *)&touppercase, &buff, 1);
+
+ memcpy(buff, "abcdefgh", 8);
+ run_test((char *)&touppercase, &buff, 3);
+ run_test((char *)&touppercase, &buff, 3);
+ run_test((char *)&touppercase, &buff, 8);
+
+ memcpy(buff, "ABCDEFGH", 8);
+ run_test((char *)&tolowercase, &buff, 3);
+ run_test((char *)&tolowercase, &buff, 3);
+ run_test((char *)&tolowercase, &buff, 8);
+
+ memcpy(buff, "0123456789", 9);
+ run_test((char *)&touppercase, &buff, 9);
+ run_test((char *)&tolowercase, &buff, 9);
+ return 0;
+}
--- /dev/null
+the translated string is
+the translated string is
+the translated string is A
+the translated string is ABC
+the translated string is ABC
+the translated string is ABCDEFGH
+the translated string is abc
+the translated string is abc
+the translated string is abcdefgh
+the translated string is 012345678
+the translated string is 012345678
--- /dev/null
+#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, buff, 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;
+}
--- /dev/null
+source address/length not updated properly
+Resulting cc is 0 and the string is
+Resulting cc is 0 and the string is
+Resulting cc is 0 and the string is
+Resulting cc is 1 and the string is a
+Resulting cc is 0 and the string is A
+Resulting cc is 1 and the string is abc
+Resulting cc is 0 and the string is ABC
+Resulting cc is 0 and the string is ABCDEFGH
+Resulting cc is 1 and the string is ABC
+Resulting cc is 1 and the string is abC
+Resulting cc is 0 and the string is abcdefgh
+Resulting cc is 0 and the string is 01234567
+Resulting cc is 0 and the string is 01234567
/* Register contents after executing an TROO insn */
typedef struct {
- uint64_t srcaddr;
- uint64_t len;
- uint64_t desaddr;
- uint64_t tabaddr;
- uint8_t testbyte;
- uint64_t cc;
+ uint64_t srcaddr;
+ uint64_t len;
+ uint64_t desaddr;
+ uint64_t tabaddr;
+ uint8_t testbyte;
+ uint64_t cc;
} troo_regs;
uint8_t tran_table[20] = {
--- /dev/null
+#include<stdio.h>
+#include<stdint.h>
+#include<string.h>
+#include<assert.h>
+
+/* Register contents after executing an TROT insn */
+typedef struct {
+ uint64_t srcaddr;
+ uint64_t len;
+ uint64_t desaddr;
+ uint64_t tabaddr;
+ uint16_t testbyte;
+ uint64_t cc;
+} trot_regs;
+
+uint16_t tran_table[40] = {
+ 0xaaaa,0xbbbb,0xcccc,0xccdd,0xffff,0xdada,0xbcbc,0xabab,0xcaca,0xeaea,
+ 0xbbbb,0xeeee
+};
+
+uint8_t src[40] = {
+ 0x01,0x03,0x04,0x02,0x07,0x08,0x06,0x02,0x05,0x09
+};
+
+uint16_t des[40];
+
+trot_regs tr(uint8_t *addr, uint16_t *codepage, uint16_t *dest, uint64_t len,
+ uint16_t test)
+{
+ trot_regs regs;
+ register uint64_t test_byte asm("0") = test;
+ register uint64_t length asm("3") = len;
+ register uint64_t srcaddr asm("4") = (uint64_t)addr;
+ register uint64_t codepage2 asm("1") = (uint64_t)codepage;
+ register uint64_t desaddr asm("2") = (uint64_t)dest;
+ register uint64_t cc asm("5");
+
+ cc = 2; /* cc result will never be 2 */
+ asm volatile(
+ " trot %1,%2\n"
+ " ipm %0\n"
+ " srl %0,28\n"
+ : "=d"(cc),"+&d"(desaddr)
+ : "d" (srcaddr),"d"(test_byte),"d" (codepage2),"d"(length)
+ : "memory" );
+
+ regs.srcaddr = srcaddr;
+ regs.len = length;
+ regs.desaddr = desaddr;
+ regs.tabaddr = codepage2;
+ regs.testbyte = test_byte;
+ regs.cc = cc;
+ return regs;
+}
+
+int run_test(void *srcaddr, void *tableaddr, void *desaddr, uint64_t len,
+ uint16_t testbyte)
+{
+ trot_regs regs;
+ int i;
+
+ assert(len <= sizeof src);
+
+ if ((testbyte & 0xffff) != testbyte)
+ printf("testbyte should be 2 byte only\n");
+
+ regs = tr(srcaddr, tableaddr, desaddr, len, testbyte);
+
+ if ((uint64_t)tableaddr != regs.tabaddr)
+ printf("translation table address changed\n");
+ if ((uint64_t)srcaddr + (len - regs.len) != regs.srcaddr)
+ printf("source address/length not updated properly\n");
+ if ((uint64_t)desaddr + 2*(len - regs.len) != regs.desaddr)
+ printf("destination address/length not updated properly\n");
+ if (regs.cc == 0 && regs.len != 0)
+ printf("length is not zero but cc is zero\n");
+ printf("%u bytes translated\n", (unsigned)(len - regs.len));
+ printf("the translated values is");
+ for (i = 0; i < len; i++) {
+ printf(" %hx", des[i]);
+ }
+ printf("\n");
+
+ return regs.cc;
+}
+
+
+int main()
+{
+ int cc;
+
+ assert(sizeof des >= sizeof src);
+
+ /* Test 1 : len == 0 */
+ cc = run_test(NULL, NULL, NULL, 0, 0x0);
+ if (cc != 0)
+ printf("cc not updated properly:%d", cc);
+
+ cc = run_test(&src, &tran_table, &des, 0, 0x0);
+ if (cc != 0)
+ printf("cc not updated properly:%d",cc);
+
+ cc = run_test(&src, &tran_table, &des, 0, 0xcaca);
+ if (cc != 0)
+ printf("cc not updated properly:%d",cc);
+
+ /* Test 2 : len > 0, testbyte not matching */
+ cc = run_test(&src, &tran_table, &des, 3, 0xeeee);
+ if (cc != 0)
+ printf("cc not updated properly:%d",cc);
+
+ cc = run_test(&src, &tran_table, &des, 10, 0xeeee);
+ if (cc != 0)
+ printf("cc not updated properly:%d",cc);
+
+ memset((uint16_t *)&des, 0, 10);
+
+ /* Test 3 : len > 0 , testbyte matching */
+ cc = run_test(&src, &tran_table, &des, 5, 0xffff);
+ if (cc != 1)
+ printf("cc not updated properly:%d",cc);
+
+ cc = run_test(&src, &tran_table, &des, 5, 0xcccc);
+ if (cc != 1)
+ printf("cc not updated properly:%d",cc);
+
+ cc = run_test(&src, &tran_table, &des, 10, 0xeaea);
+ if (cc != 1)
+ printf("cc not updated properly:%d",cc);
+
+ return 0;
+}
--- /dev/null
+0 bytes translated
+the translated values is
+0 bytes translated
+the translated values is
+0 bytes translated
+the translated values is
+3 bytes translated
+the translated values is bbbb ccdd ffff
+10 bytes translated
+the translated values is bbbb ccdd ffff cccc abab caca bcbc cccc dada eaea
+2 bytes translated
+the translated values is bbbb ccdd 0 0 0
+3 bytes translated
+the translated values is bbbb ccdd ffff 0 0
+9 bytes translated
+the translated values is bbbb ccdd ffff cccc abab caca bcbc cccc dada eaea
--- /dev/null
+prog: trot
--- /dev/null
+#include<stdio.h>
+#include<stdint.h>
+#include<assert.h>
+#include<string.h>
+
+/* Register contents after executing an TRTO insn */
+typedef struct {
+ uint64_t srcaddr;
+ uint64_t len;
+ uint64_t desaddr;
+ uint64_t tabaddr;
+ uint8_t testbyte;
+ uint64_t cc;
+} trto_regs;
+
+uint8_t tran_table[40] = {
+ 0xaa,0xbb,0xcc,0xdd,0xff,0xdd,0xbc,0xab,0xca,0xea,0xbb,0xee
+};
+
+int16_t src[40] = {
+ 0x2,0x03,0x04,0x02,0x07,0x08,0x06,0x02,0x05,0x09
+};
+
+uint8_t des[20];
+
+trto_regs tr(uint16_t *addr, uint16_t *codepage, uint8_t *dest, uint64_t len,
+ uint8_t test)
+{
+ trto_regs regs;
+ register uint64_t test_byte asm("0") = test;
+ register uint64_t length asm("3") = len;
+ register uint64_t srcaddr asm("4") = (uint64_t)addr;
+ register uint64_t codepage2 asm("1") = (uint64_t)codepage;
+ register uint64_t desaddr asm("2") = (uint64_t)dest;
+ register uint64_t cc asm("5");
+
+ cc = 2; /* cc result will never be 2 */
+ asm volatile(
+ " trto %1,%2\n"
+ " ipm %0\n"
+ " srl %0,28\n"
+ : "=d"(cc),"+&d"(desaddr)
+ : "d" (srcaddr),"d"(test_byte),"d" (codepage2),"d"(length)
+ : "memory" );
+
+ regs.srcaddr = srcaddr;
+ regs.len = length;
+ regs.desaddr = desaddr;
+ regs.tabaddr = codepage2;
+ regs.testbyte = test_byte;
+ regs.cc = cc;
+ return regs;
+}
+
+int run_test(void *srcaddr, void *tableaddr, void *desaddr, uint64_t len,
+ uint8_t testbyte)
+{
+ trto_regs regs;
+ int i;
+
+ assert(len <= sizeof src);
+
+ if ((testbyte & 0xffff) != testbyte)
+ printf("testbyte should be 1 byte only\n");
+
+ regs = tr(srcaddr, tableaddr, desaddr, len, testbyte);
+
+ if ((uint64_t)tableaddr != regs.tabaddr)
+ printf("translation table address changed\n");
+ if ((uint64_t)srcaddr + (len - regs.len) != regs.srcaddr)
+ printf("source address/length not updated properly\n");
+ if ((uint64_t)desaddr + ((len - regs.len)/2) != regs.desaddr)
+ printf("destination address/length not updated properly\n");
+ if (regs.cc == 0 && regs.len != 0)
+ printf("length is not zero but cc is zero\n");
+ printf("%u bytes translated\n", ((unsigned)(len - regs.len)/2));
+ printf("the translated values is");
+ for (i = 0; i < len/2; i++) {
+ printf(" %x", des[i]);
+ }
+ printf("\n");
+
+ return regs.cc;
+}
+
+int main()
+{
+ int cc;
+
+ assert(sizeof des <= sizeof src);
+
+ /* Test 1 : len == 0 */
+ cc = run_test(NULL, NULL, NULL, 0, 0x0);
+ if (cc != 0)
+ printf("cc not updated properly:%d", cc);
+
+ cc = run_test(&src, &tran_table, &des, 0, 0x0);
+ if (cc != 0)
+ printf("cc not updated properly:%d",cc);
+
+ cc = run_test(&src, &tran_table, &des, 0, 0xca);
+ if (cc != 0)
+ printf("cc not updated properly:%d",cc);
+
+ /* Test 2 : len > 0, testbyte not matching */
+ cc = run_test(&src, &tran_table, &des, 12, 0xee);
+ if (cc != 0)
+ printf("cc not updated properly:%d",cc);
+
+ cc = run_test(&src, &tran_table, &des, 20, 0x00);
+ if (cc != 0)
+ printf("cc not updated properly:%d",cc);
+
+ memset((uint16_t *)&des, 0, 10);
+
+ /* Test 3 : len > 0 , testbyte matching */
+ cc = run_test(&src, &tran_table, &des, 12, 0xff);
+ if (cc != 1)
+ printf("cc not updated properly:%d",cc);
+
+ cc = run_test(&src, &tran_table, &des, 12, 0xcc);
+ if (cc != 1)
+ printf("cc not updated properly:%d",cc);
+
+ cc = run_test(&src, &tran_table, &des, 20, 0xea);
+ if (cc != 1)
+ printf("cc not updated properly:%d",cc);
+
+ return 0;
+}
--- /dev/null
+0 bytes translated
+the translated values is
+0 bytes translated
+the translated values is
+0 bytes translated
+the translated values is
+6 bytes translated
+the translated values is cc dd ff cc ab ca
+10 bytes translated
+the translated values is cc dd ff cc ab ca bc cc dd ea
+2 bytes translated
+the translated values is cc dd 0 0 0 0
+0 bytes translated
+the translated values is cc dd 0 0 0 0
+9 bytes translated
+the translated values is cc dd ff cc ab ca bc cc dd 0
--- /dev/null
+prog: trto
--- /dev/null
+#include<stdio.h>
+#include<stdint.h>
+#include<string.h>
+#include<assert.h>
+
+/* Register contents after executing an TRTT insn */
+typedef struct {
+ uint64_t srcaddr;
+ uint64_t len;
+ uint64_t desaddr;
+ uint64_t tabaddr;
+ uint16_t testbyte;
+ uint64_t cc;
+} trtt_regs;
+
+uint16_t tran_table[40] = {
+ 0xaaaa,0xcccc,0xcccc,0xdddd,0xffff,0xdada,0xbcbc,0xabab,0xcaca,0xeaea,
+ 0xbbbb,0xeeee
+};
+
+uint16_t src[40] = {
+ 0x4,0x03,0x04,0x02,0x07,0x08,0x06,0x02,0x05,0x09,0xa
+};
+
+uint16_t des[20];
+
+trtt_regs tr(uint16_t *addr, uint16_t *codepage, uint16_t *dest, uint64_t len,
+ uint16_t test)
+{
+ trtt_regs regs;
+ register uint64_t test_byte asm("0") = test;
+ register uint64_t length asm("3") = len;
+ register uint64_t srcaddr asm("4") = (uint64_t)addr;
+ register uint64_t codepage2 asm("1") = (uint64_t)codepage;
+ register uint64_t desaddr asm("2") = (uint64_t)dest;
+ register uint64_t cc asm("5");
+
+ cc = 2; /* cc result will never be 2 */
+ asm volatile(
+ " trtt %1,%2\n"
+ " ipm %0\n"
+ " srl %0,28\n"
+ : "=d"(cc),"+d"(desaddr),"+d"(srcaddr)
+ : "d"(test_byte),"d" (codepage2),"d"(length)
+ : "memory" );
+
+ regs.srcaddr = srcaddr;
+ regs.len = length;
+ regs.desaddr = desaddr;
+ regs.tabaddr = codepage2;
+ regs.testbyte = test_byte;
+ regs.cc = cc;
+
+ return regs;
+}
+
+int run_test(void *srcaddr, void *tableaddr, void *desaddr, uint64_t len,
+ uint16_t testbyte)
+{
+ trtt_regs regs;
+ int i;
+
+ assert(len <= sizeof src);
+
+ if ((testbyte & 0xffff) != testbyte)
+ printf("testbyte should be 2 byte only\n");
+
+ regs = tr(srcaddr, tableaddr, desaddr, len, testbyte);
+
+ if ((uint64_t)tableaddr != regs.tabaddr)
+ printf("translation table address changed\n");
+ if ((uint64_t)srcaddr + (len - regs.len) != regs.srcaddr)
+ printf("source address/length not updated properly\n");
+ if ((uint64_t)desaddr + (len - regs.len) != regs.desaddr)
+ printf("destination address/length not updated properly\n");
+ if (regs.cc == 0 && regs.len != 0)
+ printf("length is not zero but cc is zero\n");
+ printf("%u bytes translated\n", ((unsigned)(len - regs.len))/2);
+ printf("the translated values is");
+ for (i = 0; i < len/2; i++) {
+ printf(" %hx", des[i]);
+ }
+ printf("\n");
+
+ return regs.cc;
+}
+
+
+int main()
+{
+ int cc;
+
+ assert(sizeof des <= sizeof src);
+
+ /* Test 1 : len == 0 */
+ cc = run_test(NULL, NULL, NULL, 0, 0x0);
+ if (cc != 0)
+ printf("cc not updated properly:%d", cc);
+
+ cc = run_test(&src, &tran_table, &des, 0, 0x0);
+ if (cc != 0)
+ printf("cc not updated properly:%d",cc);
+
+ cc = run_test(&src, &tran_table, &des, 0, 0xcaca);
+ if (cc != 0)
+ printf("cc not updated properly:%d",cc);
+
+ /* Test 2 : len > 0, testbyte not matching */
+ cc = run_test(&src, &tran_table, &des, 4, 0xdada);
+ if (cc != 0)
+ printf("cc not updated properly:%d",cc);
+
+ cc = run_test(&src, &tran_table, &des, 10, 0x00);
+ if (cc != 0)
+ printf("cc not updated properly:%d",cc);
+
+ memset((uint16_t *)&des, 0, 10);
+
+ /* Test 3 : len > 0 , testbyte matching */
+ cc = run_test(&src, &tran_table, &des, 10, 0xffff);
+ if (cc != 1)
+ printf("cc not updated properly:%d",cc);
+
+ cc = run_test(&src, &tran_table, &des, 10, 0xcccc);
+ if (cc != 1)
+ printf("cc not updated properly:%d",cc);
+
+ cc = run_test(&src, &tran_table, &des, 20, 0xeaea);
+ if (cc != 1)
+ printf("cc not updated properly:%d",cc);
+
+ return 0;
+}
--- /dev/null
+0 bytes translated
+the translated values is
+0 bytes translated
+the translated values is
+0 bytes translated
+the translated values is
+2 bytes translated
+the translated values is ffff dddd
+5 bytes translated
+the translated values is ffff dddd ffff cccc abab
+0 bytes translated
+the translated values is 0 0 0 0 0
+3 bytes translated
+the translated values is ffff dddd ffff 0 0
+9 bytes translated
+the translated values is ffff dddd ffff cccc abab caca bcbc cccc dada 0
--- /dev/null
+prog: trtt