You can subscribe to this list here.
| 2002 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
(1) |
Oct
(122) |
Nov
(152) |
Dec
(69) |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 2003 |
Jan
(6) |
Feb
(25) |
Mar
(73) |
Apr
(82) |
May
(24) |
Jun
(25) |
Jul
(10) |
Aug
(11) |
Sep
(10) |
Oct
(54) |
Nov
(203) |
Dec
(182) |
| 2004 |
Jan
(307) |
Feb
(305) |
Mar
(430) |
Apr
(312) |
May
(187) |
Jun
(342) |
Jul
(487) |
Aug
(637) |
Sep
(336) |
Oct
(373) |
Nov
(441) |
Dec
(210) |
| 2005 |
Jan
(385) |
Feb
(480) |
Mar
(636) |
Apr
(544) |
May
(679) |
Jun
(625) |
Jul
(810) |
Aug
(838) |
Sep
(634) |
Oct
(521) |
Nov
(965) |
Dec
(543) |
| 2006 |
Jan
(494) |
Feb
(431) |
Mar
(546) |
Apr
(411) |
May
(406) |
Jun
(322) |
Jul
(256) |
Aug
(401) |
Sep
(345) |
Oct
(542) |
Nov
(308) |
Dec
(481) |
| 2007 |
Jan
(427) |
Feb
(326) |
Mar
(367) |
Apr
(255) |
May
(244) |
Jun
(204) |
Jul
(223) |
Aug
(231) |
Sep
(354) |
Oct
(374) |
Nov
(497) |
Dec
(362) |
| 2008 |
Jan
(322) |
Feb
(482) |
Mar
(658) |
Apr
(422) |
May
(476) |
Jun
(396) |
Jul
(455) |
Aug
(267) |
Sep
(280) |
Oct
(253) |
Nov
(232) |
Dec
(304) |
| 2009 |
Jan
(486) |
Feb
(470) |
Mar
(458) |
Apr
(423) |
May
(696) |
Jun
(461) |
Jul
(551) |
Aug
(575) |
Sep
(134) |
Oct
(110) |
Nov
(157) |
Dec
(102) |
| 2010 |
Jan
(226) |
Feb
(86) |
Mar
(147) |
Apr
(117) |
May
(107) |
Jun
(203) |
Jul
(193) |
Aug
(238) |
Sep
(300) |
Oct
(246) |
Nov
(23) |
Dec
(75) |
| 2011 |
Jan
(133) |
Feb
(195) |
Mar
(315) |
Apr
(200) |
May
(267) |
Jun
(293) |
Jul
(353) |
Aug
(237) |
Sep
(278) |
Oct
(611) |
Nov
(274) |
Dec
(260) |
| 2012 |
Jan
(303) |
Feb
(391) |
Mar
(417) |
Apr
(441) |
May
(488) |
Jun
(655) |
Jul
(590) |
Aug
(610) |
Sep
(526) |
Oct
(478) |
Nov
(359) |
Dec
(372) |
| 2013 |
Jan
(467) |
Feb
(226) |
Mar
(391) |
Apr
(281) |
May
(299) |
Jun
(252) |
Jul
(311) |
Aug
(352) |
Sep
(481) |
Oct
(571) |
Nov
(222) |
Dec
(231) |
| 2014 |
Jan
(185) |
Feb
(329) |
Mar
(245) |
Apr
(238) |
May
(281) |
Jun
(399) |
Jul
(382) |
Aug
(500) |
Sep
(579) |
Oct
(435) |
Nov
(487) |
Dec
(256) |
| 2015 |
Jan
(338) |
Feb
(357) |
Mar
(330) |
Apr
(294) |
May
(191) |
Jun
(108) |
Jul
(142) |
Aug
(261) |
Sep
(190) |
Oct
(54) |
Nov
(83) |
Dec
(22) |
| 2016 |
Jan
(49) |
Feb
(89) |
Mar
(33) |
Apr
(50) |
May
(27) |
Jun
(34) |
Jul
(53) |
Aug
(53) |
Sep
(98) |
Oct
(206) |
Nov
(93) |
Dec
(53) |
| 2017 |
Jan
(65) |
Feb
(82) |
Mar
(102) |
Apr
(86) |
May
(187) |
Jun
(67) |
Jul
(23) |
Aug
(93) |
Sep
(65) |
Oct
(45) |
Nov
(35) |
Dec
(17) |
| 2018 |
Jan
(26) |
Feb
(35) |
Mar
(38) |
Apr
(32) |
May
(8) |
Jun
(43) |
Jul
(27) |
Aug
(30) |
Sep
(43) |
Oct
(42) |
Nov
(38) |
Dec
(67) |
| 2019 |
Jan
(32) |
Feb
(37) |
Mar
(53) |
Apr
(64) |
May
(49) |
Jun
(18) |
Jul
(14) |
Aug
(53) |
Sep
(25) |
Oct
(30) |
Nov
(49) |
Dec
(31) |
| 2020 |
Jan
(87) |
Feb
(45) |
Mar
(37) |
Apr
(51) |
May
(99) |
Jun
(36) |
Jul
(11) |
Aug
(14) |
Sep
(20) |
Oct
(24) |
Nov
(40) |
Dec
(23) |
| 2021 |
Jan
(14) |
Feb
(53) |
Mar
(85) |
Apr
(15) |
May
(19) |
Jun
(3) |
Jul
(14) |
Aug
(1) |
Sep
(57) |
Oct
(73) |
Nov
(56) |
Dec
(22) |
| 2022 |
Jan
(3) |
Feb
(22) |
Mar
(6) |
Apr
(55) |
May
(46) |
Jun
(39) |
Jul
(15) |
Aug
(9) |
Sep
(11) |
Oct
(34) |
Nov
(20) |
Dec
(36) |
| 2023 |
Jan
(79) |
Feb
(41) |
Mar
(99) |
Apr
(169) |
May
(48) |
Jun
(16) |
Jul
(16) |
Aug
(57) |
Sep
(19) |
Oct
|
Nov
|
Dec
|
| S | M | T | W | T | F | S |
|---|---|---|---|---|---|---|
|
|
|
|
1
(4) |
2
(3) |
3
|
4
(1) |
|
5
|
6
|
7
|
8
(1) |
9
|
10
|
11
|
|
12
|
13
(2) |
14
|
15
|
16
|
17
(3) |
18
|
|
19
|
20
(4) |
21
(4) |
22
|
23
(4) |
24
|
25
|
|
26
|
27
(1) |
28
|
29
(6) |
30
(1) |
|
|
|
From: Philippe W. <phi...@sk...> - 2016-06-29 23:00:21
|
On Wed, 2016-06-29 at 16:30 -0500, Will Schmidt wrote:
> Hi,
> I wanted to try to knock down a few of the lingering valgrind
> regression test bugs. I've chased the hgtls failure around in a few
> circles, and at this point I suspect something is going wrong somewhere
> in the valgrind part of the test for power on ppc64(BE). A bit of a
> brain dump follows of what I've figured out. At the moment I'm looking
> for insights into what would be happening here, or a pointer for where I
> should be looking or what I should be looking for. :-)
>
> With a newly built gdb(*) the behavior on a ppc64LE system appears OK.
> So this would seem to be something possibly power (BE) specific.
>
> (*) - Specifically a gdb that contains "Fix PR/18564 - regression in
> showing __thread so extern variable", from Sep 2015.
Yes, a regression was introduced in gdb at some point in time,
making hgtls failing on all platforms.
This gdb (and hgtls) regression was fixed by this change in gdb.
>
> With a very recent (06/29) version of gdb on ppc64(BE):
>
> $ perl tests/vg_regtest --keep-unfiltered gdbserver_tests/hgtls
>
> output for a ppc64 (power7) box contains:
> $ (ppc64) grep equal hgtls.stdoutB.out.unfiltered.out
> test race tls_ip 0x100200b0 ip 0x100200b0 equal 1
> test local tls_ip 0xffffffffffffffff ip 0x537f8e0 equal 0
> test global tls_ip 0x3 ip 0x5b7f8e4 equal 0
> test static_extern tls_ip 0x7 ip 0x637f8e8 equal 0
> test so_extern tls_ip 0xffffffffffffffff ip 0x6b7f8f0 equal 0
> test so_local tls_ip 0xffffffffffffffff ip 0x737f8ec equal 0
> test so_global tls_ip 0x3 ip 0x7b7f8e4 equal 0
All thread local addresses are wrong in the above.
The only correct address is the &race, which is not thread local.
So, this point at a basic problem in valgrind gdbserver processing
the packet qGetTLSAddr.
>
> Under debug (printfs added to gdb) the final values failing the compare
> are coming out of the gdb/target.c:target_translate_tls_address() call.
> The lm_addr value there looks reasonable, the addr value definitely is
> not. I admittedly have no idea if lm_addr here is actually correct.
>
> DBG: lm_addr: 4051eb8
> DBG: addr: ffffffffffffffff
> test local tls_ip 0xffffffffffffffff ip 0x577f8e0 equal 0
> ...
> DBG: lm_addr: 4051eb8
> DBG: addr: 3
> test global tls_ip 0x3 ip 0x5b7f8e4 equal 0
>
> But... When running the same test directly under gdb/gdbserver (no
> valgrind/vgdb involvement) it works OK, in that the gdb breakpoints
> trigger, the compares occur, and all report "equal 1" for the tests.
> So I'm not sure my chasing this through the gdb code is the right
> direction..
>
> Thoughts?
tls handling in valgrind gdbserver is based on various 'hacks' :
* in platform specific files (e.g. valgrind-low-ppc64.c), you have
a function target_get_dtv
* then a glibc/platform specific offset has to be 'guessed'.
This is done by the auxprog/getoff.c program
that will be launched by the function valgrind_get_tls_addr
See in getoff.c the way to verify that the ugly hack of getoff.c
works ok by using gdb as indicated in the comment following
#ifdef HAVE_DLINFO_RTLD_DI_TLS_MODID
* valgrind_get_tls_addr will then use the dtv and lm to compute the
thread local variable.
Maybe you could put some valgrind debug trace -d -d -d
and compare the ppc64 BE and LE trace ?
Or also maybe compare the gdb+gdbserver traces for lm/lm_addr etc
with what valgrind shows ?
It is now quite some time I have done this tls functionality, so I do
not remember much. The paper of Ulrich Drepper describing thread local
storage on linux gave very good information (I think some details
here and there might be obsolete).
Sorry for not being able to give more precise indications,
I hope the pointers above might give a hint.
Philippe
|
|
From: Will S. <wil...@vn...> - 2016-06-29 22:21:18
|
Hi, I wanted to try to knock down a few of the lingering valgrind regression test bugs. I've chased the hgtls failure around in a few circles, and at this point I suspect something is going wrong somewhere in the valgrind part of the test for power on ppc64(BE). A bit of a brain dump follows of what I've figured out. At the moment I'm looking for insights into what would be happening here, or a pointer for where I should be looking or what I should be looking for. :-) With a newly built gdb(*) the behavior on a ppc64LE system appears OK. So this would seem to be something possibly power (BE) specific. (*) - Specifically a gdb that contains "Fix PR/18564 - regression in showing __thread so extern variable", from Sep 2015. With a very recent (06/29) version of gdb on ppc64(BE): $ perl tests/vg_regtest --keep-unfiltered gdbserver_tests/hgtls output for a ppc64 (power7) box contains: $ (ppc64) grep equal hgtls.stdoutB.out.unfiltered.out test race tls_ip 0x100200b0 ip 0x100200b0 equal 1 test local tls_ip 0xffffffffffffffff ip 0x537f8e0 equal 0 test global tls_ip 0x3 ip 0x5b7f8e4 equal 0 test static_extern tls_ip 0x7 ip 0x637f8e8 equal 0 test so_extern tls_ip 0xffffffffffffffff ip 0x6b7f8f0 equal 0 test so_local tls_ip 0xffffffffffffffff ip 0x737f8ec equal 0 test so_global tls_ip 0x3 ip 0x7b7f8e4 equal 0 Under debug (printfs added to gdb) the final values failing the compare are coming out of the gdb/target.c:target_translate_tls_address() call. The lm_addr value there looks reasonable, the addr value definitely is not. I admittedly have no idea if lm_addr here is actually correct. DBG: lm_addr: 4051eb8 DBG: addr: ffffffffffffffff test local tls_ip 0xffffffffffffffff ip 0x577f8e0 equal 0 ... DBG: lm_addr: 4051eb8 DBG: addr: 3 test global tls_ip 0x3 ip 0x5b7f8e4 equal 0 But... When running the same test directly under gdb/gdbserver (no valgrind/vgdb involvement) it works OK, in that the gdb breakpoints trigger, the compares occur, and all report "equal 1" for the tests. So I'm not sure my chasing this through the gdb code is the right direction.. Thoughts? Thanks, -Will |
|
From: <sv...@va...> - 2016-06-29 18:10:10
|
Author: carll
Date: Wed Jun 29 19:09:57 2016
New Revision: 15896
Log:
Power PC test suite for ISA 3.0, part 4
The test suite support for the Power PC ISA 3.0 instructions added in
VEX commit 3222 is added in this commit.
Note, this is part 4 of 5. The NEWS file will be updated when the ISA 3.0
support is complete.
valgrind bugzilla 363858
Modified:
trunk/memcheck/mc_machine.c
trunk/none/tests/ppc64/ppc64_helpers.h
trunk/none/tests/ppc64/test_isa_3_0.c
trunk/none/tests/ppc64/test_isa_3_0_altivec.stdout.exp
trunk/none/tests/ppc64/test_isa_3_0_other.stdout.exp
trunk/none/tests/ppc64/test_isa_3_0_other.vgtest
Modified: trunk/memcheck/mc_machine.c
==============================================================================
--- trunk/memcheck/mc_machine.c (original)
+++ trunk/memcheck/mc_machine.c Wed Jun 29 19:09:57 2016
@@ -183,7 +183,7 @@
if (o == GOF(IP_AT_SYSCALL) && sz == 8) return -1; /* slot unused */
if (o == GOF(FPROUND) && sz == 1) return -1;
if (o == GOF(DFPROUND) && sz == 1) return -1;
- if (o == GOF(FPCC) && sz == 1) return -1;
+ if (o == GOF(C_FPCC) && sz == 1) return -1;
if (o == GOF(EMNOTE) && sz == 4) return -1;
if (o == GOF(CMSTART) && sz == 8) return -1;
if (o == GOF(CMLEN) && sz == 8) return -1;
Modified: trunk/none/tests/ppc64/ppc64_helpers.h
==============================================================================
--- trunk/none/tests/ppc64/ppc64_helpers.h (original)
+++ trunk/none/tests/ppc64/ppc64_helpers.h Wed Jun 29 19:09:57 2016
@@ -199,6 +199,15 @@
__dissect_cr(masked_cr);
}
+/* Display all of the CR fields... */
+static void dissect_cr(unsigned long local_cr) {
+ unsigned int crn;
+
+ for (crn = 0; crn < 8; crn++) {
+ dissect_cr_rn(local_cr, crn);
+ }
+}
+
/* dissect the fpscr bits that are valid under valgrind.
* Valgrind itself only tracks the C and FPCC fields from the
* FPSCR.
Modified: trunk/none/tests/ppc64/test_isa_3_0.c
==============================================================================
--- trunk/none/tests/ppc64/test_isa_3_0.c (original)
+++ trunk/none/tests/ppc64/test_isa_3_0.c Wed Jun 29 19:09:57 2016
@@ -212,7 +212,11 @@
PPC_ALTIVEC = 0x00030000,
PPC_ALTIVEC_QUAD = 0x00040000,
PPC_ALTIVEC_DOUBLE = 0x00050000,
+ PPC_DFP = 0x00060000,
+ PPC_BCD = 0x00070000,
PPC_MISC = 0x00080000,
+ PPC_NO_OP = 0x00090000,
+ PPC_PC_IMMEDIATE = 0x000A0000,
PPC_FAMILY_MASK = 0x000F0000,
/* Flags: these may be combined, so use separate bit-fields. */
@@ -849,6 +853,14 @@
__asm__ __volatile__ ("stxvl %0, 14, 15" : "=wa" (vec_xt));
}
+static void test_lxvll(void) {
+ __asm__ __volatile__ ("lxvll %0, 14, 15" : "=wa" (vec_xt));
+}
+
+static void test_stxvll(void) {
+ __asm__ __volatile__ ("stxvll %0, 14, 15" : "=wa" (vec_xt));
+}
+
static void test_lxsibzx(void) {
__asm__ __volatile__ ("lxsibzx %x0, 14, 15" : "=wa" (vec_xt));
}
@@ -916,9 +928,11 @@
static test_list_t testgroup_vector_scalar_loadstore_length[] = {
{ &test_lxvl , "lxvl " },
+ { &test_lxvll , "lxvll " },
{ &test_lxsibzx , "lxsibzx " },
{ &test_lxsihzx , "lxsihzx " },
{ &test_stxvl , "stxvl " },
+ { &test_stxvll , "stxvll " },
{ &test_stxsibx , "stxsibx " },
{ &test_stxsihx , "stxsihx " },
{ &test_lxsd_0 , "lxsd 0 " },
@@ -1215,6 +1229,388 @@
{ NULL , NULL },
};
+static void test_setb (void) {
+ /* setb RT,BFA
+ * BFA is a 3-bit field. */
+
+ switch(x_index) {
+ case 0:SET_CR0_FIELD(cr_value);
+ __asm__ __volatile__ ("setb %0, 0" : "=r" (r14)); break;
+
+ case 1:SET_CR1_FIELD(cr_value);
+ __asm__ __volatile__ ("setb %0, 1" : "=r" (r14)); break;
+
+ case 2:SET_CR2_FIELD(cr_value);
+ __asm__ __volatile__ ("setb %0, 2" : "=r" (r14)); break;
+
+ case 3:SET_CR3_FIELD(cr_value);
+ __asm__ __volatile__ ("setb %0, 3" : "=r" (r14)); break;
+
+ case 4:SET_CR4_FIELD(cr_value);
+ __asm__ __volatile__ ("setb %0, 4" : "=r" (r14)); break;
+
+ case 5:SET_CR5_FIELD(cr_value);
+ __asm__ __volatile__ ("setb %0, 5" : "=r" (r14)); break;
+
+ case 6:SET_CR6_FIELD(cr_value);
+ __asm__ __volatile__ ("setb %0, 6" : "=r" (r14)); break;
+
+ case 7:SET_CR7_FIELD(cr_value);
+ __asm__ __volatile__ ("setb %0, 7" : "=r" (r14)); break;
+ }
+
+ GET_CR(local_cr);
+
+ if (verbose) {
+ dissect_cr(local_cr);
+ }
+}
+
+static test_list_t testgroup_set_boolean[] = {
+ { &test_setb, "setb"},
+ { NULL , NULL },
+};
+
+/* cmprb l = 0:
+ * compares r14 = src with range specified by values in r15
+ * bits (48:55 - 56:63)].
+ *
+ * cmprb l=1:
+ * compares r14 = src with ranges between two pairs of values, as above and
+ * also in r15 bits (32:39 - 40:47 .
+ */
+static void test_cmprb_l0() {
+ switch(x_index) {
+ case 0: __asm__ __volatile__ ("cmprb 0, 0, %0, %1" : : "r"(r14), "r"(r15));
+ GET_CR(local_cr); break;
+
+ case 1: __asm__ __volatile__ ("cmprb 1, 0, %0, %1" : : "r"(r14), "r"(r15));
+ GET_CR(local_cr); break;
+
+ case 2: __asm__ __volatile__ ("cmprb 2, 0, %0, %1" : : "r"(r14), "r"(r15));
+ GET_CR(local_cr); break;
+
+ case 3: __asm__ __volatile__ ("cmprb 3, 0, %0, %1" : : "r"(r14), "r"(r15));
+ GET_CR(local_cr); break;
+
+ case 4: __asm__ __volatile__ ("cmprb 4, 0, %0, %1" : : "r"(r14), "r"(r15));
+ GET_CR(local_cr); break;
+
+ case 5: __asm__ __volatile__ ("cmprb 5, 0, %0, %1" : : "r"(r14), "r"(r15));
+ GET_CR(local_cr); break;
+
+ case 6: __asm__ __volatile__ ("cmprb 6, 0, %0, %1" : : "r"(r14), "r"(r15));
+ GET_CR(local_cr); break;
+
+ case 7: __asm__ __volatile__ ("cmprb 7, 0, %0, %1" : : "r"(r14), "r"(r15));
+ GET_CR(local_cr); break;
+ }
+}
+
+static void test_cmprb_l1() {
+ switch(x_index) {
+ case 0: __asm__ __volatile__ ("cmprb 0, 1 ,%0, %1" : : "r"(r14), "r"(r15));
+ GET_CR(local_cr); break;
+
+ case 1: __asm__ __volatile__ ("cmprb 1, 1, %0, %1" : : "r"(r14), "r"(r15));
+ GET_CR(local_cr); break;
+
+ case 2: __asm__ __volatile__ ("cmprb 2, 1, %0, %1" : : "r"(r14), "r"(r15));
+ GET_CR(local_cr); break;
+
+ case 3: __asm__ __volatile__ ("cmprb 3, 1, %0, %1" : : "r"(r14), "r"(r15));
+ GET_CR(local_cr); break;
+
+ case 4: __asm__ __volatile__ ("cmprb 4, 1, %0, %1" : : "r"(r14), "r"(r15));
+ GET_CR(local_cr); break;
+
+ case 5: __asm__ __volatile__ ("cmprb 5, 1, %0, %1" : : "r"(r14), "r"(r15));
+ GET_CR(local_cr); break;
+
+ case 6: __asm__ __volatile__ ("cmprb 6, 1, %0, %1" : : "r"(r14), "r"(r15));
+ GET_CR(local_cr); break;
+
+ case 7: __asm__ __volatile__ ("cmprb 7, 1, %0, %1" : : "r"(r14), "r"(r15));
+ GET_CR(local_cr); break;
+ }
+}
+
+static void test_cmpeqb() {
+ switch(x_index) {
+ case 0: __asm__ __volatile__ ("cmpeqb 0,%0, %1" : : "r"(r14), "r"(r15));
+ GET_CR(local_cr); break;
+
+ case 1: __asm__ __volatile__ ("cmpeqb 1,%0, %1" : : "r"(r14), "r"(r15));
+ GET_CR(local_cr); break;
+
+ case 2: __asm__ __volatile__ ("cmpeqb 2,%0, %1" : : "r"(r14), "r"(r15));
+ GET_CR(local_cr); break;
+
+ case 3: __asm__ __volatile__ ("cmpeqb 3,%0, %1" : : "r"(r14), "r"(r15));
+ GET_CR(local_cr); break;
+
+ case 4: __asm__ __volatile__ ("cmpeqb 4,%0, %1" : : "r"(r14), "r"(r15));
+ GET_CR(local_cr); break;
+
+ case 5: __asm__ __volatile__ ("cmpeqb 5,%0, %1" : : "r"(r14), "r"(r15));
+ GET_CR(local_cr); break;
+
+ case 6: __asm__ __volatile__ ("cmpeqb 6,%0, %1" : : "r"(r14), "r"(r15));
+ GET_CR(local_cr); break;
+
+ case 7: __asm__ __volatile__ ("cmpeqb 7,%0, %1" : : "r"(r14), "r"(r15));
+ GET_CR(local_cr); break;
+ }
+}
+
+static test_list_t testgroup_char_compare[] = {
+ { &test_cmprb_l0, "cmprb l=0" },
+ { &test_cmprb_l1, "cmprb l=1" },
+ { &test_cmpeqb , "cmpeqb" },
+ { NULL , NULL },
+};
+
+static void test_bcdadd_p0(void) {
+ __asm__ __volatile__ ("bcdadd. %0, %1, %2, 0" : "=v"(vec_xt) : "v"(vec_xa), "v"(vec_xb));
+}
+
+static void test_bcdadd_p1(void) {
+ __asm__ __volatile__ ("bcdadd. %0, %1, %2, 1" : "=v"(vec_xt) : "v"(vec_xa), "v"(vec_xb));
+}
+
+static void test_bcdsub_p0(void) {
+ __asm__ __volatile__ ("bcdsub. %0, %1, %2, 0" : "=v"(vec_xt) : "v"(vec_xa), "v"(vec_xb));
+}
+
+static void test_bcdsub_p1(void) {
+ __asm__ __volatile__ ("bcdsub. %0, %1, %2, 1" : "=v"(vec_xt) : "v"(vec_xa), "v"(vec_xb));
+}
+
+static void test_bcdcpsgn(void) {
+ __asm__ __volatile__ ("bcdcpsgn. %0, %1, %2 ": "=v"(vec_xt) : "v"(vec_xa), "v"(vec_xb));
+}
+
+static void test_bcdctz_p0(void) {
+ __asm__ __volatile__ ("bcdctz. %0, %1, 0 " : "=v"(vec_xt) : "v"(vec_xb));
+}
+
+static void test_bcdctz_p1(void) {
+ __asm__ __volatile__ ("bcdctz. %0, %1, 1 " : "=v"(vec_xt) : "v"(vec_xb));
+}
+
+static void test_bcdsetsgn_p0(void) {
+ __asm__ __volatile__ ("bcdsetsgn. %0, %1, 0 " : "=v"(vec_xt) : "v"(vec_xb));
+}
+
+static void test_bcdsetsgn_p1(void) {
+ __asm__ __volatile__ ("bcdsetsgn. %0, %1, 1 " : "=v"(vec_xt) : "v"(vec_xb));
+}
+
+static void test_bcds_p0(void) {
+ __asm__ __volatile__ ("bcds. %0, %1, %2, 0" : "=v"(vec_xt) : "v"(vec_xa), "v"(vec_xb));
+}
+
+static void test_bcds_p1(void) {
+ __asm__ __volatile__ ("bcds. %0, %1, %2, 1" : "=v"(vec_xt) : "v"(vec_xa), "v"(vec_xb));
+}
+
+static void test_bcdus(void) {
+ __asm__ __volatile__ ("bcdus. %0, %1, %2 " : "=v"(vec_xt) : "v"(vec_xa), "v"(vec_xb));
+}
+
+static void test_bcdsr_p0(void) {
+ __asm__ __volatile__ ("bcdsr. %0, %1, %2, 0" : "=v"(vec_xt) : "v"(vec_xa), "v"(vec_xb));
+}
+
+static void test_bcdsr_p1(void) {
+ __asm__ __volatile__ ("bcdsr. %0, %1, %2, 1" : "=v"(vec_xt) : "v"(vec_xa), "v"(vec_xb));
+}
+
+static void test_bcdcfn_p0(void) {
+ __asm__ __volatile__ ("bcdcfn. %0, %1, 0 " : "=v"(vec_xt) : "v"(vec_xb));
+}
+
+static void test_bcdcfn_p1(void) {
+ __asm__ __volatile__ ("bcdcfn. %0, %1, 1 " : "=v"(vec_xt) : "v"(vec_xb));
+}
+
+static void test_bcdcfz_p0(void) {
+ __asm__ __volatile__ ("bcdcfz. %0, %1, 0 " : "=v"(vec_xt) : "v"(vec_xb));
+}
+
+static void test_bcdcfz_p1(void) {
+ __asm__ __volatile__ ("bcdcfz. %0, %1, 1 " : "=v"(vec_xt) : "v"(vec_xb));
+}
+
+static void test_bcdctn(void) {
+ __asm__ __volatile__ ("bcdctn. %0, %1 " : "=v"(vec_xt) : "v"(vec_xb));
+}
+
+static test_list_t testgroup_bcd_misc[] = {
+ { &test_bcdadd_p0 , "bcdadd. p0" },
+ { &test_bcdadd_p1 , "bcdadd. p1" },
+ { &test_bcdsub_p0 , "bcdsub. p0" },
+ { &test_bcdsub_p1 , "bcdsub. p1" },
+ { &test_bcdcfn_p0 , "bcdcfn. p0" },
+ { &test_bcdcfn_p1 , "bcdcfn. p1" },
+ { &test_bcdcfz_p0 , "bcdcfz. p0" }, /* The p0, p1 substrings are used later */
+ { &test_bcdcfz_p1 , "bcdcfz. p1" }, /* " " */
+ { &test_bcdctn , "bcdctn." },
+ { &test_bcdctz_p0 , "bcdctz. p0" }, /* note: p0, p1 substrings are used later */
+ { &test_bcdctz_p1 , "bcdctz. p1" }, /* " " */
+ { &test_bcdcpsgn , "bcdcpsgn." },
+ { &test_bcdsetsgn_p0, "bcdsetsgn. p0" },
+ { &test_bcdsetsgn_p1, "bcdsetsgn. p1" },
+ { &test_bcds_p0 , "bcds. p0" },
+ { &test_bcds_p1 , "bcds. p1" },
+ { &test_bcdus , "bcdus. " },
+ { &test_bcdsr_p0 , "bcdsr. p0" },
+ { &test_bcdsr_p1 , "bcdsr. p1" },
+ { NULL , NULL },
+};
+
+static void test_wait(void) {
+ __asm__ __volatile__ ("wait 0" : :);
+}
+
+static test_list_t testgroup_noop_misc[] = {
+ { &test_wait, "wait ",},
+ { NULL , NULL, },
+};
+
+/* The significance field can be any values within bits 10-15 of the
+ * instruction. For this test, limiting the values to one per bit location.
+ */
+static void test_dtstsfi() {
+ _Decimal128 df14 = dfp_value.dec_val128;
+ switch(dfp_significance) {
+ case 0x00: __asm__ __volatile__ ("dtstsfi 3, 0x00, %0" : : "f" (df14));
+ GET_CR(local_cr); break;
+
+ case 0x01: __asm__ __volatile__ ("dtstsfi 3, 0x01, %0" : : "f" (df14));
+ GET_CR(local_cr); break;
+
+ case 0x02: __asm__ __volatile__ ("dtstsfi 3, 0x02, %0" : : "f" (df14));
+ GET_CR(local_cr); break;
+
+ case 0x03: __asm__ __volatile__ ("dtstsfi 3, 0x03, %0" : : "f" (df14));
+ GET_CR(local_cr); break;
+
+ case 0x04: __asm__ __volatile__ ("dtstsfi 3, 0x04, %0" : : "f" (df14));
+ GET_CR(local_cr); break;
+
+ case 0x06: __asm__ __volatile__ ("dtstsfi 3, 0x06, %0" : : "f" (df14));
+ GET_CR(local_cr); break;
+
+ case 0x08: __asm__ __volatile__ ("dtstsfi 3, 0x08, %0" : : "f" (df14));
+ GET_CR(local_cr); break;
+
+ case 0x0c: __asm__ __volatile__ ("dtstsfi 3, 0x0c, %0" : : "f" (df14));
+ GET_CR(local_cr); break;
+
+ case 0x10: __asm__ __volatile__ ("dtstsfi 3, 0x10, %0" : : "f" (df14));
+ GET_CR(local_cr); break;
+
+ case 0x18: __asm__ __volatile__ ("dtstsfi 3, 0x18, %0" : : "f" (df14));
+ GET_CR(local_cr); break;
+
+ case 0x20: __asm__ __volatile__ ("dtstsfi 3, 0x20, %0" : : "f" (df14));
+ GET_CR(local_cr); break;
+ }
+}
+
+static void test_dtstsfiq() {
+ _Decimal128 df14 = dfp_value.dec_val128;
+ switch(dfp_significance) {
+ case 0x00: __asm__ __volatile__ ("dtstsfiq 3, 0x00, %0" : : "f" (df14));
+ GET_CR(local_cr); break;
+
+ case 0x01: __asm__ __volatile__ ("dtstsfiq 3, 0x01, %0" : : "f" (df14));
+ GET_CR(local_cr); break;
+
+ case 0x02: __asm__ __volatile__ ("dtstsfiq 3, 0x02, %0" : : "f" (df14));
+ GET_CR(local_cr); break;
+
+ case 0x03: __asm__ __volatile__ ("dtstsfiq 3, 0x03, %0" : : "f" (df14));
+ GET_CR(local_cr); break;
+
+ case 0x04: __asm__ __volatile__ ("dtstsfiq 3, 0x04, %0" : : "f" (df14));
+ GET_CR(local_cr); break;
+
+ case 0x06: __asm__ __volatile__ ("dtstsfiq 3, 0x06, %0" : : "f" (df14));
+ GET_CR(local_cr); break;
+
+ case 0x08: __asm__ __volatile__ ("dtstsfiq 3, 0x08, %0" : : "f" (df14));
+ GET_CR(local_cr); break;
+
+ case 0x0c: __asm__ __volatile__ ("dtstsfiq 3, 0x0c, %0" : : "f" (df14));
+ GET_CR(local_cr); break;
+
+ case 0x10: __asm__ __volatile__ ("dtstsfiq 3, 0x10, %0" : : "f" (df14));
+ GET_CR(local_cr); break;
+
+ case 0x18: __asm__ __volatile__ ("dtstsfiq 3, 0x18, %0" : : "f" (df14));
+ GET_CR(local_cr); break;
+
+ case 0x20: __asm__ __volatile__ ("dtstsfiq 3, 0x20, %0" : : "f" (df14));
+ GET_CR(local_cr); break;
+ }
+}
+
+static test_list_t testgroup_dfp_significance[] = {
+ { &test_dtstsfi , "dtstsfi" },
+ { &test_dtstsfiq, "dtstsfiq" },
+ { NULL , NULL },
+};
+
+static void test_addpcis(void) {
+ switch (x_index) {
+ case 0x0: __asm__ __volatile__ ("addpcis 14, %0" : : "i"(0x0) ); break;
+ case 0x1: __asm__ __volatile__ ("addpcis 14, %0" : : "i"(0x1) ); break;
+ case 0x2: __asm__ __volatile__ ("addpcis 14, %0" : : "i"(0x2) ); break;
+ case 0x3: __asm__ __volatile__ ("addpcis 14, %0" : : "i"(0x40) ); break;
+ case 0x4: __asm__ __volatile__ ("addpcis 14, %0" : : "i"(0x800) ); break;
+ case 0x5: __asm__ __volatile__ ("addpcis 14, %0" : : "i"(0x2000) ); break;
+ case 0x6: __asm__ __volatile__ ("addpcis 14, %0" : : "i"(0x7fff) ); break;
+ case 0x7: __asm__ __volatile__ ("addpcis 14, %0" : : "i"(0x8000) ); break;
+ case 0x8: __asm__ __volatile__ ("addpcis 14, -%0" : : "i"(0x0) ); break;
+ case 0x9: __asm__ __volatile__ ("addpcis 14, -%0" : : "i"(0x1) ); break;
+ case 0xa: __asm__ __volatile__ ("addpcis 14, -%0" : : "i"(0x2) ); break;
+ case 0xb: __asm__ __volatile__ ("addpcis 14, -%0" : : "i"(0x40) ); break;
+ case 0xc: __asm__ __volatile__ ("addpcis 14, -%0" : : "i"(0x800) ); break;
+ case 0xd: __asm__ __volatile__ ("addpcis 14, -%0" : : "i"(0x2000) ); break;
+ case 0xe: __asm__ __volatile__ ("addpcis 14, -%0" : : "i"(0x7fff) ); break;
+ case 0xf: __asm__ __volatile__ ("addpcis 14, -%0" : : "i"(0x8000) ); break;
+ }
+}
+
+static void test_subpcis(void) {
+ switch (x_index) {
+ case 0x0: __asm__ __volatile__ ("subpcis 14, %0" : : "i"(0x0) ); break;
+ case 0x1: __asm__ __volatile__ ("subpcis 14, %0" : : "i"(0x1) ); break;
+ case 0x2: __asm__ __volatile__ ("subpcis 14, %0" : : "i"(0x2) ); break;
+ case 0x3: __asm__ __volatile__ ("subpcis 14, %0" : : "i"(0x40) ); break;
+ case 0x4: __asm__ __volatile__ ("subpcis 14, %0" : : "i"(0x800) ); break;
+ case 0x5: __asm__ __volatile__ ("subpcis 14, %0" : : "i"(0x2000) ); break;
+ case 0x6: __asm__ __volatile__ ("subpcis 14, %0" : : "i"(0x7fff) ); break;
+ case 0x7: __asm__ __volatile__ ("subpcis 14, %0" : : "i"(0x8000) ); break;
+ case 0x8: __asm__ __volatile__ ("subpcis 14, -%0" : : "i"(0x0) ); break;
+ case 0x9: __asm__ __volatile__ ("subpcis 14, -%0" : : "i"(0x1) ); break;
+ case 0xa: __asm__ __volatile__ ("subpcis 14, -%0" : : "i"(0x2) ); break;
+ case 0xb: __asm__ __volatile__ ("subpcis 14, -%0" : : "i"(0x40) ); break;
+ case 0xc: __asm__ __volatile__ ("subpcis 14, -%0" : : "i"(0x80) ); break;
+ case 0xd: __asm__ __volatile__ ("subpcis 14, -%0" : : "i"(0x200) ); break;
+ case 0xe: __asm__ __volatile__ ("subpcis 14, -%0" : : "i"(0x7fff) ); break;
+ case 0xf: __asm__ __volatile__ ("subpcis 14, -%0" : : "i"(0x8000) ); break;
+ }
+}
+
+static test_list_t testgroup_pc_immediate_misc[] = {
+ { &test_addpcis, "addpcis " },
+ { &test_subpcis, "subpcis " },
+ { NULL , NULL },
+};
+
static void test_xsiexpdp(void) {
__asm__ __volatile__ ("xsiexpdp %0, %1, %2 " : "+wa" (vec_xt): "r" (r14), "r" (r15));
}
@@ -1367,6 +1763,16 @@
PPC_INTEGER | PPC_ARITH | PPC_THREE_ARGS,
},
{
+ testgroup_set_boolean,
+ "ppc set boolean",
+ PPC_INTEGER | PPC_LOGICAL | PPC_ONE_IMM,
+ },
+ {
+ testgroup_char_compare,
+ "ppc char compare",
+ PPC_INTEGER | PPC_COMPARE,
+ },
+ {
testgroup_vsx_absolute,
"ppc vector absolutes",
PPC_ALTIVEC | PPC_ARITH | PPC_TWO_ARGS,
@@ -1461,6 +1867,26 @@
"ppc vector scalar tests against float double two args ",
PPC_ALTIVEC_DOUBLE | PPC_COMPARE | PPC_TWO_ARGS,
},
+ {
+ testgroup_dfp_significance,
+ "ppc dfp significance",
+ PPC_DFP,
+ },
+ {
+ testgroup_bcd_misc,
+ "ppc bcd misc",
+ PPC_BCD,
+ },
+ {
+ testgroup_noop_misc,
+ "ppc noop misc",
+ PPC_NO_OP,
+ },
+ {
+ testgroup_pc_immediate_misc,
+ "ppc addpc_misc",
+ PPC_PC_IMMEDIATE,
+ },
{ NULL, NULL, 0x00000000, },
};
@@ -2483,6 +2909,286 @@
} // i
}
+static void testfunction_set_boolean (const char* instruction_name,
+ test_func_t test_function,
+ unsigned int ignore_test_flags)
+{
+ int cr_base_value;
+ /* Notes:
+ * Set RT to values 0, -1, 1 depending on what bits are set in the specified
+ * CR field. x_index references here reflect the cr_field number.
+ */
+
+ VERBOSE_FUNCTION_CALLOUT
+
+ for (x_index = 0; x_index <= 7; x_index++) {
+ for (cr_base_value = 0; cr_base_value <= 8; cr_base_value++) {
+ cr_value = (0x11111111 * cr_base_value)
+ & (0xf << (4 * (7 - x_index))) ;
+
+ r14 = 0xa5a5a5a5c7c7c7c7;
+
+ printf("%s cr_field:%1x cr_value::%08x",
+ instruction_name, x_index,cr_value);
+ printf(" => ");
+
+ (*test_function)();
+
+ printf(" %016lx\n", r14);
+ }
+ }
+}
+
+
+static void testfunction_char_compare (const char* instruction_name,
+ test_func_t test_function,
+ unsigned int ignore_test_flags)
+{
+ /* Notes:
+ * iterate through char values stored in RA, RB.
+ * Results stored in cr field BF.
+ */
+ int i, j;
+ int local_crf;
+
+ VERBOSE_FUNCTION_CALLOUT
+
+ for (x_index = 0; x_index <= 7; x_index++) {
+ for (i = 0; i < nb_char_ranges; i += 4) {
+ for (j = 0; j < nb_char_args; j++) {
+ r14 = char_args[j];
+
+ /* For cmprb*, only needs the lower characters. */
+ r15 = char_ranges[i] | (char_ranges[i+1] << 8) |
+ char_ranges[i+2] << 16 | (char_ranges[i+3] << 24);
+
+ /* For cmpeqb, also load the rest of the range field, shift allk
+ * chars up by one.
+ */
+ r15 |= (r15 + 0x01010101) << 32;
+ printf("%s 0x%02lx (%c) (cmpeq:0x%016lx) (cmprb:src22(%c-%c) src21(%c-%c))",
+ instruction_name,
+ r14, (int)r14,
+ r15, (int)(r15 & 0xff), (int)((r15 >> 8) & 0xff),
+ (int)((r15 >> 16) & 0xff), (int)((r15 >> 24) & 0xff)
+ );
+
+ printf(" =>");
+
+ (*test_function)();
+
+ GET_CR(local_cr);
+ local_crf = extract_cr_rn(local_cr, x_index);
+
+ if (verbose)
+ printf(" %s found or in range (%x)",
+ (cr_positive_set(local_crf))?" " : " not", local_crf);
+ else
+ if (cr_positive_set(local_crf)) printf(" in range/found");
+
+ printf("\n");
+ }
+ }
+ }
+}
+
+#define instruction_uses_quads(instruction_name) (strncmp(instruction_name, "dtstsfiq", 8) == 0)
+
+static void testfunction_dfp_significance (const char* instruction_name,
+ test_func_t test_function,
+ unsigned int ignore_test_flags)
+{
+ int local_crf;
+ int i;
+ int num_dfp_vals;
+
+ VERBOSE_FUNCTION_CALLOUT
+
+ if (instruction_uses_quads(instruction_name)) {
+ num_dfp_vals = nb_dfp128_vals;
+ } else {
+ num_dfp_vals = nb_dfp64_vals;
+ }
+
+ for (i = 0; i < num_dfp_vals; i++) {
+ if (instruction_uses_quads(instruction_name)) {
+ dfp_value.u128.vall = dfp128_vals[i * 2];
+ dfp_value.u128.valu = dfp128_vals[(i * 2) + 1];
+
+ } else {
+ // could rework this to use u64.val, but...
+ dfp_value.u128.vall = dfp128_vals[i ];
+ dfp_value.u128.valu = dfp128_vals[i ];
+ }
+
+ /* Keeping test simpler, always using cr3 within test_dtstsfi* */
+ for (dfp_significance = 0; dfp_significance <= 63;) {
+ /* Todo: tweak output here, or input values so the generated content
+ * looks better.
+ */
+ printf("%s significance(0x%02x) ",
+ instruction_name, dfp_significance);
+
+ if (instruction_uses_quads(instruction_name)) {
+ dissect_dfp128_float(dfp_value.u128.vall, dfp_value.u128.valu);
+
+ if (verbose > 6)
+ printf("(RAW) value = %16lx,%016lx ",
+ dfp_value.u128.vall, dfp_value.u128.valu /*f14, f15 */);
+
+ } else {
+ dissect_dfp64_float(dfp_value.u128.vall);
+
+ if (verbose > 6)
+ printf("(RAW) value = %16lx ", dfp_value.u128.vall /*f14 */);
+ }
+
+ (*test_function)();
+
+ GET_CR(local_cr);
+
+ local_crf = extract_cr_rn(local_cr, /* hardcoded cr3 */ 3);
+ dissect_cr_rn(local_cr, /* hardcoded cr3 */ 3);
+
+ printf(" (%x)", local_crf);
+ printf("\n");
+
+ /* Special case for incrementation of the significance checking
+ * value.
+ */
+ if (dfp_significance < 8)
+ dfp_significance += 4; /* 0, 4, 8 */
+
+ else if (dfp_significance < 32)
+ dfp_significance += 8; /* 16, 24, 32 */
+
+ else if (dfp_significance < 48)
+ dfp_significance += 16; /* 48 */
+
+ else
+ dfp_significance += 15; /* 63 */
+ }
+ }
+}
+
+/* packed binary decimal misc */
+
+#define convert_tofrom_instruction(instruction_name) \
+ ( (strncmp(instruction_name, "bcdcf", 5) == 0) || \
+ (strncmp(instruction_name, "bcdct", 5) == 0) )
+
+static void testfunction_bcd_misc (const char* instruction_name,
+ test_func_t test_function,
+ unsigned int ignore_test_flags)
+{
+ int i, j;
+ int local_crf;
+ long max_xa_entries = 0;
+ long max_xb_entries = 0;
+
+ VERBOSE_FUNCTION_CALLOUT
+
+ shift_or_truncate_instruction = shift_or_truncate(instruction_name);
+
+ max_xa_entries = MAX(max_xa_entries, nb_decimal_shift_entries);
+ max_xa_entries = MAX(max_xa_entries, nb_packed_decimal_entries);
+
+ max_xb_entries = MAX(max_xb_entries, nb_zoned_decimal_entries);
+ max_xb_entries = MAX(max_xb_entries, nb_national_decimal_entries);
+ max_xb_entries = MAX(max_xb_entries, nb_packed_decimal_entries);
+
+ for (i = 0; i < (max_xa_entries - 1); i += 2) {
+ for (j = 0; j < (max_xb_entries - 1); j += 2) {
+ testfunction_bcd_setup_inputs(instruction_name, i, j);
+
+ if (short_circuit) continue;
+
+ printf("%s ", instruction_name);
+ printf("xa:%016lx %016lx ", vec_xa[0], vec_xa[1]);
+
+ if (!shift_or_truncate_instruction)
+ dissect_packed_decimal_sign(xa_sign);
+
+ printf(" xb:%016lx %016lx ", vec_xb[0], vec_xb[1]);
+
+ if (convert_from_zoned(instruction_name)) {
+ /* convert from zoned */
+ dissect_zoned_decimal_sign(xb_sign, p_value(instruction_name));
+
+ } else if (convert_from_national(instruction_name)) {
+ /* convert from national */
+ dissect_national_decimal_sign(xb_sign);
+
+ } else {
+ /* packed decimal entries */
+ if (!shift_or_truncate_instruction)
+ dissect_packed_decimal_sign(xb_sign);
+ }
+
+ printf(" => ");
+ SET_CR_ZERO
+
+ (*test_function)();
+
+ GET_CR(local_cr);
+
+ /* note: the bcd instructions are hard wired to use cr6. */
+ local_crf = extract_cr_rn(local_cr, 6);
+ dissect_cr_rn(local_cr, 6);
+ printf(" (%x)", local_crf);
+
+ if (cr_overflow_set(local_crf)) {
+ /* If overflow (S0) is set the results are undefined. Force the
+ * output to print as zeros so we have consistent results for
+ * comparison.
+ */
+ printf(" xt:%016lx %016lx", 0UL, 0UL);
+
+ } else {
+ testfunction_bcd_display_outputs(instruction_name);
+ }
+
+ printf("\n");
+ } // j = xb loop.
+
+ /* Since the bcdct* convert_tofrom instructions do not use the xa
+ * field, we will short-circuit the xa (i=*) loop here.
+ */
+ if (convert_tofrom_instruction(instruction_name))
+ i = nb_packed_decimal_entries;
+ } //i = xa loop.
+}
+
+
+static void testfunction_noop_misc (const char* instruction_name,
+ test_func_t test_function,
+ unsigned int ignore_test_flags)
+{
+ VERBOSE_FUNCTION_CALLOUT
+
+ printf("%s ", instruction_name);
+ printf(" =>");
+
+ (*test_function)();
+
+ printf("\n");
+}
+
+static void testfunction_pc_immediate_misc (const char* instruction_name,
+ test_func_t test_function,
+ unsigned int ignore_test_flags)
+{
+ VERBOSE_FUNCTION_CALLOUT
+
+ for (x_index = 0; x_index < 16; x_index++) {
+ printf("%s ", instruction_name);
+ printf(" %016x ", x_index);
+ printf(" => ");
+ (*test_function)();
+ printf(" %016lx\n", r14);
+ }
+}
+
/* ######## begin grand testing loops. */
typedef struct insn_sel_flags_t_struct {
int one_arg, two_args, three_args, four_args, cmp_args;
@@ -2544,6 +3250,10 @@
(family == PPC_ALTIVEC && !seln_flags.altivec) ||
(family == PPC_ALTIVEC_DOUBLE && !seln_flags.altivec_double) ||
(family == PPC_ALTIVEC_QUAD && !seln_flags.altivec_quad) ||
+ (family == PPC_DFP && !seln_flags.dfp) ||
+ (family == PPC_BCD && !seln_flags.bcd) ||
+ (family == PPC_NO_OP && !seln_flags.no_op) ||
+ (family == PPC_PC_IMMEDIATE && !seln_flags.pc_immediate) ||
(family == PPC_MISC && !seln_flags.misc))
continue;
@@ -2575,6 +3285,22 @@
}
break;
+ case PPC_LOGICAL:
+ switch(nb_args) {
+ case PPC_ONE_IMM:
+ group_function = &testfunction_set_boolean;
+ break;
+
+ default:
+ printf("ERROR: PPC_LOGICAL, unhandled number of arguments. 0x%08x\n",
+ nb_args);
+ }
+ break;
+
+ case PPC_COMPARE:
+ group_function = &testfunction_char_compare;
+ break;
+
default:
printf("ERROR: PPC_INTEGER, unhandled type 0x%08x\n", type);
continue;
@@ -2733,6 +3459,22 @@
} /* switch(type) */
break;
+ case PPC_DFP:
+ group_function = &testfunction_dfp_significance;
+ break;
+
+ case PPC_BCD:
+ group_function = &testfunction_bcd_misc;
+ break;
+
+ case PPC_NO_OP:
+ group_function = &testfunction_noop_misc;
+ break;
+
+ case PPC_PC_IMMEDIATE:
+ group_function = &testfunction_pc_immediate_misc;
+ break;
+
default:
printf("ERROR: unknown instruction family %08x\n", family);
continue;
@@ -2766,6 +3508,10 @@
"\t-a: test altivec instructions\n"
"\t-d: test altivec double instructions\n"
"\t-q: test altivec quad instructions\n"
+ "\t-D: test DFP instructions\n"
+ "\t-B: test BCD instructions\n"
+ "\t-N: test No Op instructions\n"
+ "\t-P: test PC Immediate Shifted instructions\n"
"\t-m: test miscellaneous instructions\n"
"\t-v: be verbose\n"
"\t-h: display this help and exit\n"
@@ -2803,6 +3549,10 @@
// Family
flags.integer = 0;
flags.misc = 0;
+ flags.dfp = 0;
+ flags.bcd = 0;
+ flags.no_op = 0;
+ flags.pc_immediate = 0;
flags.altivec = 0;
flags.altivec_double = 0;
flags.altivec_quad = 0;
@@ -2828,10 +3578,26 @@
flags.altivec_quad = 1;
break;
+ case 'D':
+ flags.dfp = 1;
+ break;
+
+ case 'B':
+ flags.bcd = 1;
+ break;
+
case 'm':
flags.misc = 1;
break;
+ case 'N':
+ flags.no_op = 1;
+ break;
+
+ case 'P':
+ flags.pc_immediate = 1;
+ break;
+
case 'h':
usage();
return 0;
@@ -2889,6 +3655,8 @@
printf(" altivec = %d\n", flags.altivec);
printf(" altivec double = %d\n", flags.altivec_double);
printf(" altivec quad = %d\n", flags.altivec_quad);
+ printf(" DFP = %d\n", flags.dfp);
+ printf(" BCD = %d\n", flags.bcd);
printf(" misc = %d\n", flags.misc);
printf(" cr update: \n");
printf(" cr = %d\n", flags.cr);
Modified: trunk/none/tests/ppc64/test_isa_3_0_altivec.stdout.exp
==============================================================================
--- trunk/none/tests/ppc64/test_isa_3_0_altivec.stdout.exp (original)
+++ trunk/none/tests/ppc64/test_isa_3_0_altivec.stdout.exp Wed Jun 29 19:09:57 2016
@@ -70300,6 +70300,547 @@
lxvl 00101f0800101f10 00101f0000101f02 0x10 [ 5a05a05a05a05a05 5a05a05a05a05a05 5a05a05a05a05a05 5a05a05a05a05a05 ]=> 5a05a05a05a05a05 5a05a05a05a05a05 & 1000000000000000
lxvl 00101f0800101f10 00101f0000101f02 0x10 [ 0102030405060708 0102030405060708 0102030405060708 0102030405060708 ]=> 0102030405060708 0102030405060708 & 1000000000000000
+lxvll 0000000000000000 0000000000000000 0x 0 [ ffffffffffffffff ffffffffffffffff ffffffffffffffff ffffffffffffffff ]=> 0000000000000000 0000000000000000 & 0
+lxvll 0000000000000000 0000000000000000 0x 0 [ aaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaa ]=> 0000000000000000 0000000000000000 & 0
+lxvll 0000000000000000 0000000000000000 0x 0 [ 5555555555555555 5555555555555555 5555555555555555 5555555555555555 ]=> 0000000000000000 0000000000000000 & 0
+lxvll 0000000000000000 0000000000000000 0x 0 [ 0000000000000000 0000000000000000 0000000000000000 0000000000000000 ]=> 0000000000000000 0000000000000000 & 0
+lxvll 0000000000000000 0000000000000000 0x 0 [ 5a05a05a05a05a05 5a05a05a05a05a05 5a05a05a05a05a05 5a05a05a05a05a05 ]=> 0000000000000000 0000000000000000 & 0
+lxvll 0000000000000000 0000000000000000 0x 0 [ 0102030405060708 0102030405060708 0102030405060708 0102030405060708 ]=> 0000000000000000 0000000000000000 & 0
+lxvll 0000000000000000 0000000000000000 0x 4 [ ffffffffffffffff ffffffffffffffff ffffffffffffffff ffffffffffffffff ]=> ffffffff00000000 0000000000000000 & 400000000000000
+lxvll 0000000000000000 0000000000000000 0x 4 [ aaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaa ]=> aaaaaaaa00000000 0000000000000000 & 400000000000000
+lxvll 0000000000000000 0000000000000000 0x 4 [ 5555555555555555 5555555555555555 5555555555555555 5555555555555555 ]=> 5555555500000000 0000000000000000 & 400000000000000
+lxvll 0000000000000000 0000000000000000 0x 4 [ 0000000000000000 0000000000000000 0000000000000000 0000000000000000 ]=> 0000000000000000 0000000000000000 & 400000000000000
+lxvll 0000000000000000 0000000000000000 0x 4 [ 5a05a05a05a05a05 5a05a05a05a05a05 5a05a05a05a05a05 5a05a05a05a05a05 ]=> 055aa00500000000 0000000000000000 & 400000000000000
+lxvll 0000000000000000 0000000000000000 0x 4 [ 0102030405060708 0102030405060708 0102030405060708 0102030405060708 ]=> 0807060500000000 0000000000000000 & 400000000000000
+lxvll 0000000000000000 0000000000000000 0x 8 [ ffffffffffffffff ffffffffffffffff ffffffffffffffff ffffffffffffffff ]=> ffffffffffffffff 0000000000000000 & 800000000000000
+lxvll 0000000000000000 0000000000000000 0x 8 [ aaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaa ]=> aaaaaaaaaaaaaaaa 0000000000000000 & 800000000000000
+lxvll 0000000000000000 0000000000000000 0x 8 [ 5555555555555555 5555555555555555 5555555555555555 5555555555555555 ]=> 5555555555555555 0000000000000000 & 800000000000000
+lxvll 0000000000000000 0000000000000000 0x 8 [ 0000000000000000 0000000000000000 0000000000000000 0000000000000000 ]=> 0000000000000000 0000000000000000 & 800000000000000
+lxvll 0000000000000000 0000000000000000 0x 8 [ 5a05a05a05a05a05 5a05a05a05a05a05 5a05a05a05a05a05 5a05a05a05a05a05 ]=> 055aa0055aa0055a 0000000000000000 & 800000000000000
+lxvll 0000000000000000 0000000000000000 0x 8 [ 0102030405060708 0102030405060708 0102030405060708 0102030405060708 ]=> 0807060504030201 0000000000000000 & 800000000000000
+lxvll 0000000000000000 0000000000000000 0x c [ ffffffffffffffff ffffffffffffffff ffffffffffffffff ffffffffffffffff ]=> ffffffffffffffff ffffffff00000000 & c00000000000000
+lxvll 0000000000000000 0000000000000000 0x c [ aaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaa ]=> aaaaaaaaaaaaaaaa aaaaaaaa00000000 & c00000000000000
+lxvll 0000000000000000 0000000000000000 0x c [ 5555555555555555 5555555555555555 5555555555555555 5555555555555555 ]=> 5555555555555555 5555555500000000 & c00000000000000
+lxvll 0000000000000000 0000000000000000 0x c [ 0000000000000000 0000000000000000 0000000000000000 0000000000000000 ]=> 0000000000000000 0000000000000000 & c00000000000000
+lxvll 0000000000000000 0000000000000000 0x c [ 5a05a05a05a05a05 5a05a05a05a05a05 5a05a05a05a05a05 5a05a05a05a05a05 ]=> 055aa0055aa0055a 055aa00500000000 & c00000000000000
+lxvll 0000000000000000 0000000000000000 0x c [ 0102030405060708 0102030405060708 0102030405060708 0102030405060708 ]=> 0807060504030201 0807060500000000 & c00000000000000
+lxvll 0000000000000000 0000000000000000 0x10 [ ffffffffffffffff ffffffffffffffff ffffffffffffffff ffffffffffffffff ]=> ffffffffffffffff ffffffffffffffff & 1000000000000000
+lxvll 0000000000000000 0000000000000000 0x10 [ aaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaa ]=> aaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaa & 1000000000000000
+lxvll 0000000000000000 0000000000000000 0x10 [ 5555555555555555 5555555555555555 5555555555555555 5555555555555555 ]=> 5555555555555555 5555555555555555 & 1000000000000000
+lxvll 0000000000000000 0000000000000000 0x10 [ 0000000000000000 0000000000000000 0000000000000000 0000000000000000 ]=> 0000000000000000 0000000000000000 & 1000000000000000
+lxvll 0000000000000000 0000000000000000 0x10 [ 5a05a05a05a05a05 5a05a05a05a05a05 5a05a05a05a05a05 5a05a05a05a05a05 ]=> 055aa0055aa0055a 055aa0055aa0055a & 1000000000000000
+lxvll 0000000000000000 0000000000000000 0x10 [ 0102030405060708 0102030405060708 0102030405060708 0102030405060708 ]=> 0807060504030201 0807060504030201 & 1000000000000000
+lxvll 0102010201020102 0102030405060708 0x 0 [ ffffffffffffffff ffffffffffffffff ffffffffffffffff ffffffffffffffff ]=> 0000000000000000 0000000000000000 & 0
+lxvll 0102010201020102 0102030405060708 0x 0 [ aaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaa ]=> 0000000000000000 0000000000000000 & 0
+lxvll 0102010201020102 0102030405060708 0x 0 [ 5555555555555555 5555555555555555 5555555555555555 5555555555555555 ]=> 0000000000000000 0000000000000000 & 0
+lxvll 0102010201020102 0102030405060708 0x 0 [ 0000000000000000 0000000000000000 0000000000000000 0000000000000000 ]=> 0000000000000000 0000000000000000 & 0
+lxvll 0102010201020102 0102030405060708 0x 0 [ 5a05a05a05a05a05 5a05a05a05a05a05 5a05a05a05a05a05 5a05a05a05a05a05 ]=> 0000000000000000 0000000000000000 & 0
+lxvll 0102010201020102 0102030405060708 0x 0 [ 0102030405060708 0102030405060708 0102030405060708 0102030405060708 ]=> 0000000000000000 0000000000000000 & 0
+lxvll 0102010201020102 0102030405060708 0x 4 [ ffffffffffffffff ffffffffffffffff ffffffffffffffff ffffffffffffffff ]=> ffffffff00000000 0000000000000000 & 400000000000000
+lxvll 0102010201020102 0102030405060708 0x 4 [ aaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaa ]=> aaaaaaaa00000000 0000000000000000 & 400000000000000
+lxvll 0102010201020102 0102030405060708 0x 4 [ 5555555555555555 5555555555555555 5555555555555555 5555555555555555 ]=> 5555555500000000 0000000000000000 & 400000000000000
+lxvll 0102010201020102 0102030405060708 0x 4 [ 0000000000000000 0000000000000000 0000000000000000 0000000000000000 ]=> 0000000000000000 0000000000000000 & 400000000000000
+lxvll 0102010201020102 0102030405060708 0x 4 [ 5a05a05a05a05a05 5a05a05a05a05a05 5a05a05a05a05a05 5a05a05a05a05a05 ]=> 055aa00500000000 0000000000000000 & 400000000000000
+lxvll 0102010201020102 0102030405060708 0x 4 [ 0102030405060708 0102030405060708 0102030405060708 0102030405060708 ]=> 0807060500000000 0000000000000000 & 400000000000000
+lxvll 0102010201020102 0102030405060708 0x 8 [ ffffffffffffffff ffffffffffffffff ffffffffffffffff ffffffffffffffff ]=> ffffffffffffffff 0000000000000000 & 800000000000000
+lxvll 0102010201020102 0102030405060708 0x 8 [ aaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaa ]=> aaaaaaaaaaaaaaaa 0000000000000000 & 800000000000000
+lxvll 0102010201020102 0102030405060708 0x 8 [ 5555555555555555 5555555555555555 5555555555555555 5555555555555555 ]=> 5555555555555555 0000000000000000 & 800000000000000
+lxvll 0102010201020102 0102030405060708 0x 8 [ 0000000000000000 0000000000000000 0000000000000000 0000000000000000 ]=> 0000000000000000 0000000000000000 & 800000000000000
+lxvll 0102010201020102 0102030405060708 0x 8 [ 5a05a05a05a05a05 5a05a05a05a05a05 5a05a05a05a05a05 5a05a05a05a05a05 ]=> 055aa0055aa0055a 0000000000000000 & 800000000000000
+lxvll 0102010201020102 0102030405060708 0x 8 [ 0102030405060708 0102030405060708 0102030405060708 0102030405060708 ]=> 0807060504030201 0000000000000000 & 800000000000000
+lxvll 0102010201020102 0102030405060708 0x c [ ffffffffffffffff ffffffffffffffff ffffffffffffffff ffffffffffffffff ]=> ffffffffffffffff ffffffff00000000 & c00000000000000
+lxvll 0102010201020102 0102030405060708 0x c [ aaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaa ]=> aaaaaaaaaaaaaaaa aaaaaaaa00000000 & c00000000000000
+lxvll 0102010201020102 0102030405060708 0x c [ 5555555555555555 5555555555555555 5555555555555555 5555555555555555 ]=> 5555555555555555 5555555500000000 & c00000000000000
+lxvll 0102010201020102 0102030405060708 0x c [ 0000000000000000 0000000000000000 0000000000000000 0000000000000000 ]=> 0000000000000000 0000000000000000 & c00000000000000
+lxvll 0102010201020102 0102030405060708 0x c [ 5a05a05a05a05a05 5a05a05a05a05a05 5a05a05a05a05a05 5a05a05a05a05a05 ]=> 055aa0055aa0055a 055aa00500000000 & c00000000000000
+lxvll 0102010201020102 0102030405060708 0x c [ 0102030405060708 0102030405060708 0102030405060708 0102030405060708 ]=> 0807060504030201 0807060500000000 & c00000000000000
+lxvll 0102010201020102 0102030405060708 0x10 [ ffffffffffffffff ffffffffffffffff ffffffffffffffff ffffffffffffffff ]=> ffffffffffffffff ffffffffffffffff & 1000000000000000
+lxvll 0102010201020102 0102030405060708 0x10 [ aaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaa ]=> aaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaa & 1000000000000000
+lxvll 0102010201020102 0102030405060708 0x10 [ 5555555555555555 5555555555555555 5555555555555555 5555555555555555 ]=> 5555555555555555 5555555555555555 & 1000000000000000
+lxvll 0102010201020102 0102030405060708 0x10 [ 0000000000000000 0000000000000000 0000000000000000 0000000000000000 ]=> 0000000000000000 0000000000000000 & 1000000000000000
+lxvll 0102010201020102 0102030405060708 0x10 [ 5a05a05a05a05a05 5a05a05a05a05a05 5a05a05a05a05a05 5a05a05a05a05a05 ]=> 055aa0055aa0055a 055aa0055aa0055a & 1000000000000000
+lxvll 0102010201020102 0102030405060708 0x10 [ 0102030405060708 0102030405060708 0102030405060708 0102030405060708 ]=> 0807060504030201 0807060504030201 & 1000000000000000
+lxvll aaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaa 0x 0 [ ffffffffffffffff ffffffffffffffff ffffffffffffffff ffffffffffffffff ]=> 0000000000000000 0000000000000000 & 0
+lxvll aaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaa 0x 0 [ aaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaa ]=> 0000000000000000 0000000000000000 & 0
+lxvll aaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaa 0x 0 [ 5555555555555555 5555555555555555 5555555555555555 5555555555555555 ]=> 0000000000000000 0000000000000000 & 0
+lxvll aaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaa 0x 0 [ 0000000000000000 0000000000000000 0000000000000000 0000000000000000 ]=> 0000000000000000 0000000000000000 & 0
+lxvll aaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaa 0x 0 [ 5a05a05a05a05a05 5a05a05a05a05a05 5a05a05a05a05a05 5a05a05a05a05a05 ]=> 0000000000000000 0000000000000000 & 0
+lxvll aaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaa 0x 0 [ 0102030405060708 0102030405060708 0102030405060708 0102030405060708 ]=> 0000000000000000 0000000000000000 & 0
+lxvll aaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaa 0x 4 [ ffffffffffffffff ffffffffffffffff ffffffffffffffff ffffffffffffffff ]=> ffffffff00000000 0000000000000000 & 400000000000000
+lxvll aaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaa 0x 4 [ aaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaa ]=> aaaaaaaa00000000 0000000000000000 & 400000000000000
+lxvll aaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaa 0x 4 [ 5555555555555555 5555555555555555 5555555555555555 5555555555555555 ]=> 5555555500000000 0000000000000000 & 400000000000000
+lxvll aaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaa 0x 4 [ 0000000000000000 0000000000000000 0000000000000000 0000000000000000 ]=> 0000000000000000 0000000000000000 & 400000000000000
+lxvll aaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaa 0x 4 [ 5a05a05a05a05a05 5a05a05a05a05a05 5a05a05a05a05a05 5a05a05a05a05a05 ]=> 055aa00500000000 0000000000000000 & 400000000000000
+lxvll aaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaa 0x 4 [ 0102030405060708 0102030405060708 0102030405060708 0102030405060708 ]=> 0807060500000000 0000000000000000 & 400000000000000
+lxvll aaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaa 0x 8 [ ffffffffffffffff ffffffffffffffff ffffffffffffffff ffffffffffffffff ]=> ffffffffffffffff 0000000000000000 & 800000000000000
+lxvll aaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaa 0x 8 [ aaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaa ]=> aaaaaaaaaaaaaaaa 0000000000000000 & 800000000000000
+lxvll aaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaa 0x 8 [ 5555555555555555 5555555555555555 5555555555555555 5555555555555555 ]=> 5555555555555555 0000000000000000 & 800000000000000
+lxvll aaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaa 0x 8 [ 0000000000000000 0000000000000000 0000000000000000 0000000000000000 ]=> 0000000000000000 0000000000000000 & 800000000000000
+lxvll aaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaa 0x 8 [ 5a05a05a05a05a05 5a05a05a05a05a05 5a05a05a05a05a05 5a05a05a05a05a05 ]=> 055aa0055aa0055a 0000000000000000 & 800000000000000
+lxvll aaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaa 0x 8 [ 0102030405060708 0102030405060708 0102030405060708 0102030405060708 ]=> 0807060504030201 0000000000000000 & 800000000000000
+lxvll aaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaa 0x c [ ffffffffffffffff ffffffffffffffff ffffffffffffffff ffffffffffffffff ]=> ffffffffffffffff ffffffff00000000 & c00000000000000
+lxvll aaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaa 0x c [ aaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaa ]=> aaaaaaaaaaaaaaaa aaaaaaaa00000000 & c00000000000000
+lxvll aaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaa 0x c [ 5555555555555555 5555555555555555 5555555555555555 5555555555555555 ]=> 5555555555555555 5555555500000000 & c00000000000000
+lxvll aaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaa 0x c [ 0000000000000000 0000000000000000 0000000000000000 0000000000000000 ]=> 0000000000000000 0000000000000000 & c00000000000000
+lxvll aaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaa 0x c [ 5a05a05a05a05a05 5a05a05a05a05a05 5a05a05a05a05a05 5a05a05a05a05a05 ]=> 055aa0055aa0055a 055aa00500000000 & c00000000000000
+lxvll aaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaa 0x c [ 0102030405060708 0102030405060708 0102030405060708 0102030405060708 ]=> 0807060504030201 0807060500000000 & c00000000000000
+lxvll aaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaa 0x10 [ ffffffffffffffff ffffffffffffffff ffffffffffffffff ffffffffffffffff ]=> ffffffffffffffff ffffffffffffffff & 1000000000000000
+lxvll aaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaa 0x10 [ aaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaa ]=> aaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaa & 1000000000000000
+lxvll aaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaa 0x10 [ 5555555555555555 5555555555555555 5555555555555555 5555555555555555 ]=> 5555555555555555 5555555555555555 & 1000000000000000
+lxvll aaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaa 0x10 [ 0000000000000000 0000000000000000 0000000000000000 0000000000000000 ]=> 0000000000000000 0000000000000000 & 1000000000000000
+lxvll aaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaa 0x10 [ 5a05a05a05a05a05 5a05a05a05a05a05 5a05a05a05a05a05 5a05a05a05a05a05 ]=> 055aa0055aa0055a 055aa0055aa0055a & 1000000000000000
+lxvll aaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaa 0x10 [ 0102030405060708 0102030405060708 0102030405060708 0102030405060708 ]=> 0807060504030201 0807060504030201 & 1000000000000000
+lxvll 5555555555555555 5555555555555555 0x 0 [ ffffffffffffffff ffffffffffffffff ffffffffffffffff ffffffffffffffff ]=> 0000000000000000 0000000000000000 & 0
+lxvll 5555555555555555 5555555555555555 0x 0 [ aaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaa ]=> 0000000000000000 0000000000000000 & 0
+lxvll 5555555555555555 5555555555555555 0x 0 [ 5555555555555555 5555555555555555 5555555555555555 5555555555555555 ]=> 0000000000000000 0000000000000000 & 0
+lxvll 5555555555555555 5555555555555555 0x 0 [ 0000000000000000 0000000000000000 0000000000000000 0000000000000000 ]=> 0000000000000000 0000000000000000 & 0
+lxvll 5555555555555555 5555555555555555 0x 0 [ 5a05a05a05a05a05 5a05a05a05a05a05 5a05a05a05a05a05 5a05a05a05a05a05 ]=> 0000000000000000 0000000000000000 & 0
+lxvll 5555555555555555 5555555555555555 0x 0 [ 0102030405060708 0102030405060708 0102030405060708 0102030405060708 ]=> 0000000000000000 0000000000000000 & 0
+lxvll 5555555555555555 5555555555555555 0x 4 [ ffffffffffffffff ffffffffffffffff ffffffffffffffff ffffffffffffffff ]=> ffffffff00000000 0000000000000000 & 400000000000000
+lxvll 5555555555555555 5555555555555555 0x 4 [ aaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaa ]=> aaaaaaaa00000000 0000000000000000 & 400000000000000
+lxvll 5555555555555555 5555555555555555 0x 4 [ 5555555555555555 5555555555555555 5555555555555555 5555555555555555 ]=> 5555555500000000 0000000000000000 & 400000000000000
+lxvll 5555555555555555 5555555555555555 0x 4 [ 0000000000000000 0000000000000000 0000000000000000 0000000000000000 ]=> 0000000000000000 0000000000000000 & 400000000000000
+lxvll 5555555555555555 5555555555555555 0x 4 [ 5a05a05a05a05a05 5a05a05a05a05a05 5a05a05a05a05a05 5a05a05a05a05a05 ]=> 055aa00500000000 0000000000000000 & 400000000000000
+lxvll 5555555555555555 5555555555555555 0x 4 [ 0102030405060708 0102030405060708 0102030405060708 0102030405060708 ]=> 0807060500000000 0000000000000000 & 400000000000000
+lxvll 5555555555555555 5555555555555555 0x 8 [ ffffffffffffffff ffffffffffffffff ffffffffffffffff ffffffffffffffff ]=> ffffffffffffffff 0000000000000000 & 800000000000000
+lxvll 5555555555555555 5555555555555555 0x 8 [ aaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaa ]=> aaaaaaaaaaaaaaaa 0000000000000000 & 800000000000000
+lxvll 5555555555555555 5555555555555555 0x 8 [ 5555555555555555 5555555555555555 5555555555555555 5555555555555555 ]=> 5555555555555555 0000000000000000 & 800000000000000
+lxvll 5555555555555555 5555555555555555 0x 8 [ 0000000000000000 0000000000000000 0000000000000000 0000000000000000 ]=> 0000000000000000 0000000000000000 & 800000000000000
+lxvll 5555555555555555 5555555555555555 0x 8 [ 5a05a05a05a05a05 5a05a05a05a05a05 5a05a05a05a05a05 5a05a05a05a05a05 ]=> 055aa0055aa0055a 0000000000000000 & 800000000000000
+lxvll 5555555555555555 5555555555555555 0x 8 [ 0102030405060708 0102030405060708 0102030405060708 0102030405060708 ]=> 0807060504030201 0000000000000000 & 800000000000000
+lxvll 5555555555555555 5555555555555555 0x c [ ffffffffffffffff ffffffffffffffff ffffffffffffffff ffffffffffffffff ]=> ffffffffffffffff ffffffff00000000 & c00000000000000
+lxvll 5555555555555555 5555555555555555 0x c [ aaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaa ]=> aaaaaaaaaaaaaaaa aaaaaaaa00000000 & c00000000000000
+lxvll 5555555555555555 5555555555555555 0x c [ 5555555555555555 5555555555555555 5555555555555555 5555555555555555 ]=> 5555555555555555 5555555500000000 & c00000000000000
+lxvll 5555555555555555 5555555555555555 0x c [ 0000000000000000 0000000000000000 0000000000000000 0000000000000000 ]=> 0000000000000000 0000000000000000 & c00000000000000
+lxvll 5555555555555555 5555555555555555 0x c [ 5a05a05a05a05a05 5a05a05a05a05a05 5a05a05a05a05a05 5a05a05a05a05a05 ]=> 055aa0055aa0055a 055aa00500000000 & c00000000000000
+lxvll 5555555555555555 5555555555555555 0x c [ 0102030405060708 0102030405060708 0102030405060708 0102030405060708 ]=> 0807060504030201 0807060500000000 & c00000000000000
+lxvll 5555555555555555 5555555555555555 0x10 [ ffffffffffffffff ffffffffffffffff ffffffffffffffff ffffffffffffffff ]=> ffffffffffffffff ffffffffffffffff & 1000000000000000
+lxvll 5555555555555555 5555555555555555 0x10 [ aaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaa ]=> aaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaa & 1000000000000000
+lxvll 5555555555555555 5555555555555555 0x10 [ 5555555555555555 5555555555555555 5555555555555555 5555555555555555 ]=> 5555555555555555 5555555555555555 & 1000000000000000
+lxvll 5555555555555555 5555555555555555 0x10 [ 0000000000000000 0000000000000000 0000000000000000 0000000000000000 ]=> 0000000000000000 0000000000000000 & 1000000000000000
+lxvll 5555555555555555 5555555555555555 0x10 [ 5a05a05a05a05a05 5a05a05a05a05a05 5a05a05a05a05a05 5a05a05a05a05a05 ]=> 055aa0055aa0055a 055aa0055aa0055a & 1000000000000000
+lxvll 5555555555555555 5555555555555555 0x10 [ 0102030405060708 0102030405060708 0102030405060708 0102030405060708 ]=> 0807060504030201 0807060504030201 & 1000000000000000
+lxvll 0102010201020102 08090a0b0c0d0e0f 0x 0 [ ffffffffffffffff ffffffffffffffff ffffffffffffffff ffffffffffffffff ]=> 0000000000000000 0000000000000000 & 0
+lxvll 0102010201020102 08090a0b0c0d0e0f 0x 0 [ aaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaa ]=> 0000000000000000 0000000000000000 & 0
+lxvll 0102010201020102 08090a0b0c0d0e0f 0x 0 [ 5555555555555555 5555555555555555 5555555555555555 5555555555555555 ]=> 0000000000000000 0000000000000000 & 0
+lxvll 0102010201020102 08090a0b0c0d0e0f 0x 0 [ 0000000000000000 0000000000000000 0000000000000000 0000000000000000 ]=> 0000000000000000 0000000000000000 & 0
+lxvll 0102010201020102 08090a0b0c0d0e0f 0x 0 [ 5a05a05a05a05a05 5a05a05a05a05a05 5a05a05a05a05a05 5a05a05a05a05a05 ]=> 0000000000000000 0000000000000000 & 0
+lxvll 0102010201020102 08090a0b0c0d0e0f 0x 0 [ 0102030405060708 0102030405060708 0102030405060708 0102030405060708 ]=> 0000000000000000 0000000000000000 & 0
+lxvll 0102010201020102 08090a0b0c0d0e0f 0x 4 [ ffffffffffffffff ffffffffffffffff ffffffffffffffff ffffffffffffffff ]=> ffffffff00000000 0000000000000000 & 400000000000000
+lxvll 0102010201020102 08090a0b0c0d0e0f 0x 4 [ aaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaa ]=> aaaaaaaa00000000 0000000000000000 & 400000000000000
+lxvll 0102010201020102 08090a0b0c0d0e0f 0x 4 [ 5555555555555555 5555555555555555 5555555555555555 5555555555555555 ]=> 5555555500000000 0000000000000000 & 400000000000000
+lxvll 0102010201020102 08090a0b0c0d0e0f 0x 4 [ 0000000000000000 0000000000000000 0000000000000000 0000000000000000 ]=> 0000000000000000 0000000000000000 & 400000000000000
+lxvll 0102010201020102 08090a0b0c0d0e0f 0x 4 [ 5a05a05a05a05a05 5a05a05a05a05a05 5a05a05a05a05a05 5a05a05a05a05a05 ]=> 055aa00500000000 0000000000000000 & 400000000000000
+lxvll 0102010201020102 08090a0b0c0d0e0f 0x 4 [ 0102030405060708 0102030405060708 0102030405060708 0102030405060708 ]=> 0807060500000000 0000000000000000 & 400000000000000
+lxvll 0102010201020102 08090a0b0c0d0e0f 0x 8 [ ffffffffffffffff ffffffffffffffff ffffffffffffffff ffffffffffffffff ]=> ffffffffffffffff 0000000000000000 & 800000000000000
+lxvll 0102010201020102 08090a0b0c0d0e0f 0x 8 [ aaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaa ]=> aaaaaaaaaaaaaaaa 0000000000000000 & 800000000000000
+lxvll 0102010201020102 08090a0b0c0d0e0f 0x 8 [ 5555555555555555 5555555555555555 5555555555555555 5555555555555555 ]=> 5555555555555555 0000000000000000 & 800000000000000
+lxvll 0102010201020102 08090a0b0c0d0e0f 0x 8 [ 0000000000000000 0000000000000000 0000000000000000 0000000000000000 ]=> 0000000000000000 0000000000000000 & 800000000000000
+lxvll 0102010201020102 08090a0b0c0d0e0f 0x 8 [ 5a05a05a05a05a05 5a05a05a05a05a05 5a05a05a05a05a05 5a05a05a05a05a05 ]=> 055aa0055aa0055a 0000000000000000 & 800000000000000
+lxvll 0102010201020102 08090a0b0c0d0e0f 0x 8 [ 0102030405060708 0102030405060708 0102030405060708 0102030405060708 ]=> 0807060504030201 0000000000000000 & 800000000000000
+lxvll 0102010201020102 08090a0b0c0d0e0f 0x c [ ffffffffffffffff ffffffffffffffff ffffffffffffffff ffffffffffffffff ]=> ffffffffffffffff ffffffff00000000 & c00000000000000
+lxvll 0102010201020102 08090a0b0c0d0e0f 0x c [ aaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaa ]=> aaaaaaaaaaaaaaaa aaaaaaaa00000000 & c00000000000000
+lxvll 0102010201020102 08090a0b0c0d0e0f 0x c [ 5555555555555555 5555555555555555 5555555555555555 5555555555555555 ]=> 5555555555555555 5555555500000000 & c00000000000000
+lxvll 0102010201020102 08090a0b0c0d0e0f 0x c [ 0000000000000000 0000000000000000 0000000000000000 0000000000000000 ]=> 0000000000000000 0000000000000000 & c00000000000000
+lxvll 0102010201020102 08090a0b0c0d0e0f 0x c [ 5a05a05a05a05a05 5a05a05a05a05a05 5a05a05a05a05a05 5a05a05a05a05a05 ]=> 055aa0055aa0055a 055aa00500000000 & c00000000000000
+lxvll 0102010201020102 08090a0b0c0d0e0f 0x c [ 0102030405060708 0102030405060708 0102030405060708 0102030405060708 ]=> 0807060504030201 0807060500000000 & c00000000000000
+lxvll 0102010201020102 08090a0b0c0d0e0f 0x10 [ ffffffffffffffff ffffffffffffffff ffffffffffffffff ffffffffffffffff ]=> ffffffffffffffff ffffffffffffffff & 1000000000000000
+lxvll 0102010201020102 08090a0b0c0d0e0f 0x10 [ aaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaa ]=> aaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaa & 1000000000000000
+lxvll 0102010201020102 08090a0b0c0d0e0f 0x10 [ 5555555555555555 5555555555555555 5555555555555555 5555555555555555 ]=> 5555555555555555 5555555555555555 & 1000000000000000
+lxvll 0102010201020102 08090a0b0c0d0e0f 0x10 [ 0000000000000000 0000000000000000 0000000000000000 0000000000000000 ]=> 0000000000000000 0000000000000000 & 1000000000000000
+lxvll 0102010201020102 08090a0b0c0d0e0f 0x10 [ 5a05a05a05a05a05 5a05a05a05a05a05 5a05a05a05a05a05 5a05a05a05a05a05 ]=> 055aa0055aa0055a 055aa0055aa0055a & 1000000000000000
+lxvll 0102010201020102 08090a0b0c0d0e0f 0x10 [ 0102030405060708 0102030405060708 0102030405060708 0102030405060708 ]=> 0807060504030201 0807060504030201 & 1000000000000000
+lxvll f8f9fafbfcfdfeff f0f1f2f3f4f5f6f7 0x 0 [ ffffffffffffffff ffffffffffffffff ffffffffffffffff ffffffffffffffff ]=> 0000000000000000 0000000000000000 & 0
+lxvll f8f9fafbfcfdfeff f0f1f2f3f4f5f6f7 0x 0 [ aaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaa ]=> 0000000000000000 0000000000000000 & 0
+lxvll f8f9fafbfcfdfeff f0f1f2f3f4f5f6f7 0x 0 [ 5555555555555555 5555555555555555 5555555555555555 5555555555555555 ]=> 0000000000000000 0000000000000000 & 0
+lxvll f8f9fafbfcfdfeff f0f1f2f3f4f5f6f7 0x 0 [ 0000000000000000 0000000000000000 0000000000000000 0000000000000000 ]=> 0000000000000000 0000000000000000 & 0
+lxvll f8f9fafbfcfdfeff f0f1f2f3f4f5f6f7 0x 0 [ 5a05a05a05a05a05 5a05a05a05a05a05 5a05a05a05a05a05 5a05a05a05a05a05 ]=> 0000000000000000 0000000000000000 & 0
+lxvll f8f9fafbfcfdfeff f0f1f2f3f4f5f6f7 0x 0 [ 0102030405060708 0102030405060708 0102030405060708 0102030405060708 ]=> 0000000000000000 0000000000000000 & 0
+lxvll f8f9fafbfcfdfeff f0f1f2f3f4f5f6f7 0x 4 [ ffffffffffffffff ffffffffffffffff ffffffffffffffff ffffffffffffffff ]=> ffffffff00000000 0000000000000000 & 400000000000000
+lxvll f8f9fafbfcfdfeff f0f1f2f3f4f5f6f7 0x 4 [ aaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaa ]=> aaaaaaaa00000000 0000000000000000 & 400000000000000
+lxvll f8f9fafbfcfdfeff f0f1f2f3f4f5f6f7 0x 4 [ 5555555555555555 5555555555555555 5555555555555555 5555555555555555 ]=> 5555555500000000 0000000000000000 & 400000000000000
+lxvll f8f9fafbfcfdfeff f0f1f2f3f4f5f6f7 0x 4 [ 0000000000000000 0000000000000000 0000000000000000 0000000000000000 ]=> 0000000000000000 0000000000000000 & 400000000000000
+lxvll f8f9fafbfcfdfeff f0f1f2f3f4f5f6f7 0x 4 [ 5a05a05a05a05a05 5a05a05a05a05a05 5a05a05a05a05a05 5a05a05a05a05a05 ]=> 055aa00500000000 0000000000000000 & 40000000000...
[truncated message content] |
|
From: <sv...@va...> - 2016-06-29 18:06:28
|
Author: carll
Date: Wed Jun 29 19:06:15 2016
New Revision: 3222
Log:
Power PC Add support for ISA 3.0, part 4
Added support to emulate the setb, cmprb, cmpeqb, dtstsfi,
dtstsfiq, dtstsfq, dtstsfiq, xscmpexpdp, xsxexpd, xsxsigdp,
xststdcsp, xststdcdp, xvtstdcsp, xvxsigdp, xsiexpdp, xvxexpdp,
xvxsigdp, xvxexpsp, xvxsigsp, xvtstdcdp, xvxsigdp, wait, addpcis
instructions.
bugzilla 363858
Modified:
trunk/priv/guest_ppc_defs.h
trunk/priv/guest_ppc_helpers.c
trunk/priv/guest_ppc_toIR.c
trunk/pub/libvex_guest_ppc32.h
trunk/pub/libvex_guest_ppc64.h
Modified: trunk/priv/guest_ppc_defs.h
==============================================================================
--- trunk/priv/guest_ppc_defs.h (original)
+++ trunk/priv/guest_ppc_defs.h Wed Jun 29 19:06:15 2016
@@ -147,7 +147,16 @@
/* --- CLEAN HELPERS --- */
-/* none, right now */
+extern ULong is_BCDstring128_helper( ULong Signed, ULong hi64, ULong low64 );
+extern ULong increment_BCDstring32_helper( ULong Signed,
+ ULong bcd_string, ULong carry_in );
+extern ULong convert_to_zoned_helper( ULong src_hi, ULong src_low,
+ ULong upper_byte,
+ ULong return_upper );
+extern ULong convert_to_national_helper( ULong src, ULong return_upper );
+extern ULong convert_from_zoned_helper( ULong src_hi, ULong src_low );
+extern ULong convert_from_national_helper( ULong src_hi, ULong src_low );
+
/* --- DIRTY HELPERS --- */
Modified: trunk/priv/guest_ppc_helpers.c
==============================================================================
--- trunk/priv/guest_ppc_helpers.c (original)
+++ trunk/priv/guest_ppc_helpers.c Wed Jun 29 19:06:15 2016
@@ -216,6 +216,216 @@
}
+/*---------------------------------------------------------------*/
+/*--- Misc BCD clean helpers. ---*/
+/*---------------------------------------------------------------*/
+
+/* This C-helper takes a 128-bit BCD value as two 64-bit pieces.
+ * It checks the string to see if it is a valid 128-bit BCD value.
+ * A valid BCD value has a sign value in bits [3:0] between 0xA
+ * and 0xF inclusive. each of the BCD digits represented as a 4-bit
+ * hex number in bits BCD value[128:4] mut be between 0 and 9
+ * inclusive. Returns an unsigned 64-bit value if valid.
+ */
+ULong is_BCDstring128_helper( ULong Signed, ULong bcd_string_hi,
+ ULong bcd_string_low ) {
+ Int i;
+ ULong valid_bcd, sign_valid = False;
+ ULong digit;
+ UInt sign;
+
+ if ( Signed == True ) {
+ sign = bcd_string_low & 0xF;
+ if( ( sign >= 0xA ) && ( sign <= 0xF ) )
+ sign_valid = True;
+
+ /* Change the sign digit to a zero
+ * so the for loop below works the same
+ * for signed and unsigned BCD stings
+ */
+ bcd_string_low &= 0xFFFFFFFFFFFFFFF0ULL;
+
+ } else {
+ sign_valid = True; /* set sign to True so result is only
+ based on the validity of the digits */
+ }
+
+ valid_bcd = True; // Assume true to start
+ for( i = 0; i < 32; i++ ) {
+ /* check high and low 64-bit strings in parallel */
+ digit = bcd_string_low & 0xF;
+ if ( digit > 0x9 )
+ valid_bcd = False;
+ bcd_string_low = bcd_string_low >> 4;
+
+ digit = bcd_string_hi & 0xF;
+ if ( digit > 0x9 )
+ valid_bcd = False;
+ bcd_string_hi = bcd_string_hi >> 4;
+ }
+
+ return valid_bcd & sign_valid;
+}
+
+/* This clean helper takes a signed 32-bit BCD value and a carry in
+ * and adds 1 to the value of the BCD value. The BCD value is passed
+ * in as a single 64-bit value. The incremented value is returned in
+ * the lower 32 bits of the result. If the input was signed the sign of
+ * the result is the same as the input. The carry out is returned in
+ * bits [35:32] of the result.
+ */
+ULong increment_BCDstring32_helper( ULong Signed,
+ ULong bcd_string, ULong carry_in ) {
+ UInt i, num_digits = 8;
+ ULong bcd_value, result = 0;
+ ULong carry, digit, new_digit;
+
+ carry = carry_in;
+
+ if ( Signed == True ) {
+ bcd_value = bcd_string >> 4; /* remove sign */
+ num_digits = num_digits - 1;
+ } else {
+ bcd_value = bcd_string;
+ }
+
+ for( i = 0; i < num_digits; i++ ) {
+ digit = bcd_value & 0xF;
+ bcd_value = bcd_value >> 4;
+ new_digit = digit + carry;
+
+ if ( new_digit > 10 ) {
+ carry = 1;
+ new_digit = new_digit - 10;
+
+ } else {
+ carry = 0;
+ }
+ result = result | (new_digit << (i*4) );
+ }
+
+ if ( Signed == True ) {
+ result = ( carry << 32) | ( result << 4 ) | ( bcd_string & 0xF );
+ } else {
+ result = ( carry << 32) | result;
+ }
+
+ return result;
+}
+
+/*---------------------------------------------------------------*/
+/*--- Misc packed decimal clean helpers. ---*/
+/*---------------------------------------------------------------*/
+
+/* This C-helper takes a 64-bit packed decimal value stored in a
+ * 64-bit value. It converts the zoned decimal format. The lower
+ * byte may contain a sign value, set it to zero. If return_upper
+ * is zero, return lower 64 bits of result, otherwise return upper
+ * 64 bits of the result.
+ */
+ULong convert_to_zoned_helper( ULong src_hi, ULong src_low,
+ ULong upper_byte, ULong return_upper ) {
+ UInt i, sh;
+ ULong tmp = 0, new_value;
+
+ /* Remove the sign from the source. Put in the upper byte of result.
+ * Sign inserted later.
+ */
+ if ( return_upper == 0 ) { /* return lower 64-bit result */
+ for(i = 0; i < 7; i++) {
+ sh = ( 8 - i ) * 4;
+ new_value = ( ( src_low >> sh ) & 0xf ) | upper_byte;
+ tmp = tmp | ( new_value << ( ( 7 - i ) * 8 ) );
+ }
+
+ } else {
+ /* Byte for i=0 is in upper 64-bit of the source, do it separately */
+ new_value = ( src_hi & 0xf ) | upper_byte;
+ tmp = tmp | new_value << 56;
+
+ for( i = 1; i < 8; i++ ) {
+ sh = ( 16 - i ) * 4;
+ new_value = ( ( src_low >> sh ) & 0xf ) | upper_byte;
+ tmp = tmp | ( new_value << ( ( 7 - i ) * 8 ) );
+ }
+ }
+ return tmp;
+}
+
+/* This C-helper takes the lower 64-bits of the 128-bit packed decimal
+ * src value. It converts the src value to a 128-bit national format.
+ * If return_upper is zero, the helper returns lower 64 bits of result,
+ * otherwise it returns the upper 64-bits of the result.
+ */
+ULong convert_to_national_helper( ULong src, ULong return_upper ) {
+
+ UInt i;
+ UInt sh = 3, max = 4, min = 0; /* initialize max, min for return upper */
+ ULong tmp = 0, new_value;
+
+ if ( return_upper == 0 ) { /* return lower 64-bit result */
+ min = 4;
+ max = 7;
+ sh = 7;
+ }
+
+ for( i = min; i < max; i++ ) {
+ new_value = ( ( src >> ( ( 7 - i ) * 4 ) ) & 0xf ) | 0x0030;
+ tmp = tmp | ( new_value << ( ( sh - i ) * 16 ) );
+ }
+ return tmp;
+}
+
+/* This C-helper takes a 128-bit zoned value stored in a 128-bit
+ * value. It converts it to the packed 64-bit decimal format without a
+ * a sign value. The sign is supposed to be in bits [3:0] and the packed
+ * value in bits [67:4]. This helper leaves it to the caller to put the
+ * result into a V128 and shift the returned value over and put the sign
+ * in.
+ */
+ULong convert_from_zoned_helper( ULong src_hi, ULong src_low ) {
+ UInt i;
+ ULong tmp = 0, nibble;
+
+ /* Unroll the i = 0 iteration so the sizes of the loop for the upper
+ * and lower extraction match. Skip sign in lease significant byte.
+ */
+ nibble = ( src_hi >> 56 ) & 0xF;
+ tmp = tmp | ( nibble << 60 );
+
+ for( i = 1; i < 8; i++ ) {
+ /* get the high nibbles, put into result */
+ nibble = ( src_hi >> ( ( 7 - i ) * 8 ) ) & 0xF;
+ tmp = tmp | ( nibble << ( ( 15 - i ) * 4 ) );
+
+ /* get the low nibbles, put into result */
+ nibble = ( src_low >> ( ( 8 - i ) * 8 ) ) & 0xF;
+ tmp = tmp | ( nibble << ( ( 8 - i ) * 4 ) );
+ }
+ return tmp;
+}
+
+/* This C-helper takes a 128-bit national value stored in a 128-bit
+ * value. It converts it to a signless packed 64-bit decimal format.
+ */
+ULong convert_from_national_helper( ULong src_hi, ULong src_low ) {
+ UInt i;
+ ULong tmp = 0, hword;
+
+ src_low = src_low & 0xFFFFFFFFFFFFFFF0ULL; /* remove the sign */
+
+ for( i = 0; i < 4; i++ ) {
+ /* get the high half-word, put into result */
+ hword = ( src_hi >> ( ( 3 - i ) * 16 ) ) & 0xF;
+ tmp = tmp | ( hword << ( ( 7 - i ) * 4 ) );
+
+ /* get the low half-word, put into result */
+ hword = ( src_low >> ( ( 3 - i ) * 16 ) ) & 0xF;
+ tmp = tmp | ( hword << ( ( 3 - i ) * 4 ) );
+ }
+ return tmp;
+}
+
/*----------------------------------------------*/
/*--- The exported fns .. ---*/
/*----------------------------------------------*/
@@ -500,7 +710,7 @@
vex_state->guest_FPROUND = PPCrm_NEAREST;
vex_state->guest_DFPROUND = PPCrm_NEAREST;
- vex_state->guest_FPCC = 0;
+ vex_state->guest_C_FPCC = 0;
vex_state->pad2 = 0;
vex_state->guest_VRSAVE = 0;
@@ -667,7 +877,7 @@
vex_state->guest_FPROUND = PPCrm_NEAREST;
vex_state->guest_DFPROUND = PPCrm_NEAREST;
- vex_state->guest_FPCC = 0;
+ vex_state->guest_C_FPCC = 0;
vex_state->pad2 = 0;
vex_state->guest_VRSAVE = 0;
@@ -834,7 +1044,7 @@
/* 8 */ ALWAYSDEFD32(guest_REDIR_SP),
/* 9 */ ALWAYSDEFD32(guest_REDIR_STACK),
/* 10 */ ALWAYSDEFD32(guest_IP_AT_SYSCALL),
- /* 11 */ ALWAYSDEFD32(guest_FPCC)
+ /* 11 */ ALWAYSDEFD32(guest_C_FPCC)
}
};
@@ -876,7 +1086,7 @@
/* 8 */ ALWAYSDEFD64(guest_REDIR_SP),
/* 9 */ ALWAYSDEFD64(guest_REDIR_STACK),
/* 10 */ ALWAYSDEFD64(guest_IP_AT_SYSCALL),
- /* 11 */ ALWAYSDEFD64(guest_FPCC)
+ /* 11 */ ALWAYSDEFD64(guest_C_FPCC)
}
};
Modified: trunk/priv/guest_ppc_toIR.c
==============================================================================
--- trunk/priv/guest_ppc_toIR.c (original)
+++ trunk/priv/guest_ppc_toIR.c Wed Jun 29 19:06:15 2016
@@ -277,7 +277,7 @@
#define OFFB_XER_BC offsetofPPCGuestState(guest_XER_BC)
#define OFFB_FPROUND offsetofPPCGuestState(guest_FPROUND)
#define OFFB_DFPROUND offsetofPPCGuestState(guest_DFPROUND)
-#define OFFB_FPCC offsetofPPCGuestState(guest_FPCC)
+#define OFFB_C_FPCC offsetofPPCGuestState(guest_C_FPCC)
#define OFFB_VRSAVE offsetofPPCGuestState(guest_VRSAVE)
#define OFFB_VSCR offsetofPPCGuestState(guest_VSCR)
#define OFFB_EMNOTE offsetofPPCGuestState(guest_EMNOTE)
@@ -457,8 +457,10 @@
PPC_GST_MAX
} PPC_GST;
-#define MASK_FPSCR_RN 0x3ULL // Binary floating point rounding mode
-#define MASK_FPSCR_DRN 0x700000000ULL // Decimal floating point rounding mode
+#define MASK_FPSCR_RN 0x3ULL // Binary floating point rounding mode
+#define MASK_FPSCR_DRN 0x700000000ULL // Decimal floating point rounding mode
+#define MASK_FPSCR_C_FPCC 0x1F000ULL // Floating-Point Condition code FPCC
+
#define MASK_VSCR_VALID 0x00010001
@@ -634,6 +636,8 @@
return IRExpr_RdTmp(tmp);
}
+#define mkU1(_n) IRExpr_Const(IRConst_U1(_n))
+
static IRExpr* mkU8 ( UChar i )
{
return IRExpr_Const(IRConst_U8(i));
@@ -3205,6 +3209,31 @@
)
);
}
+
+ if (mask & MASK_FPSCR_C_FPCC) {
+ stmt(
+ IRStmt_Put(
+ OFFB_C_FPCC,
+ unop(
+ Iop_32to8,
+ binop(
+ Iop_Or32,
+ binop(
+ Iop_And32,
+ unop(Iop_64to32, src),
+ mkU32(MASK_FPSCR_C_FPCC & mask)
+ ),
+ binop(
+ Iop_And32,
+ unop(Iop_8Uto32, IRExpr_Get(OFFB_C_FPCC,Ity_I8)),
+ mkU32(MASK_FPSCR_C_FPCC & ~mask)
+ )
+ )
+ )
+ )
+ );
+ }
+
/* Similarly, update FPSCR.DRN if any bits of |mask|
corresponding to FPSCR.DRN are set. */
if (mask & MASK_FPSCR_DRN) {
@@ -3303,29 +3332,53 @@
/* The assumption is that the value of the FPCC are passed in the lower
* four bits of a 32 bit value.
*
- * Note, the FPCC bits are a field of the FPSCR
+ * Note, the C and FPCC bits which are a field of the FPSCR
* register are stored in their own "register" in
- * memory. We don't need to shift it to the bits to
- * their location in the FPSCR register. Note, not all
- * of the FPSCR register bits are supported. We are
- * writing all of the bits in the FPCC field.
+ * memory. The FPCC bits are in the lower 4 bits. We don't need to
+ * shift it to the bits to their location in the FPSCR register. Note,
+ * not all of the FPSCR register bits are supported. We are writing all
+ * of the bits in the FPCC field but not the C field.
+ */
+ IRExpr* tmp;
+
+ vassert( typeOfIRExpr( irsb->tyenv, e ) == Ity_I32 );
+ /* Get the C bit field */
+ tmp = binop( Iop_And32,
+ mkU32( 0x10 ),
+ unop( Iop_8Uto32, IRExpr_Get( OFFB_C_FPCC, Ity_I8 ) ) );
+
+ stmt( IRStmt_Put( OFFB_C_FPCC,
+ unop( Iop_32to8,
+ binop( Iop_Or32, tmp,
+ binop( Iop_And32, mkU32( 0xF ), e ) ) ) ) );
+
+}
+
+static IRExpr* /* ::Ity_I32 */ getC ( void )
+{
+ /* Note, the Floating-Point Result Class Descriptor (C) bit is a field of
+ * the FPSCR registered are stored in its own "register" in guest state
+ * with the FPCC bit field. C | FPCC
*/
+ IRTemp val = newTemp(Ity_I32);
- vassert( typeOfIRExpr(irsb->tyenv, e) == Ity_I32 );
- stmt( IRStmt_Put(OFFB_FPCC,
- unop( Iop_32to8,
- binop( Iop_And32, mkU32( 0xF ), e ) ) ) );
+ assign( val, binop( Iop_Shr32,
+ unop( Iop_8Uto32, IRExpr_Get( OFFB_C_FPCC, Ity_I8 ) ),
+ mkU8( 4 ) ) );
+ return mkexpr(val);
}
static IRExpr* /* ::Ity_I32 */ getFPCC ( void )
{
/* Note, the FPCC bits are a field of the FPSCR
* register are stored in their own "register" in
- * guest state.
+ * guest state with the C bit field. C | FPCC
*/
IRTemp val = newTemp( Ity_I32 );
- assign( val, unop( Iop_8Uto32, IRExpr_Get( OFFB_FPCC, Ity_I8 ) ) );
+ assign( val, binop( Iop_And32, unop( Iop_8Uto32,
+ IRExpr_Get( OFFB_C_FPCC, Ity_I8 ) ),
+ mkU32( 0xF ) ));
return mkexpr(val);
}
@@ -3834,6 +3887,432 @@
mkAND1( both_neg, neg_cmp ) ) ) ) );
}
+/*-----------------------------------------------------------
+ * Helpers for VX instructions that work on National decimal values,
+ * Zoned decimal values and BCD values.
+ *
+ *------------------------------------------------------------*/
+static IRExpr * is_National_decimal (IRTemp src)
+{
+ /* The src is a 128-bit value containing a sign code in half word 7
+ * and seven digits in halfwords 0 to 6 (IBM numbering). A valid
+ * national decimal value has the following:
+ * - the sign code must be 0x002B (positive) or 0x002D (negative)
+ * - the digits must be in the range 0x0030 to 0x0039
+ */
+ Int i;
+ IRExpr * valid_pos_sign;
+ IRExpr * valid_neg_sign;
+ IRTemp valid_num[8];
+ IRTemp digit[7];
+
+ valid_pos_sign = binop( Iop_CmpEQ64,
+ binop( Iop_And64,
+ mkU64( 0xFFFF ),
+ unop( Iop_V128to64, mkexpr( src ) ) ),
+ mkU64( 0x002B ) );
+
+ valid_neg_sign = binop( Iop_CmpEQ64,
+ binop( Iop_And64,
+ mkU64( 0xFFFF ),
+ unop( Iop_V128to64, mkexpr( src ) ) ),
+ mkU64( 0x002D ) );
+
+ valid_num[0] = newTemp( Ity_I1 );
+ digit[0] = newTemp( Ity_I64 );
+ assign( valid_num[0], mkU1( 1 ) ); // Assume true to start
+
+ for(i = 0; i < 7; i++) {
+ valid_num[i+1] = newTemp( Ity_I1 );
+ digit[i] = newTemp( Ity_I64 );
+ assign( digit[i], binop( Iop_And64,
+ unop( Iop_V128to64,
+ binop( Iop_ShrV128,
+ mkexpr( src ),
+ mkU8( (7-i)*16 ) ) ),
+ mkU64( 0xFFFF ) ) );
+
+ assign( valid_num[i+1],
+ mkAND1( mkexpr( valid_num[i] ),
+ mkAND1( binop( Iop_CmpLE64U,
+ mkexpr( digit[i] ),
+ mkU64( 0x39 ) ),
+ binop( Iop_CmpLE64U,
+ mkU64( 0x30 ),
+ mkexpr( digit[i] ) ) ) ) );
+ }
+
+ return mkAND1( mkOR1( valid_pos_sign, valid_neg_sign),
+ mkexpr( valid_num[7] ) );
+}
+
+static IRExpr * is_Zoned_decimal (IRTemp src, UChar ps)
+{
+ /* The src is a 128-bit value containing a sign code the least significant
+ * two bytes. The upper pairs of bytes contain digits. A valid Zoned
+ * decimal value has the following:
+ * - the sign code must be between 0x0X to 0xFX inclusive (X - don't care)
+ * - bits [0:3] of each digit must be equal to 0x3
+ * - bits [4:7] of each digit must be between 0x0 and 0x9
+ *
+ * If ps = 0
+ * Positive sign codes are: 0x0, 0x1, 0x2, 0x3, 0x8, 0x9, 0xA, 0xB
+ * (note 0bX0XX XXXX is positive)
+ *
+ * Negative sign codes are 0x4, 0x5, 0x6, 0x7, 0xC, 0xD, 0xE, 0xF
+ * (note 0bX1XX XXXX is negative)
+ *
+ * If ps = 1, then the sign code must be in the range 0xA to 0xF
+ * Positive sign codes are: 0xA, 0xC, 0xE, 0xF
+ *
+ * Negative sign codes are 0xB, 0xD
+ */
+ Int i, mask_hi, mask_lo;
+ IRExpr *valid_range;
+ IRTemp valid_num[16];
+ IRTemp digit[15];
+
+ /* check the range of the sign value based on the value of ps */
+ valid_range = mkOR1(
+ mkAND1( binop( Iop_CmpEQ64,
+ mkU64( 1 ),
+ mkU64( ps ) ),
+ mkAND1( binop( Iop_CmpLE64U,
+ binop( Iop_And64,
+ mkU64( 0xF0 ),
+ unop( Iop_V128to64,
+ mkexpr( src ) ) ),
+
+ mkU64( 0xF0 ) ),
+ binop( Iop_CmpLE64U,
+ mkU64( 0xA0 ),
+ binop( Iop_And64,
+ mkU64( 0xF0 ),
+ unop( Iop_V128to64,
+ mkexpr( src ) ))))),
+ binop( Iop_CmpEQ64,
+ mkU64( 0 ),
+ mkU64( ps ) ) );
+
+ valid_num[0] = newTemp( Ity_I1 );
+ assign( valid_num[0], mkU1( 1) ); // Assume true to start
+
+ if (ps == 0) {
+ mask_hi = 0x39;
+ mask_lo = 0x30;
+ } else {
+ mask_hi = 0xF9;
+ mask_lo = 0xF0;
+ }
+
+ for(i = 0; i < 15; i++) {
+ valid_num[i+1] = newTemp( Ity_I1 );
+ digit[i] = newTemp( Ity_I64 );
+ assign( digit[i], binop( Iop_And64,
+ unop( Iop_V128to64,
+ binop( Iop_ShrV128,
+ mkexpr( src ),
+ mkU8( (15-i)*8 ) ) ),
+ mkU64( 0xFF ) ) );
+
+ assign( valid_num[i+1],
+ mkAND1( mkexpr( valid_num[i] ),
+ mkAND1( binop( Iop_CmpLE64U,
+ mkexpr( digit[i] ),
+ mkU64( mask_hi ) ),
+ binop( Iop_CmpLE64U,
+ mkU64( mask_lo ),
+ mkexpr( digit[i] ) ) ) ) );
+ }
+
+ return mkAND1( valid_range, mkexpr( valid_num[15] ) );
+}
+
+static IRExpr * CmpGT128U ( IRExpr *src1, IRExpr *src2 )
+{
+ /* Unsigend compare of two 128-bit values */
+ IRExpr *pos_upper_gt, *pos_upper_eq, *pos_lower_gt;
+
+ pos_upper_gt = binop( Iop_CmpLT64U,
+ unop( Iop_V128HIto64, src2 ),
+ unop( Iop_V128HIto64, src1 ) );
+ pos_upper_eq = binop( Iop_CmpEQ64,
+ unop( Iop_V128HIto64, src1 ),
+ unop( Iop_V128HIto64, src2 ) );
+ pos_lower_gt = binop( Iop_CmpLT64U,
+ unop( Iop_V128to64, src2),
+ unop( Iop_V128to64, src1) );
+ return mkOR1( pos_upper_gt,
+ mkAND1( pos_upper_eq,
+ pos_lower_gt ) );
+}
+
+
+static IRExpr * is_BCDstring128 (UInt Signed, IRExpr *src)
+{
+
+ IRTemp valid = newTemp( Ity_I64 );
+
+ /* The src is a 128-bit value containing a MAX_DIGITS BCD digits and
+ * a sign. The upper bytes are BCD values between 0x0 and 0x9. The sign
+ * byte is the least significant byte. This function returns 64-bit 1
+ * value if sign and digits are valid, 0 otherwise.
+ *
+ * This function was originally written using IR code. It has been
+ * replaced with a clean helper due to the large amount of IR code
+ * needed by this function.
+ */
+ assign( valid,
+ mkIRExprCCall( Ity_I64, 0 /*regparms*/,
+ "is_BCDstring128_helper",
+ &is_BCDstring128_helper,
+ mkIRExprVec_3( mkU64( Signed ),
+ unop( Iop_V128HIto64, src ),
+ unop( Iop_V128to64, src ) ) ) );
+ return mkexpr( valid );
+}
+
+static IRExpr * BCDstring_zero (IRExpr *src)
+{
+ /* The src is a 128-bit value containing a BCD string and a sign in the
+ * least significant byte. The function returns a 1 if the BCD string
+ * values are all zero, 0 otherwise.
+ */
+ IRTemp tsrc = newTemp( Ity_V128 );
+ assign( tsrc, src);
+
+ return mkAND1( binop( Iop_CmpEQ64,
+ mkU64( 0 ),
+ unop( Iop_V128HIto64,
+ mkexpr( tsrc ) ) ),
+ binop( Iop_CmpEQ64,
+ mkU64( 0 ),
+ unop( Iop_V128to64,
+ mkexpr( tsrc ) ) ) );
+}
+
+static IRExpr * check_BCD_round (IRExpr *src, IRTemp shift)
+{
+ /* The src is a 128-bit value containing 31 BCD digits with the sign in
+ * the least significant byte. The bytes are BCD values between 0x0 and 0x9.
+ * This routine checks the BCD digit in position shift (counting from
+ * the least significant digit). If the digit is greater then five,
+ * a 1 is returned indicating the string needs to be rounded up,
+ * otherwise, 0 is returned. The value of shift (I64) is the index of
+ * the BCD digit times four bits.
+ */
+ return binop( Iop_CmpLE64U,
+ mkU64( 6 ),
+ binop( Iop_And64,
+ unop( Iop_V128to64,
+ binop( Iop_ShrV128,
+ src,
+ unop( Iop_64to8, mkexpr( shift ) ) ) ),
+ mkU64( 0xF ) ) );
+}
+
+static IRTemp increment_BCDstring (IRExpr *src, IRExpr *carry_in)
+{
+ /* The src is a 128-bit value containing 31 BCD digits with the sign in
+ * the least significant byte. The bytes are BCD values between 0x0 and 0x9.
+ * This function returns the BCD string incremented by 1.
+ *
+ * Call a clean helper to do the computation as it requires a lot of
+ * IR code to do this.
+ *
+ * The helper function takes a 32-bit BCD string, in a 64-bit value, and
+ * increments the string by the 32-bi carry in value.
+ *
+ * The incremented value is returned in the lower 32-bits of the result.
+ * The carry out is returned in bits [35:32] of the result. The
+ * helper function will be called for each of the four 32-bit strings
+ * that make up the src string passing the returned carry out to the
+ * next call.
+ */
+ IRTemp bcd_result = newTemp( Ity_V128 );
+ IRTemp bcd_result0 = newTemp( Ity_I64 );
+ IRTemp bcd_result1 = newTemp( Ity_I64 );
+ IRTemp bcd_result2 = newTemp( Ity_I64 );
+ IRTemp bcd_result3 = newTemp( Ity_I64 );
+ IRExpr *bcd_string0, *bcd_string1, *bcd_string2, *bcd_string3;
+
+ bcd_string0 = binop( Iop_And64,
+ mkU64( 0xFFFFFFFF ), unop( Iop_V128to64, src ) );
+ bcd_string1 = binop( Iop_Shr64, unop( Iop_V128to64, src ), mkU8( 32 ) );
+ bcd_string2 = binop( Iop_And64,
+ mkU64( 0xFFFFFFFF ), unop( Iop_V128HIto64, src ) );
+ bcd_string3 = binop( Iop_Shr64, unop( Iop_V128HIto64, src ), mkU8( 32 ) );
+
+ assign( bcd_result0,
+ mkIRExprCCall( Ity_I64, 0 /*regparms*/,
+ "increment_BCDstring32_helper",
+ &increment_BCDstring32_helper,
+ mkIRExprVec_3( mkU64( True /*Signed*/ ),
+ bcd_string0,
+ binop( Iop_32HLto64, mkU32( 0 ),
+ carry_in ) ) ) );
+
+ assign( bcd_result1,
+ mkIRExprCCall( Ity_I64, 0 /*regparms*/,
+ "increment_BCDstring32_helper",
+ &increment_BCDstring32_helper,
+ mkIRExprVec_3( mkU64( False /*Unsigned*/ ),
+ bcd_string1,
+ binop( Iop_Shr64,
+ mkexpr( bcd_result0 ),
+ mkU8( 32 ) ) ) ) );
+ assign( bcd_result2,
+ mkIRExprCCall( Ity_I64, 0 /*regparms*/,
+ "increment_BCDstring32_helper",
+ &increment_BCDstring32_helper,
+ mkIRExprVec_3( mkU64( False /*Unsigned*/ ),
+ bcd_string2,
+ binop( Iop_Shr64,
+ mkexpr( bcd_result1 ),
+ mkU8( 32 ) ) ) ) );
+ assign( bcd_result3,
+ mkIRExprCCall( Ity_I64, 0 /*regparms*/,
+ "increment_BCDstring32_helper",
+ &increment_BCDstring32_helper,
+ mkIRExprVec_3( mkU64( False /*Unsigned*/ ),
+ bcd_string3,
+ binop( Iop_Shr64,
+ mkexpr( bcd_result2 ),
+ mkU8( 32 ) ) ) ) );
+
+ /* Put the 128-bit result together from the intermediate results. Remember
+ * to mask out the carry out from the upper 32 bits of the results.
+ */
+ assign( bcd_result,
+ binop( Iop_64HLtoV128,
+ binop( Iop_Or64,
+ binop( Iop_And64,
+ mkU64( 0xFFFFFFFF ), mkexpr (bcd_result2 ) ),
+ binop( Iop_Shl64,
+ mkexpr (bcd_result3 ), mkU8( 32 ) ) ),
+ binop( Iop_Or64,
+ binop( Iop_And64,
+ mkU64( 0xFFFFFFFF ), mkexpr (bcd_result0 ) ),
+ binop( Iop_Shl64,
+ mkexpr (bcd_result1 ), mkU8( 32 ) ) ) ) );
+ return bcd_result;
+}
+
+static IRExpr * convert_to_zoned ( IRExpr *src, IRExpr *upper_byte )
+{
+ /* The function takes a V128 packed decimal value and returns
+ * the value in zoned format. Note, the sign of the value is ignored.
+ */
+ IRTemp result_low = newTemp( Ity_I64 );
+ IRTemp result_hi = newTemp( Ity_I64 );
+ IRTemp result = newTemp( Ity_V128 );
+
+ /* Since we can only return 64-bits from a clean helper, we will
+ * have to get the lower and upper 64-bits separately.
+ */
+
+ assign( result_low,
+ mkIRExprCCall( Ity_I64, 0 /*regparms*/,
+ "convert_to_zoned_helper",
+ &convert_to_zoned_helper,
+ mkIRExprVec_4( unop( Iop_V128HIto64, src ),
+ unop( Iop_V128to64, src ),
+ upper_byte,
+ mkU64( 0 ) ) ) );
+
+ assign( result_hi,
+ mkIRExprCCall( Ity_I64, 0 /*regparms*/,
+ "convert_to_zoned_helper",
+ &convert_to_zoned_helper,
+ mkIRExprVec_4( unop( Iop_V128HIto64, src ),
+ unop( Iop_V128to64, src ),
+ upper_byte,
+ mkU64( 1 ) ) ) );
+
+
+ assign( result,
+ binop( Iop_64HLtoV128, mkexpr( result_hi ), mkexpr( result_low ) ) );
+
+ return mkexpr( result );
+}
+
+static IRExpr * convert_to_national ( IRExpr *src ) {
+ /* The function takes 128-bit value which has a 64-bit packed decimal
+ * value in the lower 64-bits of the source. The packed decimal is
+ * converted to the national format via a clean helper. The clean
+ * helper is used to to the large amount of IR code needed to do the
+ * conversion. The helper returns the upper 64-bits of the 128-bit
+ * result if return_upper != 0. Otherwise, the lower 64-bits of the
+ * result is returned.
+ */
+ IRTemp result_low = newTemp( Ity_I64 );
+ IRTemp result_hi = newTemp( Ity_I64 );
+ IRTemp result = newTemp( Ity_V128 );
+
+ /* Since we can only return 64-bits from a clean helper, we will
+ * have to get the lower and upper 64-bits separately.
+ */
+
+ assign( result_low,
+ mkIRExprCCall( Ity_I64, 0 /*regparms*/,
+ "convert_to_national_helper",
+ &convert_to_national_helper,
+ mkIRExprVec_2( unop( Iop_V128to64, src ),
+ mkU64( 0 ) ) ) );
+
+ assign( result_hi,
+ mkIRExprCCall( Ity_I64, 0 /*regparms*/,
+ "convert_to_national_helper",
+ &convert_to_national_helper,
+ mkIRExprVec_2( unop( Iop_V128to64, src ),
+ mkU64( 1 ) ) ) );
+
+ assign( result,
+ binop( Iop_64HLtoV128, mkexpr( result_hi ), mkexpr( result_low ) ) );
+
+ return mkexpr( result );
+}
+
+static IRExpr * convert_from_zoned ( IRExpr *src ) {
+ /* The function takes 128-bit zoned value and returns a signless 64-bit
+ * packed decimal value in the lower 64-bits of the 128-bit result.
+ */
+ IRTemp result = newTemp( Ity_V128 );
+
+ assign( result,
+ binop( Iop_ShlV128,
+ binop( Iop_64HLtoV128,
+ mkU64( 0 ),
+ mkIRExprCCall( Ity_I64, 0 /*regparms*/,
+ "convert_from_zoned_helper",
+ &convert_from_zoned_helper,
+ mkIRExprVec_2( unop( Iop_V128HIto64,
+ src ),
+ unop( Iop_V128to64,
+ src ) ) ) ),
+ mkU8( 4 ) ) );
+
+ return mkexpr( result );
+}
+
+static IRExpr * convert_from_national ( IRExpr *src ) {
+ /* The function takes 128-bit national value and returns a 64-bit
+ * packed decimal value.
+ */
+ IRTemp result = newTemp( Ity_I64);
+
+ assign( result,
+ mkIRExprCCall( Ity_I64, 0 /*regparms*/,
+ "convert_from_national_helper",
+ &convert_from_national_helper,
+ mkIRExprVec_2( unop( Iop_V128HIto64,
+ src ),
+ unop( Iop_V128to64,
+ src ) ) ) );
+
+ return mkexpr( result );
+}
+
/*------------------------------------------------------------*/
/* Transactional memory helpers
*
@@ -4926,7 +5405,7 @@
break;
default:
- vex_printf("dis_int_cmp(ppc)(opc1)\n");
+ vex_printf("dis_modulo_int(ppc)(opc1)\n");
return False;
}
@@ -4937,6 +5416,164 @@
/*
+ Byte Compare Instructions
+*/
+static Bool dis_byte_cmp ( UInt theInstr )
+{
+ /* X-Form */
+ UChar opc1 = ifieldOPC(theInstr);
+ UInt opc2 = ifieldOPClo10(theInstr);
+ UChar rA_addr = ifieldRegA(theInstr);
+ UChar rB_addr = ifieldRegB(theInstr);
+ IRTemp rA = newTemp(Ity_I64);
+ IRTemp rB = newTemp(Ity_I64);
+ UChar L = toUChar( IFIELD( theInstr, 21, 1 ) );
+ UChar BF = toUChar( IFIELD( theInstr, 23, 3 ) );
+
+ assign( rA, getIReg(rA_addr) );
+ assign( rB, getIReg(rB_addr) );
+
+ if (opc1 != 0x1F) {
+ vex_printf("dis_byte_cmp(ppc)(opc1)\n");
+ return False;
+ }
+
+ switch (opc2) {
+ case 0xc0: // cmprb (Compare Ranged Byte)
+ {
+ IRExpr *value;
+ IRExpr *hi_1, *lo_1, *hi_2, *lo_2;
+ IRExpr *inrange_1, *inrange_2;
+
+ DIP("cmprb %u,%u,r%u,r%u\n", BF, L, rA_addr, rB_addr);
+
+ hi_1 = binop( Iop_Shr64,
+ binop( Iop_And64,
+ mkexpr( rB ),
+ mkU64( 0xFF000000 ) ),
+ mkU8( 24 ) );
+ lo_1 = binop( Iop_Shr64,
+ binop( Iop_And64,
+ mkexpr( rB ),
+ mkU64( 0xFF0000 ) ) ,
+ mkU8( 16 ) );
+ hi_2 = binop( Iop_Shr64,
+ binop( Iop_And64,
+ mkexpr( rB ),
+ mkU64( 0xFF00 ) ),
+ mkU8( 8 ) );
+ lo_2 = binop( Iop_And64,
+ mkexpr( rB ),
+ mkU64( 0xFF ) );
+ value = binop( Iop_And64,
+ mkexpr( rA ),
+ mkU64( 0xFF ) );
+
+ inrange_1 = mkAND1( binop( Iop_CmpLE64U, value, hi_1 ),
+ mkNOT1( binop( Iop_CmpLT64U, value, lo_1 ) ) );
+ inrange_2 = mkAND1( binop( Iop_CmpLE64U, value, hi_2 ),
+ mkNOT1( binop( Iop_CmpLT64U, value, lo_2 ) ) );
+
+ putGST_field( PPC_GST_CR,
+ binop( Iop_Shl32,
+ binop( Iop_Or32,
+ unop( Iop_1Uto32, inrange_2 ),
+ binop( Iop_And32,
+ mkU32 ( L ),
+ unop( Iop_1Uto32, inrange_1 ) ) ),
+ mkU8( 2 ) ),
+ BF );
+ }
+ break;
+
+ case 0xE0: // cmpeqb (Compare Equal Byte)
+ {
+ Int i;
+ IRTemp tmp[9];
+ IRExpr *value;
+
+ DIP("cmpeqb %u,r%u,r%u\n", BF, rA_addr, rB_addr);
+
+ value = binop( Iop_And64,
+ mkexpr( rA ),
+ mkU64( 0xFF ) );
+
+ tmp[0] = newTemp(Ity_I32);
+ assign( tmp[0], mkU32( 0 ) );
+
+ for(i = 0; i < 8; i++) {
+ tmp[i+1] = newTemp(Ity_I32);
+ assign( tmp[i+1], binop( Iop_Or32,
+ unop( Iop_1Uto32,
+ binop( Iop_CmpEQ64,
+ value,
+ binop( Iop_And64,
+ binop( Iop_Shr64,
+ mkexpr( rB ),
+ mkU8( i*8 ) ),
+ mkU64( 0xFF ) ) ) ),
+ mkexpr( tmp[i] ) ) );
+ }
+
+ putGST_field( PPC_GST_CR,
+ binop( Iop_Shl32,
+ unop( Iop_1Uto32,
+ mkNOT1( binop( Iop_CmpEQ32,
+ mkexpr( tmp[8] ),
+ mkU32( 0 ) ) ) ),
+ mkU8( 2 ) ),
+ BF );
+ }
+ break;
+
+ default:
+ vex_printf("dis_byte_cmp(ppc)(opc2)\n");
+ return False;
+ }
+ return True;
+}
+
+/*
+ * Integer Miscellaneous instructions
+ */
+static Bool dis_int_misc ( UInt theInstr )
+{
+ Int wc = IFIELD(theInstr, 21, 2);
+ UChar opc1 = ifieldOPC(theInstr);
+ UInt opc2 = ifieldOPClo10(theInstr);
+
+ if ( opc1 != 0x1F ) {
+ vex_printf("dis_modulo_int(ppc)(opc1)\n");
+ return False;
+ }
+
+ switch (opc2) {
+ case 0x01E: // wait, (X-from)
+ DIP("wait %u\n", wc);
+
+ /* The wait instruction causes instruction fetching and execution
+ * to be suspended. Instruction fetching and execution are resumed
+ * when the events specified by the WC field occur.
+ *
+ * 0b00 Resume instruction fetching and execution when an
+ * exception or an event-based branch exception occurs,
+ * or a resume signal from the platform is recieved.
+ *
+ * 0b01 Reserved.
+ *
+ * For our purposes, we will just assume the contition is always
+ * immediately satisfied.
+ */
+ break;
+ default:
+ vex_printf("dis_int_misc(ppc)(opc2)\n");
+ return False;
+}
+
+ return True;
+}
+
+/*
Integer Compare Instructions
*/
static Bool dis_int_cmp ( UInt theInstr )
@@ -4961,7 +5598,7 @@
return False;
}
- if (b22 != 0) {
+ if (( b22 != 0 ) && ( opc2 != 0x080 ) ) { // setb case exception
vex_printf("dis_int_cmp(ppc)(b22)\n");
return False;
}
@@ -5041,6 +5678,50 @@
putCR0( crfD, getXER_SO() );
break;
+ case 0x080: // setb (Set Boolean)
+ {
+ UChar rT_addr = ifieldRegDS(theInstr);
+ Int bfa = IFIELD(theInstr, 18, 3);
+ IRTemp cr = newTemp(Ity_I32);
+ IRTemp cr0 = newTemp(Ity_I32);
+ IRTemp cr1 = newTemp(Ity_I32);
+ IRTemp result = newTemp(Ity_I64);
+
+ DIP("setb r%u,%d\n", rT_addr, bfa);
+
+ /* Fetch the entire condition code value */
+ assign( cr, getGST( PPC_GST_CR ) );
+
+ /* Get bit zero (IBM numbering) of the CR field specified
+ * by bfa.
+ */
+ assign( cr0, binop( Iop_And32,
+ binop( Iop_Shr32,
+ mkexpr( cr ),
+ mkU8( (7-bfa)*4 ) ),
+ mkU32( 0x8 ) ) );
+ assign( cr1, binop( Iop_And32,
+ binop( Iop_Shr32,
+ mkexpr( cr ),
+ mkU8( (7-bfa)*4 ) ),
+ mkU32( 0x4 ) ) );
+ assign( result, binop( Iop_Or64,
+ unop( Iop_1Sto64,
+ binop( Iop_CmpEQ32,
+ mkexpr( cr0 ),
+ mkU32( 0x8 ) ) ),
+ binop( Iop_32HLto64,
+ mkU32( 0 ),
+ unop( Iop_1Uto32,
+ binop( Iop_CmpEQ32,
+ mkexpr( cr1 ),
+ mkU32( 0x4 ) ) ) ) ) );
+ if ( ty == Ity_I64 )
+ putIReg( rT_addr, mkexpr( result ) );
+ else
+ putIReg( rT_addr, unop( Iop_64to32, mkexpr(result ) ) );
+ }
+ break;
default:
vex_printf("dis_int_cmp(ppc)(opc2)\n");
return False;
@@ -6888,11 +7569,62 @@
return True;
}
+/*
+ * PC relative instruction
+ */
+static Bool dis_pc_relative ( UInt theInstr )
+{
+ /* DX-Form */
+ UChar opc1 = ifieldOPC(theInstr);
+ unsigned long long D;
+ UInt d0 = IFIELD(theInstr, 6, 10);
+ UInt d1 = IFIELD(theInstr, 16, 5);
+ UInt d2 = IFIELD(theInstr, 0, 1);
+ UChar rT_addr = ifieldRegDS(theInstr);
+ UInt opc2 = ifieldOPClo5(theInstr);
+ IRType ty = mode64 ? Ity_I64 : Ity_I32;
+
+ if ( opc1 != 0x13) {
+ vex_printf("dis_pc_relative(ppc)(opc1)\n");
+ return False;
+ }
+
+ switch (opc2) {
+ case 0x002: // addpcis (Add PC immediate Shifted DX-form)
+ {
+ IRExpr* nia = mkSzImm(ty, nextInsnAddr());
+ IRExpr* result;
+
+ D = (d0 << 6) | (d1 << 1) | d2;
+ DIP("addpcis %u,%llu\n", rT_addr, D);
+
+ if ( (D & 0x8000) == 0x8000 )
+ D = 0xFFFFFFFFFFFF0000UL | D; // sign extend
+
+ if ( ty == Ity_I32 ) {
+ result = binop( Iop_Add32, nia, mkU32( D << 16 ) );
+
+ } else if ( ty == Ity_I64 ) {
+ result = binop( Iop_Add64, nia, mkU64( D << 16 ) );
+
+ } else {
+ vex_printf("dis_pc_relative(unsupported type)\n");
+ }
+ putIReg( rT_addr, result);
+ }
+ break;
+
+ default:
+ vex_printf("dis_pc_relative(ppc)(opc2)\n");
+ return False;
+ }
+ return True;
+}
/*
Condition Register Logical Instructions
-*/
+ */
static Bool dis_cond_logic ( UInt theInstr )
{
/* XL-Form */
@@ -10555,9 +11287,13 @@
IRExpr* fpscr_lower
= binop( Iop_Or32,
getGST_masked( PPC_GST_FPSCR, MASK_FPSCR_RN),
- binop( Iop_Shl32,
- getFPCC(),
- mkU8( 63-51 ) ) );
+ binop( Iop_Or32,
+ binop( Iop_Shl32,
+ getC(),
+ mkU8(63-47) ) ,
+ binop( Iop_Shl32,
+ getFPCC(),
+ mkU8(63-51) ) ) );
IRExpr* fpscr_upper = getGST_masked_upper( PPC_GST_FPSCR,
MASK_FPSCR_DRN );
@@ -10622,6 +11358,12 @@
else
mask |= BFP_MASK_SEED >> ( 4 * ( i + 8 * ( 1 - Wbit ) ) );
}
+ if ((FM & (1<<(7-i))) == 0x2) { //set the FPCC bits
+ mask |= 0xF000;
+ }
+ if ((FM & (1<<(7-i))) == 0x4) { //set the Floating-Point Class Descriptor (C) bit
+ mask |= 0x10000;
+ }
}
}
assign( frB, getFReg(frB_addr));
@@ -11200,7 +11942,7 @@
IRTemp low_u_flag = newTemp( Ity_I8 );
IRTemp low_l_flag = newTemp( Ity_I8 );
- /* Check the LMD, digit 16, to see if it is zero. */
+ /* Check the LMD, digit 34, to see if it is zero. */
assign( num_lmd, unop( Iop_1Uto8, binop( Iop_CmpEQ32, lmd, mkU32( 0 ) ) ) );
assign( lmd_flag, unop( Iop_Not8, mkexpr( num_lmd ) ) );
@@ -11212,7 +11954,7 @@
&top_flag,
top_12_l );
- Count_zeros( 1,
+ Count_zeros( 2,
mkexpr( num_top ),
mkexpr( top_flag ),
&num_mid_u,
@@ -11221,14 +11963,14 @@
binop( Iop_Shl32, mid_60_u, mkU8( 2 ) ),
binop( Iop_Shr32, mid_60_l, mkU8( 30 ) ) ) );
- Count_zeros( 2,
+ Count_zeros( 1,
mkexpr( num_mid_u ),
mkexpr( mid_u_flag ),
&num_mid_l,
&mid_l_flag,
mid_60_l );
- Count_zeros( 1,
+ Count_zeros( 2,
mkexpr( num_mid_l ),
mkexpr( mid_l_flag ),
&num_low_u,
@@ -11237,7 +11979,7 @@
binop( Iop_Shl32, low_60_u, mkU8( 2 ) ),
binop( Iop_Shr32, low_60_l, mkU8( 30 ) ) ) );
- Count_zeros( 2,
+ Count_zeros( 1,
mkexpr( num_low_u ),
mkexpr( low_u_flag ),
&num_low_l,
@@ -11263,10 +12005,10 @@
binop( Iop_CmpEQ32,
mkexpr( gfield0to5 ),
mkU32( 0x1E ) ) ),
- unop( Iop_1Sto32, /* SNaN check */
- binop( Iop_CmpEQ32,
- mkexpr( gfield0to5 ),
- mkU32( 0x1F ) ) ) );
+ unop( Iop_1Sto32, /* SNaN check */
+ binop( Iop_CmpEQ32,
+ mkexpr( gfield0to5 ),
+ mkU32( 0x1F ) ) ) );
}
#undef AND
@@ -13359,10 +14101,11 @@
static Bool dis_dfp_significant_digits( UInt theInstr )
{
+ UInt opc1 = ifieldOPC( theInstr );
+ UInt opc2 = ifieldOPClo10(theInstr);
UChar frA_addr = ifieldRegA( theInstr );
UChar frB_addr = ifieldRegB( theInstr );
IRTemp frA = newTemp( Ity_D64 );
- UInt opc1 = ifieldOPC( theInstr );
IRTemp B_sig = newTemp( Ity_I8 );
IRTemp K = newTemp( Ity_I8 );
IRTemp lmd_B = newTemp( Ity_I32 );
@@ -13375,22 +14118,37 @@
IRTemp KisZero_true_mask = newTemp( Ity_I32 );
IRTemp KisZero_false_mask = newTemp( Ity_I32 );
IRTemp cc = newTemp( Ity_I32 );
+ UChar UIM = toUChar( IFIELD( theInstr, 16, 6 ) );
+ IRTemp BCD_valid = newTemp( Ity_I32 );
- /* Get the reference singificance stored in frA */
- assign( frA, getDReg( frA_addr ) );
+ if (opc2 == 0x2A2) { // dtstsf DFP Test Significance
+ // dtstsfq DFP Test Significance Quad
+ /* Get the reference singificance stored in frA */
+ assign( frA, getDReg( frA_addr ) );
- /* Convert from 64 bit to 8 bits in two steps. The Iop_64to8 is not
- * supported in 32-bit mode.
- */
- assign( K, unop( Iop_32to8,
- binop( Iop_And32,
- unop( Iop_64to32,
- unop( Iop_ReinterpD64asI64,
- mkexpr( frA ) ) ),
- mkU32( 0x3F ) ) ) );
+ /* Convert from 64 bit to 8 bits in two steps. The Iop_64to8 is not
+ * supported in 32-bit mode.
+ */
+ assign( K, unop( Iop_32to8,
+ binop( Iop_And32,
+ unop( Iop_64to32,
+ unop( Iop_ReinterpD64asI64,
+ mkexpr( frA ) ) ),
+ mkU32( 0x3F ) ) ) );
+
+ } else if (opc2 == 0x2A3) { // dtstsfi DFP Test Significance Immediate
+ // dtstsfiq DFP Test Significance Quad Immediate
+ /* get the significane from the immediate field */
+ assign( K, mkU8( UIM) );
+
+ } else {
+ vex_printf("dis_dfp_significant_digits(ppc)(opc2) wrong\n");
+ return False;
+ }
switch ( opc1 ) {
case 0x3b: // dtstsf DFP Test Significance
+ // dtstsfi DFP Test Significance Immediate
{
IRTemp frB = newTemp( Ity_D64 );
IRTemp frBI64 = newTemp( Ity_I64 );
@@ -13398,7 +14156,11 @@
IRTemp B_bcd_l = newTemp( Ity_I32 );
IRTemp tmp64 = newTemp( Ity_I64 );
- DIP( "dtstsf %u,r%u,r%u\n", crfD, frA_addr, frB_addr );
+ if (opc2 == 0x2A2) {
+ DIP( "dtstsf %u,r%u,r%u\n", crfD, frA_addr, frB_addr );
+ } else {
+ DIP( "dtstsfi %u,%u,r%u\n", crfD, UIM, frB_addr );
+ }
assign( frB, getDReg( frB_addr ) );
assign( frBI64, unop( Iop_ReinterpD64asI64, mkexpr( frB ) ) );
@@ -13423,10 +14185,23 @@
Count_leading_zeros_60( mkexpr( lmd_B ),
mkexpr( B_bcd_u ),
mkexpr( B_bcd_l ) ) ) );
- assign( Unordered_true, Check_unordered( mkexpr( frBI64 ) ) );
+
+ assign( BCD_valid,
+ binop( Iop_Or32,
+ bcd_digit_inval( mkexpr( B_bcd_u), mkexpr( B_bcd_l) ),
+ bcd_digit_inval( mkexpr( lmd_B), mkU32( 0 ) ) ) );
+
+ /* Set unordered to True if the number is NaN, Inf or an invalid
+ * digit.
+ */
+ assign( Unordered_true,
+ binop( Iop_Or32,
+ Check_unordered( mkexpr( frBI64 ) ),
+ mkexpr( BCD_valid) ) );
}
break;
case 0x3F: // dtstsfq DFP Test Significance
+ // dtstsfqi DFP Test Significance Immediate
{
IRTemp frB_hi = newTemp( Ity_D64 );
IRTemp frB_lo = newTemp( Ity_D64 );
@@ -13438,7 +14213,11 @@
IRTemp B_mid_60_l = newTemp( Ity_I32 );
IRTemp B_top_12_l = newTemp( Ity_I32 );
- DIP( "dtstsfq %u,r%u,r%u\n", crfD, frA_addr, frB_addr );
+ if (opc2 == 0x2A2) {
+ DIP( "dtstsfq %u,r%u,r%u\n", crfD, frA_addr, frB_addr );
+ } else {
+ DIP( "dtstsfiq %u,%u,r%u\n", crfD, UIM, frB_addr );
+ }
assign( frB_hi, getDReg( frB_addr ) );
assign( frB_lo, getDReg( frB_addr + 1 ) );
@@ -13464,6 +14243,16 @@
&B_low_60_u,
&B_low_60_l );
+ assign( BCD_valid,
+ binop( Iop_Or32,
+ binop( Iop_Or32,
+ bcd_digit_inval( mkexpr( lmd_B ),
+ mkexpr( B_top_12_l ) ),
+ bcd_digit_inval( mkexpr( B_mid_60_u ),
+ mkexpr( B_mid_60_l ) ) ),
+ bcd_digit_inval( mkexpr( B_low_60_u ),
+ mkexpr( B_low_60_l ) ) ) );
+
assign( B_sig,
binop( Iop_Sub8,
mkU8( DFP_EXTND_MAX_SIG_DIGITS ),
@@ -13474,7 +14263,13 @@
mkexpr( B_low_60_u ),
mkexpr( B_low_60_l ) ) ) );
- assign( Unordered_true, Check_unordered( mkexpr( frBI64_hi ) ) );
+ /* Set unordered to True if the number is NaN, Inf or an invalid
+ * digit.
+ */
+ assign( Unordered_true,
+ binop( Iop_Or32,
+ Check_unordered( mkexpr( frBI64_hi ) ),
+ mkexpr( BCD_valid) ) );
}
break;
}
@@ -13549,7 +14344,6 @@
return True;
}
-
/*------------------------------------------------------------*/
/*--- AltiVec Instruction Translation ---*/
/*------------------------------------------------------------*/
@@ -18334,8 +19128,8 @@
assign( ld_result, binop( Iop_ShrV128,
binop( Iop_ShlV128,
binop( Iop_64HLtoV128,
- mkexpr( tmp_hi[8] ),
- mkexpr( tmp_low[8] ) ),
+ mkexpr( tmp_low[8] ),
+ mkexpr( tmp_hi[8] ) ),
mkexpr( shift ) ),
mkexpr( shift ) ) );
@@ -18350,11 +19144,112 @@
break;
}
- case 0x16C: // lxvwsx
+ case 0x12D: // lxvll (Load VSX Vector Left-Justified with Length XX1 form)
{
- IRTemp data = newTemp( Ity_I64 );
-
- DIP("lxvwsx %d,r%u,r%u\n", (UInt)XT, rA_addr, rB_addr);
+ IRTemp byte[16];
+ IRTemp tmp_low[9];
+ IRTemp tmp_hi[9];
+ IRTemp mask = newTemp(Ity_V128);
+ IRTemp rB = newTemp( Ity_I64 );
+ IRTemp nb = newTemp( Ity_I64 );
+ IRTemp nb_zero = newTemp(Ity_V128);
+ IRTemp mask_shift = newTemp(Ity_I64);
+ Int i;
+ UInt ea_off = 0;
+ IRExpr* irx_addr;
+ IRTemp base_addr = newTemp( ty );
+ IRTemp nb_compare_zero = newTemp( Ity_I64 );
+
+ DIP("lxvll %d,r%u,r%u\n", (UInt)XT, rA_addr, rB_addr);
+
+ tmp_low[0] = newTemp(Ity_I64);
+ tmp_hi[0] = newTemp(Ity_I64);
+
+ assign( rB, getIReg(rB_addr));
+ assign( base_addr, ea_rAor0( rA_addr ) );
+ assign( tmp_low[0], mkU64( 0 ) );
+ assign( tmp_hi[0], mkU64( 0 ) );
+
+ /* mask_shift is number of 16 bytes minus (nb times 8-bits per byte) */
+ assign( nb, binop( Iop_Shr64, mkexpr( rB ), mkU8( 56 ) ) );
+
+ assign( nb_compare_zero, unop( Iop_1Sto64,
+ binop( Iop_CmpEQ64,
+ mkexpr( nb ),
+ mkU64( 0 ) ) ) );
+
+ /* nb_zero is 0xFF..FF if the nb_field = 0 */
+ assign( nb_zero, binop( Iop_64HLtoV128,
+ mkexpr( nb_compare_zero ),
+ mkexpr( nb_compare_zero ) ) );
+
+ assign( mask_shift, binop( Iop_Sub64,
+ mkU64( 16*8 ),
+ binop( Iop_Mul64,
+ mkexpr( nb ),
+ mkU64( 8 ) ) ) );
+
+ /* fetch all 16 bytes, we will remove what we don't want later */
+ for (i = 0; i < 8; i++) {
+ byte[i] = newTemp(Ity_I64);
+ tmp_hi[i+1] = newTemp(Ity_I64);
+
+ irx_addr = binop( mkSzOp( ty, Iop_Add8 ), mkexpr( base_addr ),
+ ty == Ity_I64 ? mkU64( ea_off ) : mkU32( ea_off ) );
+ ea_off += 1;
+
+ /* Instruction always loads in Big Endian format */
+ assign( byte[i], binop( Iop_Shl64,
+ unop( Iop_8Uto64,
+ load( Ity_I8, irx_addr ) ),
+ mkU8( 8 * (7 - i) ) ) );
+ assign( tmp_hi[i+1],
+ binop( Iop_Or64,
+ mkexpr( byte[i] ), mkexpr( tmp_hi[i] ) ) );
+ }
+
+ for (i = 0; i < 8; i++) {
+ byte[i + 8] = newTemp(Ity_I64);
+ tmp_low[i+1] = newTemp(Ity_I64);
+
+ irx_addr = binop( mkSzOp( ty, Iop_Add8 ), mkexpr( base_addr ),
+ ty == Ity_I64 ? mkU64( ea_off ) : mkU32( ea_off ) );
+ ea_off += 1;
+
+ /* Instruction always loads in Big Endian format */
+ assign( byte[i+8], binop( Iop_Shl64,
+ unop( Iop_8Uto64,
+ load( Ity_I8, irx_addr ) ),
+ mkU8( 8 * (7 - i) ) ) );
+ assign( tmp_low[i+1], binop( Iop_Or64,
+ mkexpr( byte[i+8] ),
+ mkexpr( tmp_low[i] ) ) );
+ }
+
+ /* Create mask to clear the right most 16 - nb bytes, set to zero
+ * if nb= 0.
+ */
+ assign( mask, binop( Iop_AndV128,
+ binop( Iop_ShlV128,
+ binop( Iop_ShrV128,
+ mkV128( 0xFFFF ),
+ unop( Iop_64to8, mkexpr( mask_shift ) ) ),
+ unop( Iop_64to8, mkexpr( mask_shift ) ) ),
+ unop( Iop_NotV128, mkexpr( nb_zero ) ) ) );
+
+ putVSReg( XT, binop( Iop_AndV128,
+ mkexpr( mask ),
+ binop( Iop_64HLtoV128,
+ mkexpr( tmp_hi[8] ),
+ mkexpr( tmp_low[8] ) ) ) );
+ break;
+ }
+
+ case 0x16C: // lxvwsx
+ {
+ IRTemp data = newTemp( Ity_I64 );
+
+ DIP("lxvwsx %d,r%u,r%u\n", (UInt)XT, rA_addr, rB_addr);
/* The load is a 64-bit fetch that is Endian aware, just want
* the lower 32 bits. */
@@ -18886,9 +19781,8 @@
unop( Iop_NotV128, mkexpr( nb_zero ) ) ),
binop( Iop_AndV128,
mkexpr( nb_zero ),
- binop( Iop_64HLtoV128,
- mkU64( 0x0 ),
- mkU64( 0x0 ) ) ) ) );
+ mkV128( 0 ) ) ) );
+
assign( store_val,
binop( Iop_OrV128,
binop( Iop_AndV128,
@@ -18912,9 +19806,7 @@
unop( Iop_NotV128, mkexpr( nb_zero ) ) ),
binop( Iop_AndV128,
mkexpr( nb_zero ),
- binop( Iop_64HLtoV128,
- mkU64( 0x0 ),
- mkU64( 0x0 ) ) ) ) );
+ mkV128( 0 ) ) ) );
assign( store_val,
binop( Iop_OrV128,
@@ -18964,6 +19856,7 @@
ty == Ity_I64 ? mkU64( ea_off ) : mkU32( ea_off ) );
store( irx_addr, unop( Iop_64to32, mkexpr( word1 ) ) );
+
ea_off += 4;
irx_addr = binop( mkSzOp( ty, Iop_Add8 ), mkexpr( base_addr ),
ty == Ity_I64 ? mkU64( ea_off ) : mkU32( ea_off ) );
@@ -18972,11 +19865,274 @@
break;
}
+ case 0x1AD: // stxvll (Store VSX Vector Left-justified with length XX1-form)
+ {
+ UInt ea_off = 0;
+ IRExpr* irx_addr;
+ IRTemp word0[5];
+ IRTemp word1[5];
+ IRTemp word2[5];
+ IRTemp word3[5];
+ IRTemp shift = newTemp(Ity_I8);
+ IRTemp nb_gt16 = newTemp(Ity_I8);
+ IRTemp nb_zero = newTemp(Ity_V128);
+ IRTemp nb = newTemp(Ity_I8);
+ IRTemp nb_field = newTemp(Ity_I64);
+ IRTemp n_bytes = newTemp(Ity_I8);
+ IRTemp base_addr = newTemp( ty );
+ IRTemp current_mem = newTemp(Ity_V128);
+ IRTemp store_val = newTemp(Ity_V128);
+ IRTemp nb_mask = newTemp(Ity_V128);
+ IRTemp mask = newTemp( Ity_I64 );
+ IRTemp byte[16];
+ IRTemp tmp_low[9];
+ IRTemp tmp_hi[9];
+ IRTemp nb_field_compare_zero = newTemp( Ity_I64 );
+ Int i;
+
+ DIP("stxvll %d,r%u,r%u\n", (UInt)XS, rA_addr, rB_addr);
+
+ assign( nb_field, binop( Iop_Shr64,
+ getIReg(rB_addr),
+ mkU8( 56 ) ) );
+ assign( nb, unop( Iop_64to8, mkexpr( nb_field ) ) );
+ assign( mask, mkU64( 0xFFFFFFFFFFFFFFFFULL ) );
+
+ /* nb_gt16 will be all zeros if nb > 16 */
+ assign( nb_gt16, unop( Iop_1Sto8,
+ binop( Iop_CmpLT64U,
+ binop( Iop_Shr64,
+ mkexpr( nb_field ),
+ mkU8( 4 ) ),
+ mkU64( 1 ) ) ) );
+
+ assign( nb_field_compare_zero, unop( Iop_1Sto64,
+ binop( Iop_CmpEQ64,
+ mkexpr( nb_field ),
+ mkU64( 0 ) ) ) );
+
+ /* nb_zero is 0xFF..FF if the nb_field = 0 */
+ assign( nb_zero, binop( Iop_64HLtoV128,
+ mkexpr( nb_field_compare_zero ),
+ mkexpr( nb_field_compare_zero ) ) );...
[truncated message content] |
|
From: Tom H. <to...@co...> - 2016-06-29 13:09:50
|
On 29/06/16 13:00, 黄雄 wrote: > But these status of bugs are still UNCONFIRMED for a long time. > Using these patches can make valgrind test apk codes in > android 5.0,I think it's useful for valgrind . > So I hope someone can confirm these patches and give me a > response.Thank you ! Those all look to be fairly recent - one of the bugs is older but the patches are all from the last couple of months. It's likely that they will be reviewed when we are next preparing a release so I wouldn't worry that nothing has happened just yet. Tom -- Tom Hughes (to...@co...) http://compton.nu/ |
|
From: 黄雄 <win...@16...> - 2016-06-29 12:00:38
|
hello:
I‘m Xiong Huang. I submit some patches of bugs in bugs.kde.org of valgrind.
But these status of bugs are still UNCONFIRMED for a long time.
Using these patches can make valgrind test apk codes in android 5.0,I think it's useful for valgrind .
So I hope someone can confirm these patches and give me a response.Thank you !
This is bug and patch list:
|
Bug ID
|
Patch ID
|
|
344802
|
98894
|
|
362892
|
98896
|
|
362939
|
98913
|
|
356675
|
98947
|
Thank you very much!
Best, Xiong Huang |