]> git.ipfire.org Git - thirdparty/valgrind.git/commitdiff
PPC64: Add support for the darn instruction
authorCarl Love <cel@us.ibm.com>
Mon, 22 Mar 2021 22:55:05 +0000 (17:55 -0500)
committerCarl Love <cel@us.ibm.com>
Tue, 4 May 2021 15:38:48 +0000 (10:38 -0500)
12 files changed:
Makefile.all.am
NEWS
VEX/priv/guest_ppc_defs.h
VEX/priv/guest_ppc_helpers.c
VEX/priv/guest_ppc_toIR.c
configure.ac
coregrind/m_initimg/initimg-linux.c
none/tests/ppc64/Makefile.am
none/tests/ppc64/test_darn_inst.c [new file with mode: 0644]
none/tests/ppc64/test_darn_inst.stderr.exp [new file with mode: 0644]
none/tests/ppc64/test_darn_inst.stdout.exp [new file with mode: 0644]
none/tests/ppc64/test_darn_inst.vgtest [new file with mode: 0644]

index bcd29165daf155941ffef49a521098700fba5891..1b66f82ea46ab10c1f89d5188966cdd0f35b9b00 100644 (file)
@@ -125,7 +125,11 @@ AM_CFLAGS_BASE = \
 
 # Power ISA flag for use by guest_ppc_helpers.c
 if HAS_XSCVHPDP
+if HAS_DARN
+ISA_3_0_BUILD_FLAG = -DHAS_XSCVHPDP -DHAS_DARN
+else
 ISA_3_0_BUILD_FLAG = -DHAS_XSCVHPDP
+endif
 else
 ISA_3_0_BUILD_FLAG =
 endif
diff --git a/NEWS b/NEWS
index d41d529aab82a3342026a5550342eaafc8355e9e..4b4d33309cc63762b77b2be69f23fbf24dc4cec9 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -18,6 +18,7 @@ support for X86/macOS 10.13, AMD64/macOS 10.13 and nanoMIPS/Linux.
 * ppc64:
 
   - ISA 3.1 support is now complete
+  - ISA 3.0 support for the darn instruction added.
 
 * ==================== TOOL CHANGES ====================
 
@@ -34,6 +35,7 @@ are not entered into bugzilla tend to get forgotten about or ignored.
 429375  PPC ISA 3.1 support is missing, part 9
 433801  PPC ISA 3.1 support is missing, part 10 (ISA 3.1 support complete)
 433863  s390x: memcheck/tests/s390x/{cds,cs,csg} failures
+434840  PPC64 darn instruction not supported
 
 To see details of a given bug, visit
   https://bugs.kde.org/show_bug.cgi?id=XXXXXX
index d36d6c07d4a2b1eeaacb01fe51138b2c6621d0cc..3c22096673be819ae073ecb156bc5e60e5de678a 100644 (file)
@@ -272,6 +272,8 @@ extern void vsx_matrix_64bit_float_ger_dirty_helper( VexGuestPPC64State* gst,
                                                      ULong srcY_hi,
                                                      ULong srcY_lo,
                                                      UInt masks_inst );
+extern ULong darn_dirty_helper ( UInt L );
+
 #endif /* ndef __VEX_GUEST_PPC_DEFS_H */
 
 /*---------------------------------------------------------------*/
index d8131eb6075f4b928deac451df9e3c2ac9bd57a2..c7557399898e19c2d2838782758c05665dfd94ba 100644 (file)
@@ -2416,6 +2416,27 @@ void vsx_matrix_64bit_float_ger_dirty_helper( VexGuestPPC64State* gst,
    }
 }
 
+/* CALLED FROM GENERATED CODE */
+/* DIRTY HELPER uses inline assembly to call random number instruction on
+   the host machine.  Note, the dirty helper takes the value returned from
+   the host and returns it.  The helper does not change the guest state
+   or guest memory.  */
+ULong darn_dirty_helper ( UInt L )
+{
+   ULong val = 0xFFFFFFFFFFFFFFFFULL;  /* error */
+
+#  if defined (HAS_DARN)
+   if ( L == 0)
+      __asm__ __volatile__("darn  %0,0" : "=r"(val));
+   else if (L == 1)
+      __asm__ __volatile__("darn  %0,1" : "=r"(val));
+   else if (L == 2)
+      __asm__ __volatile__("darn  %0,2" : "=r"(val));
+# endif
+
+   return val;
+}
+
 /*----------------------------------------------*/
 /*--- The exported fns ..                    ---*/
 /*----------------------------------------------*/
index 469c27fe5f76a86865f3662e060c375d6f5cf964..09e9c490873b31fc55ea912ccfb153d745855904 100644 (file)
@@ -35607,6 +35607,52 @@ static Int dis_nop_prefix ( UInt prefix, UInt theInstr )
    return False;
 }
 
+static Int dis_darn ( UInt prefix, UInt theInstr,
+                      const VexAbiInfo* vbi )
+{
+   /* darn - Deliver A Random Number */
+   UInt L = IFIELD( theInstr, 16, 2);
+   UChar rD_addr = ifieldRegDS( theInstr );
+   IRTemp rD = newTemp( Ity_I64 );
+   IRDirty* d;
+
+   /* L      Format or returned value
+      0      0 || CRN_32bits
+      1      CRN_64bits       (0 to 0xFFFF_FFFF_FFFF_FFFE)
+      2      RRN_64bits       (0 to 0xFFFF_FFFF_FFFF_FFFE)
+      3      reserved
+
+      On error, return 0xFFFFFFFFFFFFFFFF
+      A CRN value is a conditioned random number that was processed
+      to to reduce bias.
+   */
+   /* There is no prefixed version of these instructions.  */
+   PREFIX_CHECK
+   DIP("darn r%u,%u\n", rD_addr, L);
+
+   if (L == 3)
+      /*  Hardware reports illegal instruction if L = 3.  */
+      return False;
+
+   IRExpr** args = mkIRExprVec_1( mkU32( L ) );
+
+   d = unsafeIRDirty_1_N (
+      rD,
+      0/*regparms*/,
+      "darn_dirty_helper",
+      fnptr_to_fnentry( vbi, &darn_dirty_helper ),
+      args );
+
+   /* Execute the dirty call, returning the result in rD. The dirty
+      helper calls the darn instruction on the host returning the
+      random number generated by the darn instruction on the host.
+      The dirty helper does not change the state of the guest or guest
+      memory.  */
+   stmt( IRStmt_Dirty(d) );
+   putIReg( rD_addr, mkexpr( rD ) );
+   return True;
+}
+
 
 /*------------------------------------------------------------*/
 /*--- Disassemble a single instruction                     ---*/
@@ -37170,6 +37216,12 @@ DisResult disInstr_PPC_WRK (
          if (dis_int_logic( prefix, theInstr )) goto decode_success;
          goto decode_failure;
 
+      case 0x2F3:                         // darn - Deliver A Random Number
+         if (!allow_isa_3_0) goto decode_noP9;
+         if (dis_darn( prefix, theInstr, abiinfo ))
+            goto decode_success;
+         goto decode_failure;
+
       case 0x28E: case 0x2AE:             // tbegin., tend.
       case 0x2EE: case 0x2CE: case 0x30E: // tsr., tcheck., tabortwc.
       case 0x32E: case 0x34E: case 0x36E: // tabortdc., tabortwci., tabortdci.
index 14a01ab7b5785d24c543f91502ada4c1601b70f2..b2f3dd91dbcb60d42fa292fb45df0b821eeb2069 100755 (executable)
@@ -1654,6 +1654,20 @@ ac_asm_have_xscvhpdp=no
 AC_MSG_RESULT([no])
 ])
 
+# darn instruction checking
+AC_MSG_CHECKING([that assembler knows darn instruction ])
+
+AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
+]], [[
+  __asm__ __volatile__("darn 1,0 ");
+]])], [
+ac_asm_have_darn_inst=yes
+AC_MSG_RESULT([yes])
+], [
+ac_asm_have_darn_inst=no
+AC_MSG_RESULT([no])
+])
+
 # isa 3.01 checking
 AC_MSG_CHECKING([that assembler knows ISA 3.1 ])
 
@@ -1673,6 +1687,7 @@ AM_CONDITIONAL(HAS_ISA_3_00, [test x$ac_asm_have_isa_3_00 = xyes \
                              -a x$HWCAP_HAS_ISA_3_00 = xyes])
 
 AM_CONDITIONAL(HAS_XSCVHPDP, [test x$ac_asm_have_xscvhpdp = xyes])
+AM_CONDITIONAL(HAS_DARN, [test x$ac_asm_have_darn_inst = xyes])
 
 AM_CONDITIONAL(HAS_ISA_3_1, [test x$ac_asm_have_isa_3_1 = xyes \
                              -a x$HWCAP_HAS_ISA_3_1 = xyes])
index 73dab34363a0bb59914d8f9861b3a1a35c79a6a2..55559b492344c24e5bc8876ab2d60553cc09a74c 100644 (file)
@@ -821,6 +821,7 @@ Addr setup_client_stack( void*  init_sp,
                               | 0x04000000ULL   /* VEC_CRYPTO */
                               | 0x00800000ULL   /* ARCH_3_00 */
                               | 0x00400000ULL   /* HAS_IEEE128 */
+                              | 0x00200000ULL   /* PPC_FEATURE2_DARN */
                               | 0x00040000ULL); /* ARCH_3_1 */
          }
 
index 38a3dc4833c958c9f45892c8879aebedd31e42a2..00c65b565402e7d75d739f142c4f65f2f30dc0f1 100644 (file)
@@ -57,7 +57,8 @@ EXTRA_DIST = \
        test_isa_3_1_Misc.vgtest test_isa_3_1_Misc.stderr.exp test_isa_3_1_Misc.stdout.exp \
        test_isa_3_1_AT.vgtest test_isa_3_1_AT.stderr.exp test_isa_3_1_AT.stdout.exp \
        subnormal_test.stderr.exp  subnormal_test.stdout.exp \
-       subnormal_test.vgtest
+       subnormal_test.vgtest test_darn_inst.stderr.exp \
+       test_darn_inst.stdout.exp test_darn_inst.vgtest
 
 check_PROGRAMS = \
        allexec \
@@ -68,7 +69,7 @@ check_PROGRAMS = \
        test_isa_3_0 test_mod_instructions \
        test_isa_3_1_RT test_isa_3_1_XT test_isa_3_1_VRT \
        test_isa_3_1_Misc test_isa_3_1_AT \
-       subnormal_test \
+       subnormal_test test_darn_inst \
        test_tm test_touch_tm data-cache-instructions \
        power6_mf_gpr std_reg_imm \
        twi_tdi tw_td power6_bcmp
@@ -188,6 +189,9 @@ test_touch_tm_CFLAGS = $(AM_CFLAGS) -Winline -Wall -O -g -mregnames $(HTM_FLAG)
 test_isa_3_0_CFLAGS = $(AM_CFLAGS) -Winline -Wall -O -g -mregnames $(HTM_FLAG) $(ISA_3_00_FLAG) \
                        @FLAG_M64@ $(BUILD_FLAGS_ISA_3_00)
 
+test_darn_inst_CFLAGS = $(AM_CFLAGS) -Winline -Wall -O -g -mregnames $(HTM_FLAG) $(ISA_3_00_FLAG) \
+                       @FLAG_M64@ $(BUILD_FLAGS_ISA_3_00)
+
 test_isa_3_1_CFLAGS = $(AM_CFLAGS) -Winline -Wall -O -g -mregnames  $(ISA_3_1_FLAG) \
                        @FLAG_M64@ $(BUILD_FLAGS_ISA_3_1)
 test_isa_3_1_RT_CFLAGS = $(test_isa_3_1_CFLAGS)
diff --git a/none/tests/ppc64/test_darn_inst.c b/none/tests/ppc64/test_darn_inst.c
new file mode 100644 (file)
index 0000000..ba828a3
--- /dev/null
@@ -0,0 +1,42 @@
+#include <stdio.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <altivec.h>
+
+#define TRUE  1
+#define FALSE 0
+#define ERROR 0xFFFFFFFFFFFFFFFFULL
+
+int main()
+{
+  unsigned long long rand;
+  int success = TRUE;
+
+  /* The random number instruction returns 0xFFFFFFFFFFFFFFFFULL on error
+     and an unsigned 64-bit value between 0 and 0xFFFFFFFFFFFFFFFEULL on
+     success.  */
+  __asm__ __volatile__ ("darn %0,0" : "=r" (rand));
+  if (rand == ERROR) {
+     success = FALSE;
+     printf ("Error darn 0 result = 0%llx not in expected range.\n", rand);
+  }
+
+  __asm__ __volatile__ ("darn %0,1" : "=r" (rand));
+  if (rand == ERROR) {
+     success = FALSE;
+     printf ("Error darn 1 result = 0%llx not in expected range.\n", rand);
+  }
+
+  __asm__ __volatile__ ("darn %0,2" : "=r" (rand));
+  if (rand == ERROR) {
+     success = FALSE;
+       printf ("Error darn 2 result = 0%llx not in expected range.\n", rand);
+  }
+
+  if (success)
+     printf("Success.\n");
+  else
+     printf("Failure.\n");
+
+  return 0;
+}
diff --git a/none/tests/ppc64/test_darn_inst.stderr.exp b/none/tests/ppc64/test_darn_inst.stderr.exp
new file mode 100644 (file)
index 0000000..139597f
--- /dev/null
@@ -0,0 +1,2 @@
+
+
diff --git a/none/tests/ppc64/test_darn_inst.stdout.exp b/none/tests/ppc64/test_darn_inst.stdout.exp
new file mode 100644 (file)
index 0000000..a9d787c
--- /dev/null
@@ -0,0 +1 @@
+Success.
diff --git a/none/tests/ppc64/test_darn_inst.vgtest b/none/tests/ppc64/test_darn_inst.vgtest
new file mode 100644 (file)
index 0000000..b72a687
--- /dev/null
@@ -0,0 +1,2 @@
+prereq: ../../../tests/check_ppc64_auxv_cap arch_3_00
+prog: test_darn_inst