diff --git a/NEWS b/NEWS index 161441e16..ef1fce7ba 100644 --- a/NEWS +++ b/NEWS @@ -58,6 +58,7 @@ are not entered into bugzilla tend to get forgotten about or ignored. 441534 Update the expected output for test_isa_3_1_VRT. 442061 very slow execution under Fedora 34 (readdwarf3) 443031 Gcc -many change requires explicit .machine directives +443033 Add support for the ISA 3.0 mcrxrx instruction To see details of a given bug, visit https://bugs.kde.org/show_bug.cgi?id=XXXXXX diff --git a/none/tests/ppc64/Makefile.am b/none/tests/ppc64/Makefile.am index 1e5398575..bf95bfe41 100644 --- a/none/tests/ppc64/Makefile.am +++ b/none/tests/ppc64/Makefile.am @@ -60,7 +60,8 @@ EXTRA_DIST = \ test_darn_inst.stdout.exp test_darn_inst.vgtest \ scv_test.stderr.exp scv_test.stdout.exp scv_test.vgtest \ test_copy_paste.stderr.exp test_copy_paste.stdout.exp \ - test_copy_paste.vgtest + test_copy_paste.vgtest \ + test_mcrxrx.vgtest test_mcrxrx.stderr.exp test_mcrxrx.stdout.exp check_PROGRAMS = \ @@ -75,7 +76,8 @@ check_PROGRAMS = \ subnormal_test test_darn_inst test_copy_paste \ test_tm test_touch_tm data-cache-instructions \ std_reg_imm \ - twi_tdi tw_td power6_bcmp scv_test + twi_tdi tw_td power6_bcmp scv_test \ + test_mcrxrx # lmw, stmw, lswi, lswx, stswi, stswx compile (and run) only on big endian. if VGCONF_PLATFORMS_INCLUDE_PPC64BE_LINUX @@ -221,6 +223,8 @@ subnormal_test_CFLAGS = $(AM_CFLAGS) -Winline -Wall -O -g -mregnames $(VSX_FLAG) test_copy_paste_CFLAGS = $(AM_CFLAGS) -Winline -Wall -O -g -mregnames $(HTM_FLAG) $(ISA_3_1_FLAG) \ @FLAG_M64@ $(BUILD_FLAGS_ISA_3_1) +test_mcrxrx_CFLAGS = $(AM_FLAGS) -Winline -Wall -O -g -mregnames @FLAG_M64@ $(ISA_3_00_FLAG) + test_isa_2_06_part3_LDADD = -lm test_dfp1_LDADD = -lm test_dfp2_LDADD = -lm @@ -232,4 +236,5 @@ test_isa_2_07_part2_LDADD = -lm test_tm_LDADD = -lm test_touch_tm_LDADD = -lm test_isa_3_0_LDADD = -lm +test_mcrxrx_LDADD = -lm diff --git a/none/tests/ppc64/test_mcrxrx.c b/none/tests/ppc64/test_mcrxrx.c new file mode 100644 index 000000000..50aa40239 --- /dev/null +++ b/none/tests/ppc64/test_mcrxrx.c @@ -0,0 +1,113 @@ +/* + * Valgrind testcase for mcrxrx. + * This is a power9 (isa 3.0) instruction that copies + * OV,OV32,CA,CA32 fields from the XER and places them + * into a specified field of the CR. */ + +#include +#include +#include + +unsigned long long current_cr; +unsigned long long current_xer; + +inline static void dissect_cr_field (unsigned long long full_cr, int offset) { + int mask; + int crfield; + mask = 0xf << (offset*4); + crfield = full_cr & mask; + crfield = crfield >> 4*offset; + + if (crfield & 0x01) printf("(LT)"); else printf(" - "); + if (crfield & 0x02) printf("(GT)"); else printf(" - "); + if (crfield & 0x04) printf("(EQ)"); else printf(" - "); + if (crfield & 0x08) printf("(SO)"); else printf(" - "); +} + +/* dissect_xer helpers */ +static char * xer_strings[] = { + " 0-RSVD", " 1-RSVD", " 2-RSVD", " 3-RSVD", " 4-RSVD", " 5-RSVD", " 6-RSVD", + " 7-RSVD", " 8-RSVD", " 9-RSVD", "10-RSVD", "11-RSVD", "12-RSVD", "13-RSVD", + "14-RSVD", "15-RSVD", "16-RSVD", "17-RSVD", "18-RSVD", "19-RSVD", + "20-RSVD", "21-RSVD", "22-RSVD", "23-RSVD", "24-RSVD", "25-RSVD", + "26-RSVD", "27-RSVD", "28-RSVD", "29-RSVD", "30-RSVD", "31-RSVD", + /* 32 */ "SO", "OV", "CA", + /* 35 */ "35-RSVD", "36-RSVD", "37-RSVD", "38-RSVD", "39-RSVD", + /* 40 */ "40-RSVD", "41-RSVD", "42-RSVD", "43-RSVD", + /* 44 */ "OV32", "CA32", + /* 46 */ "46-RSVD", "47-RSVD", "48-RSVD", "49-RSVD", "50-RSVD", "51-RSVD", + "52-RSVD", "53-RSVD", "54-RSVD", "55-RSVD", "56-RSVD", + /* 57:63 # bytes transferred by a Load/Store String Indexed instruction. */ + "LSI/SSI-0", "LSI/SSI-1", "LSI/SSI-2", "LSI/SSI-3", + "LSI/SSI-4", "LSI/SSI-5", "LSI/SSI-6", +}; + +/* Dissect the XER register contents. +*/ +static void dissect_xer_raw(unsigned long local_xer) { + int i; + long mybit; + char mystr[30]; + strcpy(mystr,""); + for (i = 0; i <= 63; i++) { + mybit = 1ULL << (63 - i); /* compensate for reversed bit numbering. */ + if (mybit & local_xer) { + strcat(mystr,xer_strings[i]); + strcat(mystr," "); + } + } + printf(" %16s",mystr); +} + +int main (int argc, char **argv) +{ +#if HAS_ISA_3_00 + /* init xer to zero. */ + unsigned long long Rx = 0; + __asm__ __volatile__ ("mtxer %0" : : "r" (Rx) :"xer"); + + /* iterate over each of the interesting fields in the xer + * OV,CA,OV32,CA32. Build a field with those bits set, and + * push that into the XER (mtxer). */ + unsigned long long i18,i19,i29,i30; + for (i30=0; i30<2; i30++) { // iterate OV + for (i29=0; i29<2; i29++) { // iterate CA + for (i19=0; i19<2; i19++) { // iterate OV32 + for (i18=0; i18<2; i18++) { // iterate CA32 + Rx = i18 << 18; + Rx += i19 << 19; + Rx += i29 << 29; + Rx += i30 << 30; + + printf("mcrxrx "); + + /* move 'Rx' value into the xer. */ + __asm__ __volatile__ ("mtxer %0" : : "r" (Rx) :"xer"); + + /* Retrieve the XER and print it. */ + __asm__ __volatile__ ("mfxer %0" : "=b"(current_xer) ); + + /* Moving the xer contents to the CR field # 2 + * using the mcrxr instruction. */ + __asm__ __volatile__ (".machine push;" \ + ".machine power9;" \ + "mcrxrx 2;" \ + ".machine pop;" ); + + /* Copy the cr into a reg so we can print it.. */ + __asm__ __volatile__ ("mfcr %0" : "=b"(current_cr) ); + + dissect_xer_raw(current_xer); + printf(" => "); + dissect_cr_field(current_cr,5); + printf("\n"); + } + } + } + } +#else + printf("HAS_ISA_3_00 not detected.\n"); +#endif + return 0; +} + diff --git a/none/tests/ppc64/test_mcrxrx.stderr.exp b/none/tests/ppc64/test_mcrxrx.stderr.exp new file mode 100644 index 000000000..139597f9c --- /dev/null +++ b/none/tests/ppc64/test_mcrxrx.stderr.exp @@ -0,0 +1,2 @@ + + diff --git a/none/tests/ppc64/test_mcrxrx.stdout.exp b/none/tests/ppc64/test_mcrxrx.stdout.exp new file mode 100644 index 000000000..c9ad72e6d --- /dev/null +++ b/none/tests/ppc64/test_mcrxrx.stdout.exp @@ -0,0 +1,16 @@ +mcrxrx => - - - - +mcrxrx CA32 => (LT) - - - +mcrxrx OV32 => - - (EQ) - +mcrxrx OV32 CA32 => (LT) - (EQ) - +mcrxrx CA => - (GT) - - +mcrxrx CA CA32 => (LT)(GT) - - +mcrxrx CA OV32 => - (GT)(EQ) - +mcrxrx CA OV32 CA32 => (LT)(GT)(EQ) - +mcrxrx OV => - - - (SO) +mcrxrx OV CA32 => (LT) - - (SO) +mcrxrx OV OV32 => - - (EQ)(SO) +mcrxrx OV OV32 CA32 => (LT) - (EQ)(SO) +mcrxrx OV CA => - (GT) - (SO) +mcrxrx OV CA CA32 => (LT)(GT) - (SO) +mcrxrx OV CA OV32 => - (GT)(EQ)(SO) +mcrxrx OV CA OV32 CA32 => (LT)(GT)(EQ)(SO) diff --git a/none/tests/ppc64/test_mcrxrx.vgtest b/none/tests/ppc64/test_mcrxrx.vgtest new file mode 100644 index 000000000..6713503d5 --- /dev/null +++ b/none/tests/ppc64/test_mcrxrx.vgtest @@ -0,0 +1,2 @@ +prereq: ../../../tests/check_ppc64_auxv_cap arch_3_00 +prog: test_mcrxrx