# 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
* ppc64:
- ISA 3.1 support is now complete
+ - ISA 3.0 support for the darn instruction added.
* ==================== TOOL CHANGES ====================
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
ULong srcY_hi,
ULong srcY_lo,
UInt masks_inst );
+extern ULong darn_dirty_helper ( UInt L );
+
#endif /* ndef __VEX_GUEST_PPC_DEFS_H */
/*---------------------------------------------------------------*/
}
}
+/* 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 .. ---*/
/*----------------------------------------------*/
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 ---*/
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.
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 ])
-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])
| 0x04000000ULL /* VEC_CRYPTO */
| 0x00800000ULL /* ARCH_3_00 */
| 0x00400000ULL /* HAS_IEEE128 */
+ | 0x00200000ULL /* PPC_FEATURE2_DARN */
| 0x00040000ULL); /* ARCH_3_1 */
}
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 \
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
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)
--- /dev/null
+#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;
+}
--- /dev/null
+prereq: ../../../tests/check_ppc64_auxv_cap arch_3_00
+prog: test_darn_inst