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
|
2
(27) |
3
|
4
|
|
5
|
6
(2) |
7
|
8
|
9
(2) |
10
|
11
|
|
12
|
13
|
14
(12) |
15
(4) |
16
(3) |
17
(2) |
18
(3) |
|
19
(2) |
20
|
21
|
22
(9) |
23
(3) |
24
(2) |
25
(5) |
|
26
(1) |
27
(1) |
28
(6) |
29
(3) |
30
|
31
|
|
|
From: Petar J. <pe...@so...> - 2020-01-14 12:14:32
|
https://sourceware.org/git/gitweb.cgi?p=valgrind.git;h=8b7a3a2107c4e4465b256c61ae69bcf0421816bd commit 8b7a3a2107c4e4465b256c61ae69bcf0421816bd Author: Aleksandar Rikalo <ale...@rt...> Date: Tue Jan 14 12:09:18 2020 +0000 mips: Fix UASWM and UALWM instructions for nanoMIPS UASWM and UALWM have not been implemented correctly. Code used to implement SWM and LWM has been reused without making all of the required adjustments. This fixes memcpy() and memset() libc functions. Diff: --- VEX/priv/guest_nanomips_toIR.c | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/VEX/priv/guest_nanomips_toIR.c b/VEX/priv/guest_nanomips_toIR.c index 373ba5f..7233a73 100755 --- a/VEX/priv/guest_nanomips_toIR.c +++ b/VEX/priv/guest_nanomips_toIR.c @@ -2086,19 +2086,27 @@ static void nano_plsuawm(DisResult *dres, UInt cins) UChar count3 = (cins >> 12) & 0x07; UChar count = count3 ? count3 : 8; UChar counter = 0; - UInt offset = extend_sign(s, 9); + UInt offset = s; UChar rt_tmp, offset_tmp; - if ((cins >> 11) & 0x01) { /* swm */ - while (counter++ != count) { + if ((cins >> 11) & 0x01) { /* uaswm */ + + DIP("uaswm r%u, %d(r%u), %u", rt, (int)offset, rs, count); + + while (counter != count) { rt_tmp = rt ? (rt & 0x10) | ((rt + counter) & 0x1F) : 0; offset_tmp = offset + (counter << 2); store(binop(Iop_Add32, getIReg(rs), mkU32(offset_tmp)), getIReg(rt_tmp)); + counter+=1; } - } else { /* lwm */ - while (counter++ != count) { - rt_tmp = (rt & 0x10) | (rt + counter); + + } else { /* ualwm */ + + DIP("ualwm r%u, %d(r%u), %u", rt, (int)offset, rs, count); + + while (counter != count) { + rt_tmp = (rt & 0x10) | ((rt + counter) & 0x1F); offset_tmp = offset + (counter << 2); putIReg(rt_tmp, load(Ity_I32, binop(Iop_Add32, getIReg(rs), mkU32(offset_tmp)))); @@ -2107,6 +2115,7 @@ static void nano_plsuawm(DisResult *dres, UInt cins) vassert(0); // raise UNPREDICTABLE() } + counter+=1; } } |
|
From: Petar J. <pe...@so...> - 2020-01-14 12:14:24
|
https://sourceware.org/git/gitweb.cgi?p=valgrind.git;h=0fb2f59f57df506b39bd6959d69b87aa4d4143aa commit 0fb2f59f57df506b39bd6959d69b87aa4d4143aa Author: Aleksandar Rikalo <ale...@rt...> Date: Tue Jan 14 12:07:11 2020 +0000 mips: Change client request convention for nanoMIPS Use a7/t0 register pair for for client requests. The same convention is used throughout the rest of the code, as well as for mips32/64. Diff: --- VEX/priv/guest_nanomips_toIR.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/VEX/priv/guest_nanomips_toIR.c b/VEX/priv/guest_nanomips_toIR.c index 67f2313..373ba5f 100755 --- a/VEX/priv/guest_nanomips_toIR.c +++ b/VEX/priv/guest_nanomips_toIR.c @@ -2987,15 +2987,15 @@ static Bool check_for_special_requests_nanoMIPS(DisResult *dres, getUInt(code + 8) == word3 && getUInt(code + 12) == word4) { /* Got a "Special" instruction preamble. Which one is it? */ if (getUInt(code + 16) == 0x218C6290 /* or t0, t0, t0 */ ) { - /* $a0 = client_request ( $a1 ) */ - DIP("a0 = client_request(a1)"); + /* $a7 = client_request ( $t0 ) */ + DIP("a7 = client_request(t0)"); dres->jk_StopHere = Ijk_ClientReq; dres->whatNext = Dis_StopHere; dres->len = 20; return True; } else if (getUInt(code + 16) == 0x21AD6A90 /* or t1, t1, t1 */ ) { - /* $a0 = guest_NRADDR */ - DIP("a0 = guest_NRADDR"); + /* $a7 = guest_NRADDR */ + DIP("a7 = guest_NRADDR"); putIReg(11, IRExpr_Get(offsetof(VexGuestMIPS32State, guest_NRADDR), Ity_I32)); dres->len = 20; |
|
From: Petar J. <pe...@so...> - 2020-01-14 12:14:17
|
https://sourceware.org/git/gitweb.cgi?p=valgrind.git;h=d4d92fe5db8942e55b27398ccdafe927454271b6 commit d4d92fe5db8942e55b27398ccdafe927454271b6 Author: Aleksandar Rikalo <ale...@rt...> Date: Tue Jan 14 12:04:31 2020 +0000 mips: Fix Ist_CAS for nanoMIPS This code portion introduced a SEGFAULT: - if (&i->NMin.Cas.sz){ + if (i->NMin.Cas.sz == 8) { The implementation of Ist_Cas has been fixed and missing logging has been added as well. Diff: --- VEX/priv/host_nanomips_defs.c | 92 ++++++++++++++++++++++++++++++++----------- 1 file changed, 70 insertions(+), 22 deletions(-) diff --git a/VEX/priv/host_nanomips_defs.c b/VEX/priv/host_nanomips_defs.c index eadac53..9f0b975 100644 --- a/VEX/priv/host_nanomips_defs.c +++ b/VEX/priv/host_nanomips_defs.c @@ -605,9 +605,8 @@ void ppNANOMIPSInstr(const NANOMIPSInstr* i) break; case NMin_Cas: - if (i->NMin.Cas.sz == 4){ - vex_printf("cas: \n"); - + vex_printf("cas: \n"); + if (i->NMin.Cas.sz == 4) { vex_printf("ll "); ppHRegNANOMIPS(i->NMin.Cas.oldLo); vex_printf(", 0("); @@ -639,9 +638,61 @@ void ppNANOMIPSInstr(const NANOMIPSInstr* i) vex_printf(", "); ppHRegNANOMIPS(i->NMin.Cas.dataLo); vex_printf("; end:"); - } - else{ - vassert(0); + } else { + vex_printf("llwp "); + ppHRegNANOMIPS(i->NMin.Cas.oldLo); + vex_printf(", "); + ppHRegNANOMIPS(i->NMin.Cas.oldHi); + vex_printf(", 0("); + ppHRegNANOMIPS(i->NMin.Cas.addr); + vex_printf("); "); + + vex_printf("bnec "); + ppHRegNANOMIPS(i->NMin.Cas.oldLo); + vex_printf(", "); + ppHRegNANOMIPS(i->NMin.Cas.expdLo); + vex_printf(", end; "); + + vex_printf("bnec "); + ppHRegNANOMIPS(i->NMin.Cas.oldHi); + vex_printf(", "); + ppHRegNANOMIPS(i->NMin.Cas.expdHi); + vex_printf(", end; "); + + vex_printf("addiu "); + ppHRegNANOMIPS(i->NMin.Cas.oldLo); + vex_printf(", "); + ppHRegNANOMIPS(i->NMin.Cas.oldLo); + vex_printf(", 1; "); + + vex_printf("addiu "); + ppHRegNANOMIPS(i->NMin.Cas.oldHi); + vex_printf(", "); + ppHRegNANOMIPS(i->NMin.Cas.oldHi); + vex_printf(", 1; "); + + vex_printf("scwp "); + ppHRegNANOMIPS(i->NMin.Cas.dataLo); + vex_printf(", "); + ppHRegNANOMIPS(i->NMin.Cas.dataHi); + vex_printf(", 0("); + ppHRegNANOMIPS(i->NMin.Cas.addr); + vex_printf("); "); + + vex_printf("movn "); + ppHRegNANOMIPS(i->NMin.Cas.oldLo); + vex_printf(", "); + ppHRegNANOMIPS(i->NMin.Cas.expdLo); + vex_printf(", "); + ppHRegNANOMIPS(i->NMin.Cas.dataLo); + + vex_printf("movn "); + ppHRegNANOMIPS(i->NMin.Cas.oldHi); + vex_printf(", "); + ppHRegNANOMIPS(i->NMin.Cas.expdHi); + vex_printf(", "); + ppHRegNANOMIPS(i->NMin.Cas.dataHi); + vex_printf("; end:"); } break; @@ -807,18 +858,13 @@ void getRegUsage_NANOMIPSInstr(HRegUsage* u, const NANOMIPSInstr* i) return; case NMin_Cas: - if (i->NMin.Cas.sz == 4){ - addHRegUse(u, HRmWrite, i->NMin.Cas.oldLo); - addHRegUse(u, HRmRead, i->NMin.Cas.addr); - addHRegUse(u, HRmRead, i->NMin.Cas.expdLo); - addHRegUse(u, HRmModify, i->NMin.Cas.dataLo); - } else { - addHRegUse(u, HRmWrite, i->NMin.Cas.oldLo); + addHRegUse(u, HRmWrite, i->NMin.Cas.oldLo); + addHRegUse(u, HRmRead, i->NMin.Cas.addr); + addHRegUse(u, HRmRead, i->NMin.Cas.expdLo); + addHRegUse(u, HRmModify, i->NMin.Cas.dataLo); + if (i->NMin.Cas.sz == 8) { addHRegUse(u, HRmWrite, i->NMin.Cas.oldHi); - addHRegUse(u, HRmRead, i->NMin.Cas.addr); - addHRegUse(u, HRmRead, i->NMin.Cas.expdLo); addHRegUse(u, HRmRead, i->NMin.Cas.expdHi); - addHRegUse(u, HRmModify, i->NMin.Cas.dataLo); addHRegUse(u, HRmModify, i->NMin.Cas.dataHi); } return; @@ -938,7 +984,7 @@ void mapRegs_NANOMIPSInstr(HRegRemap * m, NANOMIPSInstr * i) mapReg(m, &i->NMin.Cas.addr); mapReg(m, &i->NMin.Cas.expdLo); mapReg(m, &i->NMin.Cas.dataLo); - if (&i->NMin.Cas.sz){ + if (i->NMin.Cas.sz == 8) { mapReg(m, &i->NMin.Cas.oldHi); mapReg(m, &i->NMin.Cas.expdHi); mapReg(m, &i->NMin.Cas.dataHi); @@ -1785,15 +1831,17 @@ Int emit_NANOMIPSInstr ( /*MB_MOD*/Bool* is_profInc, } case NMin_Cas: { + vassert((i->NMin.Cas.sz == 4) || (i->NMin.Cas.sz == 8)); UInt oldLo = iregNo(i->NMin.Cas.oldLo); - UInt oldHi = iregNo(i->NMin.Cas.oldHi); UInt addr = iregNo(i->NMin.Cas.addr); UInt expdLo = iregNo(i->NMin.Cas.expdLo); - UInt expdHi = iregNo(i->NMin.Cas.expdHi); UInt dataLo = iregNo(i->NMin.Cas.dataLo); - UInt dataHi = iregNo(i->NMin.Cas.dataHi); - - vassert((i->NMin.Cas.sz == 4) || (i->NMin.Cas.sz == 8)); + UInt oldHi = 0, expdHi = 0, dataHi = 0; + if (i->NMin.Cas.sz == 8) { + oldHi = iregNo(i->NMin.Cas.oldHi); + expdHi = iregNo(i->NMin.Cas.expdHi); + dataHi = iregNo(i->NMin.Cas.dataHi); + } if (i->NMin.Cas.sz == 4) { /* |
|
From: Petar J. <pe...@so...> - 2020-01-14 11:55:31
|
https://sourceware.org/git/gitweb.cgi?p=valgrind.git;h=43c90db16fdc3cfa9a3f11f409e2e3689d161978 commit 43c90db16fdc3cfa9a3f11f409e2e3689d161978 Author: Aleksandar Rikalo <ale...@rt...> Date: Tue Jan 14 11:54:15 2020 +0000 mips: Fix SAVE instruction for nanoMIPS During a save (push) instruction adjusting the SP is required before doing a store, otherwise Memcheck reports warning because of a write operation outside of the stack area. Diff: --- VEX/priv/guest_nanomips_toIR.c | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/VEX/priv/guest_nanomips_toIR.c b/VEX/priv/guest_nanomips_toIR.c index 2000896..67f2313 100755 --- a/VEX/priv/guest_nanomips_toIR.c +++ b/VEX/priv/guest_nanomips_toIR.c @@ -980,17 +980,21 @@ static void nano_ppsr(DisResult *dres, UInt cins) DIP("save %u, r%u-r%u", u, (rt & 0x1fu) | (rt & 0x10u), ((rt + count - 1) & 0x1fu) | (rt & 0x10u)); + IRTemp t1 = newTemp(Ity_I32); + assign(t1, getIReg(29)); + + putIReg(29, binop(Iop_Sub32, mkexpr(t1), mkU32(u))); + while (counter != count) { Bool use_gp = (cins & 0x04) && (counter + 1 == count); UChar this_rt = use_gp ? 28 : (UChar)((rt + counter) & 0x1f) | (rt & 0x10); Int offset = -((counter + 1) << 2); - store(binop(Iop_Add32, getIReg(29), mkU32(offset)), + store(binop(Iop_Add32, mkexpr(t1), mkU32(offset)), getIReg(this_rt)); counter++; } - putIReg(29, binop(Iop_Sub32, getIReg(29), mkU32(u))); break; } @@ -2328,14 +2332,17 @@ static void nano_p16sr(DisResult *dres, UShort cins) DIP("save %u, r%u-r%u", u, (rt & 0x1fu) | (rt & 0x10u), ((rt + count - 1) & 0x1fu) | (rt & 0x10u)); + IRTemp t1 = newTemp(Ity_I32); + assign(t1, getIReg(29)); + + putIReg(29, binop(Iop_Sub32, mkexpr(t1), mkU32(u))); + while (counter != count) { UChar this_rt = ((rt + counter) & 0x1f) | (rt & 0x10); Int offset = -((counter + 1) << 2); - store(binop(Iop_Add32, getIReg(29), mkU32(offset)), getIReg(this_rt)); + store(binop(Iop_Add32, mkexpr(t1), mkU32(offset)), getIReg(this_rt)); counter++; } - - putIReg(29, binop(Iop_Sub32, getIReg(29), mkU32(u))); } } |
|
From: Petar J. <pe...@so...> - 2020-01-14 11:55:27
|
https://sourceware.org/git/gitweb.cgi?p=valgrind.git;h=6eb5b451d31c3fb117bf61e0a62cf743dde83945 commit 6eb5b451d31c3fb117bf61e0a62cf743dde83945 Author: Petar Jovanovic <mip...@gm...> Date: Tue Jan 14 09:48:56 2020 +0000 mips: Fix BRSC and BALRSC instructions for nanoMIPS Basic blocks should be terminated after detecting branch instruction. Diff: --- VEX/priv/guest_nanomips_toIR.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/VEX/priv/guest_nanomips_toIR.c b/VEX/priv/guest_nanomips_toIR.c old mode 100644 new mode 100755 index ad099ed..2000896 --- a/VEX/priv/guest_nanomips_toIR.c +++ b/VEX/priv/guest_nanomips_toIR.c @@ -2547,8 +2547,10 @@ static void nano_pj(DisResult *dres, UInt cins) putIReg(rt, mkU32(guest_PC_curr_instr + 4)); putPC(mkexpr(t1)); } + dres->jk_StopHere = Ijk_Boring; + dres->whatNext = Dis_StopHere; + break; } - break; } } |
|
From: Petar J. <pe...@so...> - 2020-01-14 11:55:21
|
https://sourceware.org/git/gitweb.cgi?p=valgrind.git;h=1d3a772034d0c8243882c2f43afcb7245d707bf4 commit 1d3a772034d0c8243882c2f43afcb7245d707bf4 Author: Petar Jovanovic <mip...@gm...> Date: Tue Jan 14 09:31:48 2020 +0000 mips: Fix clone syscall for nanoMIPS - Reset syscall return register (a0) in clone_new_thread() - Use "syscall[32]" asm idiom instead of "syscall" with immediate parameter in ML_ (call_on_new_stack_0_1)() - Optimize stack usage in ML_ (call_on_new_stack_0_1)() - Code refactor of ML_ (call_on_new_stack_0_1)() It partially fixes all tests which use clone system call, e.g. none/tests/pth_atfork1. Patch by Aleksandar Rikalo. Diff: --- coregrind/m_syswrap/syswrap-linux.c | 2 +- coregrind/m_syswrap/syswrap-nanomips-linux.c | 99 ++++++++++++++-------------- 2 files changed, 49 insertions(+), 52 deletions(-) diff --git a/coregrind/m_syswrap/syswrap-linux.c b/coregrind/m_syswrap/syswrap-linux.c index 96c309e..25d9a95 100644 --- a/coregrind/m_syswrap/syswrap-linux.c +++ b/coregrind/m_syswrap/syswrap-linux.c @@ -528,7 +528,7 @@ static SysRes clone_new_thread ( Word (*fn)(void *), res = VG_ (mk_SysRes_mips32_linux) (/*val */ ret, 0, /*errflag */ 0); #elif defined(VGP_nanomips_linux) UInt ret = 0; - ctst->arch.vex.guest_r2 = 0; + ctst->arch.vex.guest_r4 = 0; ret = do_syscall_clone_nanomips_linux (ML_(start_thread_NORETURN), stack, flags, ctst, child_tidptr, parent_tidptr, NULL); diff --git a/coregrind/m_syswrap/syswrap-nanomips-linux.c b/coregrind/m_syswrap/syswrap-nanomips-linux.c index aac595a..0badf56 100644 --- a/coregrind/m_syswrap/syswrap-nanomips-linux.c +++ b/coregrind/m_syswrap/syswrap-nanomips-linux.c @@ -88,24 +88,24 @@ asm ( " move $ra, $a1 \n\t" // retaddr to $ra " move $t9, $a2 \n\t" // f to t9 " move $a0, $a3 \n\t" // arg1 to $a0 - " li $t4, 0\n\t" // zero all GP regs - " li $t5, 0\n\t" - " li $a1, 0\n\t" - " li $a2, 0\n\t" - " li $a3, 0\n\t" - " li $t0, 0\n\t" - " li $t1, 0\n\t" - " li $t2, 0\n\t" - " li $t3, 0\n\t" - " li $s0, 0\n\t" - " li $s1, 0\n\t" - " li $s2, 0\n\t" - " li $s3, 0\n\t" - " li $s4, 0\n\t" - " li $s5, 0\n\t" - " li $s6, 0\n\t" - " li $s7, 0\n\t" - " li $t8, 0\n\t" + " li $t4, 0 \n\t" // zero all GP regs + " li $t5, 0 \n\t" + " li $a1, 0 \n\t" + " li $a2, 0 \n\t" + " li $a3, 0 \n\t" + " li $t0, 0 \n\t" + " li $t1, 0 \n\t" + " li $t2, 0 \n\t" + " li $t3, 0 \n\t" + " li $s0, 0 \n\t" + " li $s1, 0 \n\t" + " li $s2, 0 \n\t" + " li $s3, 0 \n\t" + " li $s4, 0 \n\t" + " li $s5, 0 \n\t" + " li $s6, 0 \n\t" + " li $s7, 0 \n\t" + " li $t8, 0 \n\t" " jrc $t9 \n\t" // jump to dst " break 0x7 \n" // should never get here ".previous\n" @@ -142,48 +142,45 @@ asm ( // See priv_syswrap-linux.h for arg profile. asm ( -" .text\n" -" .set noreorder\n" -" .set nomacro\n" -" .globl do_syscall_clone_nanomips_linux\n" -" do_syscall_clone_nanomips_linux:\n" -" addiu $sp, $sp, -32\n" -" sw $ra, 0($sp) \n\t" -" sw $fp, 4($sp) \n\t" -" sw $gp, 8($sp) \n\t" -" sw $t4, 12($sp) \n\t" - -" addiu $a1, $a1, -32\n" -" sw $a0, 0($a1)\n" /* fn */ -" sw $a3, 4($a1)\n" /* arg */ -" sw $a2, 8($a1)\n" /* flags */ - +" .text \n" +" .set noreorder \n" +" .set nomacro \n" +" .globl do_syscall_clone_nanomips_linux \n" +" do_syscall_clone_nanomips_linux: \n\t" +" addiu $sp, $sp, -16 \n\t" +" sw $ra, 0($sp) \n\t" +" sw $fp, 4($sp) \n\t" +" sw $gp, 8($sp) \n\t" + +" addiu $a1, $a1, -16 \n\t" +" sw $a0, 0($a1) \n\t" /* fn */ +" sw $a3, 4($a1) \n\t" /* arg */ /* 1. arg for syscalls */ -" move $a0, $a2\n" /* flags */ -" move $a2, $a5\n" /* parent */ -" move $a3, $a6\n" /* tls */ +" move $a0, $a2 \n\t" /* flags */ +" move $a2, $a5 \n\t" /* parent */ +" move $a3, $a6 \n\t" /* tls */ /* 2. do a syscall to clone */ -" li $t4, " __NR_CLONE "\n\t" /* __NR_clone */ -" syscall 1\n" +" li $t4, " __NR_CLONE "\n\t" /* __NR_clone */ +" syscall[32] \n\t" /* 3. See if we are a child, call fn and after that exit */ -" bnezc $a0, p_or_error\n" +" bnezc $a0, p_or_error \n\t" + +" lw $t9, 0($sp) \n\t" +" lw $a0, 4($sp) \n\t" +" jalrc $t9 \n\t" -" lw $t9,0($sp)\n" -" lw $a0,4($sp)\n" -" jalrc $t9\n" +" li $t4, " __NR_EXIT "\n\t" /* NR_exit */ +" syscall[32] \n" -" li $t4, " __NR_EXIT "\n\t" /* NR_exit */ -" syscall 1\n\t" /* 4. If we are parent or error, just return to caller */ -" p_or_error:\n" -" lw $ra, 0($sp)\n" -" lw $fp, 4($sp)\n" -" lw $gp, 8($sp)\n" -" lw $t4, 12($sp)\n" -" addiu $sp,$sp, 32\n" +" p_or_error: \n\t" +" lw $ra, 0($sp) \n\t" +" lw $fp, 4($sp) \n\t" +" lw $gp, 8($sp) \n\t" +" addiu $sp, $sp, 16 \n\t" " jrc $ra\n" " .previous\n" |
|
From: Petar J. <pe...@so...> - 2020-01-09 18:29:41
|
https://sourceware.org/git/gitweb.cgi?p=valgrind.git;h=3e48ab0803d4f1fc1872bb7faed3310d2f5915de commit 3e48ab0803d4f1fc1872bb7faed3310d2f5915de Author: Petar Jovanovic <mip...@gm...> Date: Thu Jan 9 18:28:57 2020 +0000 mips: add IOP_And1 and Iop_Or1 for nanoMIPS Support IOP_And1 and Iop_Or1 in iselWordExpr_R_wrk(). Diff: --- VEX/priv/host_nanomips_isel.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/VEX/priv/host_nanomips_isel.c b/VEX/priv/host_nanomips_isel.c index a76a5c6..fe60a49 100644 --- a/VEX/priv/host_nanomips_isel.c +++ b/VEX/priv/host_nanomips_isel.c @@ -504,12 +504,14 @@ static HReg iselWordExpr_R_wrk(ISelEnv * env, IRExpr * e) aluOp = NMalu_SUB; break; + case Iop_And1: case Iop_And8: case Iop_And16: case Iop_And32: aluOp = NMalu_AND; break; + case Iop_Or1: case Iop_Or8: case Iop_Or16: case Iop_Or32: |
|
From: Petar J. <pe...@so...> - 2020-01-09 18:05:33
|
https://sourceware.org/git/gitweb.cgi?p=valgrind.git;h=f6ce74cd7bfa09b097277229824b11cc2ba56365 commit f6ce74cd7bfa09b097277229824b11cc2ba56365 Author: Petar Jovanovic <mip...@gm...> Date: Thu Jan 9 19:05:07 2020 +0100 mips: Implement Iop_CmpNEZ32, Iop_CmpNEZ64, Iop_And1 and Iop_Or1 Implement Iop_CmpNEZ32, Iop_CmpNEZ64, Iop_And1 and Iop_Or1 and fix broken Memcheck for mips32/64. Diff: --- VEX/priv/host_mips_isel.c | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/VEX/priv/host_mips_isel.c b/VEX/priv/host_mips_isel.c index f14f654..51428cf 100644 --- a/VEX/priv/host_mips_isel.c +++ b/VEX/priv/host_mips_isel.c @@ -925,6 +925,7 @@ static HReg iselWordExpr_R_wrk(ISelEnv * env, IRExpr * e) aluOp = Malu_DSUB; break; + case Iop_And1: case Iop_And8: case Iop_And16: case Iop_And32: @@ -932,6 +933,7 @@ static HReg iselWordExpr_R_wrk(ISelEnv * env, IRExpr * e) aluOp = Malu_AND; break; + case Iop_Or1: case Iop_Or8: case Iop_Or16: case Iop_Or32: @@ -2471,7 +2473,7 @@ static MIPSRH *iselWordExpr_RH_wrk(ISelEnv * env, Bool syned, IRExpr * e) ULong u; Long l; IRType ty = typeOfIRExpr(env->type_env, e); - vassert(ty == Ity_I8 || ty == Ity_I16 || ty == Ity_I32 || + vassert(ty == Ity_I1 || ty == Ity_I8 || ty == Ity_I16 || ty == Ity_I32 || ((ty == Ity_I64) && env->mode64)); /* special case: immediate */ @@ -2493,6 +2495,9 @@ static MIPSRH *iselWordExpr_RH_wrk(ISelEnv * env, Bool syned, IRExpr * e) case Ico_U8: u = 0x000000FF & con->Ico.U8; break; + case Ico_U1: + u = 0x00000001 & con->Ico.U1; + break; default: vpanic("iselIntExpr_RH.Iex_Const(mips)"); } @@ -2750,6 +2755,24 @@ static MIPSCondCode iselCondCode_wrk(ISelEnv * env, IRExpr * e) r_dst, mode64)); return MIPScc_NE; } + + if (e->tag == Iex_Unop + && (e->Iex.Unop.op == Iop_CmpNEZ32 + || ((e->Iex.Unop.op == Iop_CmpNEZ64) && mode64))) { + HReg r_dst = newVRegI(env); + HReg r_src = iselWordExpr_R(env, e->Iex.Unop.arg); + + addInstr(env, MIPSInstr_Cmp(False, !mode64, r_dst, r_src, + hregMIPS_GPR0(mode64), MIPScc_NE)); + /* Store result to guest_COND */ + MIPSAMode *am_addr = MIPSAMode_IR(0, GuestStatePointer(mode64)); + + addInstr(env, MIPSInstr_Store(4, + MIPSAMode_IR(am_addr->Mam.IR.index + COND_OFFSET(mode64), + am_addr->Mam.IR.base), + r_dst, mode64)); + return MIPScc_NE; + } #if 0 // sewardj 2019Dec14: this is my best attempt at And1/Or1, but I am not // sure if it is correct. In any case it is not needed until chasing cond |
|
From: Petar J. <pe...@so...> - 2020-01-06 16:53:10
|
https://sourceware.org/git/gitweb.cgi?p=valgrind.git;h=cb62332c32b3da338c680e97213df26689f284f9 commit cb62332c32b3da338c680e97213df26689f284f9 Author: Petar Jovanovic <mip...@gm...> Date: Mon Jan 6 16:51:37 2020 +0000 mips: update NEWS and README.mips Patches from Bug #400872 (Add nanoMIPS support to Valgrind) have been merged. Update README.mips with a correct configure line applicable for the latest nanomips toolchain package in public. Diff: --- NEWS | 3 ++- README.mips | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/NEWS b/NEWS index 9d24df6..895c96f 100644 --- a/NEWS +++ b/NEWS @@ -1,5 +1,5 @@ -Release 3.16.0 (?? ?????? 2019) +Release 3.16.0 (?? ?????? 2020) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 3.16.0 is a feature release with many improvements and the usual collection of @@ -72,6 +72,7 @@ To see details of a given bug, visit where XXXXXX is the bug number as listed below. 400593 In Coregrind, use statx for some internal syscalls if [f]stat[64] fail +400872 Add nanoMIPS support to Valgrind 404406 s390x: z14 miscellaneous instructions not implemented 405201 Incorrect size of struct vki_siginfo on 64-bit Linux architectures 406561 mcinfcallWSRU gdbserver_test fails on ppc64 diff --git a/README.mips b/README.mips index 82b00a5..df8b259 100644 --- a/README.mips +++ b/README.mips @@ -26,7 +26,7 @@ CFLAGS="-mips64 -mabi=64" will do the trick and compile Valgrind correctly. * --host=mips-linux-gnu is necessary if you compile it with cross toolchain compiler for big endian platform. - * --host=mipsel-linux-gnu is necessary if you compile it with cross toolchain + * --host=mipsel-linux-musl is necessary if you compile it with cross toolchain compiler for little endian platform. * --host=nanomipseb-linux-gnu is necessary if you compile it with cross toolchain |
|
From: Petar J. <pe...@so...> - 2020-01-06 13:53:58
|
https://sourceware.org/git/gitweb.cgi?p=valgrind.git;h=9acc066ffcf37ad04edfc801cc610ae64fa8d771 commit 9acc066ffcf37ad04edfc801cc610ae64fa8d771 Author: Petar Jovanovic <mip...@gm...> Date: Fri Jan 3 17:29:11 2020 +0000 mips: Add tests for nanoMIPS instruction set Patch by Tamara Vlahovic, Aleksandar Rikalo and Dimitrije Nikolic. Related KDE issue: #400872. Diff: --- .gitignore | 11 + configure.ac | 1 + none/tests/Makefile.am | 6 +- none/tests/allexec_prepare_prereq | 1 + none/tests/nanomips/Makefile.am | 33 + none/tests/nanomips/allexec.c | 56 + none/tests/nanomips/arithmetic.S | 1043 ++++++++++ none/tests/nanomips/arithmetic.stderr.exp | 0 none/tests/nanomips/arithmetic.stdout.exp | 868 ++++++++ none/tests/nanomips/arithmetic.vgtest | 2 + none/tests/nanomips/bits.S | 1051 ++++++++++ none/tests/nanomips/bits.stderr.exp | 0 none/tests/nanomips/bits.stdout.exp | 830 ++++++++ none/tests/nanomips/bits.vgtest | 2 + none/tests/nanomips/branches.c | 727 +++++++ none/tests/nanomips/branches.stderr.exp | 0 none/tests/nanomips/branches.stdout.exp | 480 +++++ none/tests/nanomips/branches.vgtest | 2 + none/tests/nanomips/filter_stderr | 4 + none/tests/nanomips/load_store.S | 2626 ++++++++++++++++++++++++ none/tests/nanomips/load_store.stderr.exp | 0 none/tests/nanomips/load_store.stdout.exp | 1228 +++++++++++ none/tests/nanomips/load_store.vgtest | 2 + none/tests/nanomips/move.S | 510 +++++ none/tests/nanomips/move.stderr.exp | 0 none/tests/nanomips/move.stdout.exp | 360 ++++ none/tests/nanomips/move.vgtest | 2 + none/tests/nanomips/mwrap_printf.c | 5 + none/tests/nanomips/pc_instructions.S | 243 +++ none/tests/nanomips/pc_instructions.stderr.exp | 0 none/tests/nanomips/pc_instructions.stdout.exp | 135 ++ none/tests/nanomips/pc_instructions.vgtest | 2 + 32 files changed, 10229 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 0d6f3af..58dfee0 100644 --- a/.gitignore +++ b/.gitignore @@ -1706,6 +1706,17 @@ /none/tests/mips64/unaligned_load /none/tests/mips64/unaligned_load_store +# /none/tests/nanomips/ +/none/tests/nanomips/Makefile +/none/tests/nanomips/Makefile.in +/none/tests/nanomips/.deps +/none/tests/nanomips/arithmetic +/none/tests/nanomips/bits +/none/tests/nanomips/branches +/none/tests/nanomips/load_store +/none/tests/nanomips/move +/none/tests/nanomips/pc_instructions + # /none/tests/ppc32/ /none/tests/ppc32/*.stderr.diff /none/tests/ppc32/*.stderr.out diff --git a/configure.ac b/configure.ac index 0d0e220..3336329 100755 --- a/configure.ac +++ b/configure.ac @@ -4843,6 +4843,7 @@ AC_CONFIG_FILES([ none/tests/s390x/Makefile none/tests/mips32/Makefile none/tests/mips64/Makefile + none/tests/nanomips/Makefile none/tests/linux/Makefile none/tests/darwin/Makefile none/tests/solaris/Makefile diff --git a/none/tests/Makefile.am b/none/tests/Makefile.am index e2b0187..e4a12ca 100644 --- a/none/tests/Makefile.am +++ b/none/tests/Makefile.am @@ -32,6 +32,10 @@ endif if VGCONF_ARCHS_INCLUDE_MIPS64 SUBDIRS += mips64 endif +if VGCONF_ARCHS_INCLUDE_NANOMIPS +SUBDIRS += nanomips +endif + # OS-specific tests if VGCONF_OS_IS_LINUX @@ -64,7 +68,7 @@ if VGCONF_PLATFORMS_INCLUDE_X86_SOLARIS SUBDIRS += x86-solaris endif -DIST_SUBDIRS = x86 amd64 ppc32 ppc64 arm arm64 s390x mips32 mips64 \ +DIST_SUBDIRS = x86 amd64 ppc32 ppc64 arm arm64 s390x mips32 mips64 nanomips \ linux darwin solaris amd64-linux x86-linux amd64-darwin \ x86-darwin amd64-solaris x86-solaris scripts . diff --git a/none/tests/allexec_prepare_prereq b/none/tests/allexec_prepare_prereq index 09958b5..a541f42 100755 --- a/none/tests/allexec_prepare_prereq +++ b/none/tests/allexec_prepare_prereq @@ -33,5 +33,6 @@ pair ppc32 ppc64 pair s390x_unexisting_in_32bits s390x pair arm arm64 pair mips32 mips64 +pair nanomips nanoMIPS_unexisting_in_64bits exit 0 diff --git a/none/tests/nanomips/Makefile.am b/none/tests/nanomips/Makefile.am new file mode 100644 index 0000000..a0ef139 --- /dev/null +++ b/none/tests/nanomips/Makefile.am @@ -0,0 +1,33 @@ +include $(top_srcdir)/Makefile.tool-tests.am + +dist_noinst_SCRIPTS = filter_stderr + +EXTRA_DIST = \ + arithmetic.vgtest arithmetic.stderr.exp arithmetic.stdout.exp \ + bits.vgtest bits.stderr.exp bits.stdout.exp \ + branches.vgtest branches.stderr.exp branches.stdout.exp \ + load_store.vgtest load_store.stderr.exp load_store.stdout.exp \ + move.vgtest move.stderr.exp move.stdout.exp \ + pc_instructions.vgtest pc_instructions.stderr.exp pc_instructions.stdout.exp + +check_PROGRAMS = \ + arithmetic \ + bits \ + branches \ + load_store \ + move \ + pc_instructions \ + allexec + +arithmetic_CCASFLAGS = -Wa,-mpic $(AM_CCASFLAGS) +bits_CCASFLAGS = -Wa,-mpic $(AM_CCASFLAGS) +load_store_CCASFLAGS = -Wa,-mpic $(AM_CCASFLAGS) +move_CCASFLAGS = -Wa,-mpic $(AM_CCASFLAGS) +pc_instructions_CCASFLAGS = -Wa,-mpic $(AM_CCASFLAGS) + +arithmetic_SOURCES = mwrap_printf.c arithmetic.S +bits_SOURCES = mwrap_printf.c bits.S +branches_SOURCES = branches.c +load_store_SOURCES = mwrap_printf.c load_store.S +move_SOURCES = mwrap_printf.c move.S +pc_instructions_SOURCES = mwrap_printf.c pc_instructions.S diff --git a/none/tests/nanomips/allexec.c b/none/tests/nanomips/allexec.c new file mode 100644 index 0000000..69e1208 --- /dev/null +++ b/none/tests/nanomips/allexec.c @@ -0,0 +1,56 @@ +#include <assert.h> +#include <stdio.h> +#include <string.h> +#include <sys/types.h> +#include <sys/wait.h> +#include <unistd.h> + +extern char **environ; + +#define S(...) (fprintf(stdout, __VA_ARGS__),fflush(stdout)) +#define FORKEXECWAIT(exec_call) do { \ + int status;\ + pid_t child = fork(); \ + if (child == 0) {exec_call; perror ("exec failed");} \ + else if (child == -1) perror ("cannot fork\n"); \ + else if (child != wait (&status)) perror ("error waiting child"); \ + else S("child exited\n"); \ + } while (0) + +void test_allexec (char *exec) +{ + FORKEXECWAIT (execlp(exec, exec, (char *) NULL)); + FORKEXECWAIT (execlp(exec, exec, "constant_arg1", "constant_arg2", + (char *) NULL)); + { + /* Solaris requires that the argv parameter to execve() isn't NULL, so + set it. Note that this isn't necessary on Linux. */ + char *const argv[] = {exec, NULL}; + FORKEXECWAIT (execve(exec, argv, environ)); + } +} + + +/* If a single argument "exec" is given, will execute itself + (in bi-arch, a 32 bit and 64 bit variant) via various exec system calls. + Note that this test can only be run after the prerequisite have been + prepared by allexec_prepare_prereq, which will a.o. make links + for the allexec32 and allexec64 executables. On single arch build, + these links points to the same executable to ensure this test works + everywhere the same. + No arguments or more arguments means just print its args. */ +int main(int argc, char **argv, char **envp) +{ + if ( (argc == 2) && (strcmp (argv[1], "exec") == 0)) { + S("%s will exec ./allexec32\n", argv[0]); + test_allexec ("./allexec32"); + S("%s will exec ./allexec64\n", argv[0]); + test_allexec ("./allexec64"); + } else { + int i; + S("program exec-ed:"); + for (i = 0; i < argc; i++) S(" %s", argv[i]); + S("\n"); + } + return 0; +} diff --git a/none/tests/nanomips/arithmetic.S b/none/tests/nanomips/arithmetic.S new file mode 100644 index 0000000..6fe4257 --- /dev/null +++ b/none/tests/nanomips/arithmetic.S @@ -0,0 +1,1043 @@ + .data + test_ints: #12 + .word 0x0 + .word 0xFFFFFFFF + .word 0x55555555 + .word 0x00000002 + .word 0xAAAAAAAA + .word 0x33333333 + .word 0xFFFFFFFE + .word 0x00000001 + .word 0xCCCCCCCC + .word 0x0000000A + .word 0x12345678 + .word 0x9ABCDEF + + .text + .align 1 + + .macro THREE_REG label, instruction, reg1, reg2, reg3, offset1, offset2, mem1, mem2 + .data + &label: + .ascii "&instruction ®1 %08x ®2 %08x ®3 %08x\n" + .byte 0 + .text + li $ra, &mem1 + lw ®2, &offset1($ra) + li $ra, &mem2 + lw ®3, &offset2($ra) + &instruction ®1, ®2, ®3 + move $a1, ®1 + li $a0, &label + lw $a3, &offset2($ra) + li $ra, &mem1 + lw $a2, &offset1($ra) + lapc[48] $t9, mwrap_printf + jalrc $t9 + .endm + + .macro TWO_REG_16 label, instruction, reg1, reg2, offset1, offset2, mem1, mem2 + .data + &label: + .ascii "&instruction ®1 %08x old ®1 %08x ®2 %08x\n" + .byte 0 + .text + li $ra, &mem1 + lw ®1, &offset1($ra) + li $ra, &mem2 + lw ®2, &offset2($ra) + &instruction ®1, ®2 + move $a1, ®1 + li $a0, &label + lw $a3, &offset2($ra) + li $ra, &mem1 + lw $a2, &offset1($ra) + lapc[48] $t9, mwrap_printf + jalrc $t9 + .endm + + .macro TWO_REG_1_IMM label, instruction, reg1, reg2, offset, mem, imm + .data + &label: + .ascii "&instruction ®1 %08x ®2 %08x, &imm\n" + .byte 0 + .text + li $ra, &mem + lw ®2, &offset($ra) + &instruction ®1, ®2, &imm + move $a1, ®1 + li $a0, &label + lw $a2, &offset($ra) + lapc[48] $t9, mwrap_printf + jalrc $t9 + .endm + + .macro ONE_REG_1_IMM label, instruction, reg, offset, mem, imm + .data + &label: + .ascii "&instruction ® %08x old ® %08x, &imm\n" + .byte 0 + .text + li $ra, &mem + lw ®, &offset($ra) + &instruction ®, &imm + move $a1, ® + li $a0, &label + lw $a2, &offset($ra) + lapc[48] $t9, mwrap_printf + jalrc $t9 + .endm + + .macro TWO_REG_1_IMM_SPECIAL label, instruction, special, reg, offset, mem, imm + .data + &label: + .ascii "&instruction ® %08x &special %08x, &imm\n" + .byte 0 + .text + move $ra, $sp + sw &special, 4($ra) + li ®, &mem + lw &special, &offset(®) + &instruction ®, &special, &imm + move $a1, ® + li $a0, &label + move $a2, &special + lw &special, 4($ra) + lapc[48] $t9, mwrap_printf + jalrc $t9 + .endm + + .globl main + .ent main + .type main, @function +main: + .set noreorder + .set nomacro + addiu $sp, $sp, -32 + save[32] 48,$30,$31,$16-$24,$28 + +# add + THREE_REG message1, add, $s5, $a6, $a1, 20, 40, test_ints, test_ints + THREE_REG message2, add, $t0, $s2, $t2, 36, 28, test_ints, test_ints + THREE_REG message3, add, $s2, $a2, $t0, 36, 40, test_ints, test_ints + THREE_REG message4, add, $s4, $a5, $a3, 20, 16, test_ints, test_ints + THREE_REG message5, add, $s1, $t1, $t2, 0, 24, test_ints, test_ints + THREE_REG message6, add, $a2, $t3, $a7, 32, 4, test_ints, test_ints + THREE_REG message7, add, $s0, $s5, $a7, 36, 28, test_ints, test_ints + THREE_REG message9, add, $s4, $a7, $t1, 32, 0, test_ints, test_ints + THREE_REG message10, add, $t3, $a4, $t1, 40, 20, test_ints, test_ints + THREE_REG message11, add, $s6, $a3, $s3, 32, 12, test_ints, test_ints + THREE_REG message12, add, $s5, $a6, $a7, 36, 12, test_ints, test_ints + THREE_REG message13, add, $t0, $s1, $a0, 0, 8, test_ints, test_ints + THREE_REG message14, add, $t3, $a6, $t3, 0, 40, test_ints, test_ints + THREE_REG message15, add, $s6, $a0, $s5, 28, 4, test_ints, test_ints + THREE_REG message16, add, $a5, $a2, $t1, 44, 4, test_ints, test_ints + THREE_REG message17, add, $s3, $s1, $s4, 24, 36, test_ints, test_ints + THREE_REG message18, add, $s0, $a7, $s4, 44, 16, test_ints, test_ints + THREE_REG message19, add, $t3, $s7, $s1, 28, 12, test_ints, test_ints + THREE_REG message20, add, $s3, $s3, $t1, 12, 44, test_ints, test_ints + THREE_REG message21, add, $a4, $t1, $a0, 36, 0, test_ints, test_ints + THREE_REG message22, add, $s5, $a3, $s6, 8, 40, test_ints, test_ints + THREE_REG message23, add, $a3, $s5, $t3, 0, 12, test_ints, test_ints + THREE_REG message24, add, $a4, $s0, $s7, 0, 44, test_ints, test_ints + THREE_REG message25, add, $s7, $t3, $s2, 36, 12, test_ints, test_ints + THREE_REG message26, add, $s6, $a0, $s6, 28, 28, test_ints, test_ints + THREE_REG message27, add, $s5, $a7, $s4, 4, 4, test_ints, test_ints + THREE_REG message28, add, $a4, $t2, $a0, 12, 36, test_ints, test_ints + THREE_REG message29, add, $s2, $a6, $a6, 36, 40, test_ints, test_ints + THREE_REG message30, add, $s6, $a5, $s6, 4, 40, test_ints, test_ints + THREE_REG message31, add, $a1, $s0, $a5, 32, 36, test_ints, test_ints + THREE_REG message32, add, $s0, $a6, $a6, 8, 20, test_ints, test_ints + THREE_REG message33, add, $a1, $s0, $s1, 8, 4, test_ints, test_ints + THREE_REG message34, add, $a6, $s2, $s4, 24, 4, test_ints, test_ints + THREE_REG message35, add, $a5, $t0, $a0, 12, 4, test_ints, test_ints + THREE_REG message36, add, $a6, $a5, $a6, 20, 24, test_ints, test_ints + THREE_REG message37, add, $s4, $a2, $a7, 8, 40, test_ints, test_ints + THREE_REG message38, add, $s4, $t2, $a4, 40, 36, test_ints, test_ints + THREE_REG message39, add, $a6, $a4, $a1, 12, 40, test_ints, test_ints + THREE_REG message40, add, $s6, $s5, $a0, 40, 44, test_ints, test_ints + +# addu[32] + THREE_REG message41, addu[32], $s6, $a3, $a7, 40, 12, test_ints, test_ints + THREE_REG message42, addu[32], $t0, $s4, $a4, 8, 36, test_ints, test_ints + THREE_REG message43, addu[32], $a3, $a7, $s0, 40, 36, test_ints, test_ints + THREE_REG message44, addu[32], $a6, $s6, $s7, 28, 36, test_ints, test_ints + THREE_REG message45, addu[32], $s0, $t1, $a1, 4, 16, test_ints, test_ints + THREE_REG message46, addu[32], $a3, $t0, $s1, 44, 8, test_ints, test_ints + THREE_REG message47, addu[32], $a0, $s1, $s2, 12, 28, test_ints, test_ints + THREE_REG message48, addu[32], $t1, $s7, $a0, 20, 20, test_ints, test_ints + THREE_REG message49, addu[32], $a5, $t0, $s0, 20, 40, test_ints, test_ints + THREE_REG message50, addu[32], $a5, $s4, $a5, 4, 12, test_ints, test_ints + THREE_REG message51, addu[32], $a2, $s1, $a4, 44, 28, test_ints, test_ints + THREE_REG message52, addu[32], $a0, $t2, $a7, 20, 4, test_ints, test_ints + THREE_REG message53, addu[32], $a1, $s1, $s7, 44, 0, test_ints, test_ints + THREE_REG message54, addu[32], $a2, $a0, $s7, 24, 8, test_ints, test_ints + THREE_REG message55, addu[32], $t0, $s4, $a2, 4, 4, test_ints, test_ints + THREE_REG message56, addu[32], $s5, $s2, $a1, 40, 12, test_ints, test_ints + THREE_REG message57, addu[32], $s0, $s4, $a5, 16, 28, test_ints, test_ints + THREE_REG message58, addu[32], $t0, $a4, $t1, 12, 36, test_ints, test_ints + THREE_REG message59, addu[32], $a2, $a4, $s6, 20, 32, test_ints, test_ints + THREE_REG message60, addu[32], $s6, $s4, $a0, 20, 40, test_ints, test_ints + THREE_REG message61, addu[32], $a6, $t2, $s2, 36, 44, test_ints, test_ints + THREE_REG message62, addu[32], $a0, $s6, $t1, 20, 0, test_ints, test_ints + THREE_REG message63, addu[32], $a1, $a2, $t0, 24, 8, test_ints, test_ints + THREE_REG message64, addu[32], $s7, $a2, $s3, 32, 4, test_ints, test_ints + THREE_REG message65, addu[32], $t0, $s6, $a1, 12, 0, test_ints, test_ints + THREE_REG message66, addu[32], $a1, $t1, $t0, 24, 44, test_ints, test_ints + THREE_REG message67, addu[32], $s6, $a0, $s1, 4, 4, test_ints, test_ints + THREE_REG message68, addu[32], $a4, $a5, $t3, 4, 8, test_ints, test_ints + THREE_REG message69, addu[32], $a3, $a6, $s4, 12, 32, test_ints, test_ints + THREE_REG message70, addu[32], $t3, $a6, $t2, 8, 40, test_ints, test_ints + THREE_REG message71, addu[32], $s7, $t2, $t1, 20, 20, test_ints, test_ints + THREE_REG message72, addu[32], $a1, $s2, $t3, 4, 0, test_ints, test_ints + THREE_REG message73, addu[32], $s2, $s7, $t1, 44, 0, test_ints, test_ints + THREE_REG message74, addu[32], $a2, $s7, $t1, 8, 0, test_ints, test_ints + THREE_REG message75, addu[32], $s0, $t1, $s7, 32, 4, test_ints, test_ints + THREE_REG message76, addu[32], $t3, $t3, $a7, 8, 4, test_ints, test_ints + THREE_REG message77, addu[32], $s2, $s5, $s4, 44, 24, test_ints, test_ints + THREE_REG message78, addu[32], $s5, $a0, $s5, 0, 36, test_ints, test_ints + THREE_REG message79, addu[32], $s1, $s6, $a4, 40, 20, test_ints, test_ints + THREE_REG message80, addu[32], $t1, $s1, $a0, 8, 12, test_ints, test_ints + +# addu[16] + THREE_REG message81, addu[16], $a1, $a2, $s0, 32, 44, test_ints, test_ints + THREE_REG message82, addu[16], $s1, $a3, $a2, 36, 4, test_ints, test_ints + THREE_REG message83, addu[16], $a0, $s3, $a3, 0, 24, test_ints, test_ints + THREE_REG message84, addu[16], $s1, $s1, $a2, 8, 8, test_ints, test_ints + THREE_REG message85, addu[16], $s3, $a0, $a0, 12, 40, test_ints, test_ints + THREE_REG message86, addu[16], $s2, $a0, $s3, 24, 44, test_ints, test_ints + THREE_REG message87, addu[16], $s2, $a3, $s1, 28, 44, test_ints, test_ints + THREE_REG message88, addu[16], $s0, $a0, $s3, 12, 4, test_ints, test_ints + THREE_REG message89, addu[16], $a0, $s3, $a0, 12, 44, test_ints, test_ints + THREE_REG message90, addu[16], $a2, $a1, $s0, 0, 28, test_ints, test_ints + THREE_REG message91, addu[16], $s2, $a3, $a3, 28, 28, test_ints, test_ints + THREE_REG message92, addu[16], $s2, $s1, $a3, 36, 28, test_ints, test_ints + THREE_REG message93, addu[16], $s2, $s0, $a3, 16, 44, test_ints, test_ints + THREE_REG message94, addu[16], $s2, $a0, $s3, 4, 44, test_ints, test_ints + THREE_REG message95, addu[16], $a1, $s2, $s2, 20, 36, test_ints, test_ints + THREE_REG message96, addu[16], $s1, $s0, $a2, 40, 16, test_ints, test_ints + THREE_REG message97, addu[16], $s2, $a0, $s0, 4, 44, test_ints, test_ints + THREE_REG message98, addu[16], $s3, $s3, $s0, 8, 4, test_ints, test_ints + THREE_REG message99, addu[16], $s0, $a1, $a1, 44, 4, test_ints, test_ints + THREE_REG message100, addu[16], $a0, $s1, $s1, 12, 28, test_ints, test_ints + THREE_REG message101, addu[16], $s1, $a0, $a1, 28, 40, test_ints, test_ints + THREE_REG message102, addu[16], $a2, $a1, $s2, 36, 44, test_ints, test_ints + THREE_REG message103, addu[16], $s2, $a3, $a3, 40, 0, test_ints, test_ints + THREE_REG message104, addu[16], $a3, $a1, $s0, 44, 0, test_ints, test_ints + THREE_REG message105, addu[16], $a1, $a3, $s1, 8, 40, test_ints, test_ints + THREE_REG message106, addu[16], $a2, $a2, $a0, 44, 20, test_ints, test_ints + THREE_REG message107, addu[16], $a3, $s0, $a2, 0, 0, test_ints, test_ints + THREE_REG message108, addu[16], $s0, $s2, $a1, 40, 44, test_ints, test_ints + THREE_REG message109, addu[16], $s0, $a0, $s2, 28, 28, test_ints, test_ints + THREE_REG message110, addu[16], $a3, $a2, $s0, 44, 24, test_ints, test_ints + THREE_REG message111, addu[16], $a0, $a0, $s1, 36, 8, test_ints, test_ints + THREE_REG message112, addu[16], $a0, $s3, $s0, 32, 12, test_ints, test_ints + THREE_REG message113, addu[16], $s1, $a3, $a3, 44, 44, test_ints, test_ints + THREE_REG message114, addu[16], $a3, $a3, $s1, 0, 20, test_ints, test_ints + THREE_REG message115, addu[16], $a1, $a0, $s2, 44, 0, test_ints, test_ints + THREE_REG message116, addu[16], $a1, $a2, $a2, 4, 36, test_ints, test_ints + THREE_REG message117, addu[16], $s0, $s2, $a1, 40, 44, test_ints, test_ints + THREE_REG message118, addu[16], $a3, $a2, $a3, 12, 40, test_ints, test_ints + THREE_REG message119, addu[16], $a2, $s1, $s1, 20, 32, test_ints, test_ints + THREE_REG message120, addu[16], $s0, $a1, $a0, 4, 36, test_ints, test_ints + +# addu[4x4] + TWO_REG_16 message121, addu[4x4], $s5, $s2, 8, 12, test_ints, test_ints + TWO_REG_16 message122, addu[4x4], $s2, $s6, 32, 16, test_ints, test_ints + TWO_REG_16 message123, addu[4x4], $a0, $a2, 8, 20, test_ints, test_ints + TWO_REG_16 message124, addu[4x4], $s0, $s7, 12, 12, test_ints, test_ints + TWO_REG_16 message125, addu[4x4], $a3, $s1, 24, 40, test_ints, test_ints + TWO_REG_16 message126, addu[4x4], $a3, $s0, 28, 32, test_ints, test_ints + TWO_REG_16 message127, addu[4x4], $s6, $a4, 32, 44, test_ints, test_ints + TWO_REG_16 message128, addu[4x4], $s4, $s5, 0, 36, test_ints, test_ints + TWO_REG_16 message129, addu[4x4], $s0, $a2, 4, 24, test_ints, test_ints + TWO_REG_16 message130, addu[4x4], $a0, $a1, 8, 4, test_ints, test_ints + TWO_REG_16 message131, addu[4x4], $a3, $a4, 40, 12, test_ints, test_ints + TWO_REG_16 message132, addu[4x4], $a4, $s5, 28, 12, test_ints, test_ints + TWO_REG_16 message133, addu[4x4], $a6, $a5, 4, 4, test_ints, test_ints + TWO_REG_16 message134, addu[4x4], $s6, $s1, 36, 16, test_ints, test_ints + TWO_REG_16 message135, addu[4x4], $s5, $s5, 12, 4, test_ints, test_ints + TWO_REG_16 message136, addu[4x4], $s2, $a7, 40, 24, test_ints, test_ints + TWO_REG_16 message137, addu[4x4], $s2, $s7, 16, 40, test_ints, test_ints + TWO_REG_16 message138, addu[4x4], $a1, $a3, 12, 32, test_ints, test_ints + TWO_REG_16 message139, addu[4x4], $a7, $s1, 0, 28, test_ints, test_ints + TWO_REG_16 message140, addu[4x4], $a6, $a7, 8, 32, test_ints, test_ints + +# div + THREE_REG message141, div, $a4, $a0, $a1, 8, 32, test_ints, test_ints+4 + THREE_REG message142, div, $s2, $s2, $s6, 28, 28, test_ints, test_ints+4 + THREE_REG message143, div, $a3, $a6, $a1, 4, 24, test_ints, test_ints+4 + THREE_REG message144, div, $a3, $s1, $a1, 36, 40, test_ints, test_ints+4 + THREE_REG message145, div, $t0, $s5, $a2, 28, 24, test_ints, test_ints+4 + THREE_REG message146, div, $a6, $t3, $a1, 4, 0, test_ints, test_ints+4 + THREE_REG message147, div, $t1, $s2, $a1, 28, 24, test_ints, test_ints+4 + THREE_REG message148, div, $a6, $s1, $t3, 16, 8, test_ints, test_ints+4 + THREE_REG message149, div, $t0, $s7, $a7, 20, 36, test_ints, test_ints+4 + THREE_REG message150, div, $t3, $a4, $t2, 0, 16, test_ints, test_ints+4 + THREE_REG message151, div, $t0, $s0, $a3, 40, 28, test_ints, test_ints+4 + THREE_REG message152, div, $a1, $t1, $s7, 40, 8, test_ints, test_ints+4 + THREE_REG message153, div, $t0, $s4, $a4, 40, 12, test_ints, test_ints+4 + THREE_REG message154, div, $a5, $t0, $s4, 32, 40, test_ints, test_ints+4 + THREE_REG message155, div, $s5, $s4, $t0, 32, 0, test_ints, test_ints+4 + THREE_REG message156, div, $a5, $s4, $t2, 44, 4, test_ints, test_ints+4 + THREE_REG message157, div, $t0, $s3, $a5, 28, 16, test_ints, test_ints+4 + THREE_REG message158, div, $s1, $s5, $s3, 32, 4, test_ints, test_ints+4 + THREE_REG message159, div, $a5, $a0, $a7, 8, 32, test_ints, test_ints+4 + THREE_REG message160, div, $a2, $a7, $t3, 28, 4, test_ints, test_ints+4 + THREE_REG message161, div, $a0, $a0, $a7, 0, 24, test_ints, test_ints+4 + THREE_REG message162, div, $a1, $a2, $t1, 16, 28, test_ints, test_ints+4 + THREE_REG message163, div, $s5, $a0, $s1, 8, 24, test_ints, test_ints+4 + THREE_REG message164, div, $a3, $t3, $a5, 8, 28, test_ints, test_ints+4 + THREE_REG message165, div, $s4, $s3, $t0, 32, 40, test_ints, test_ints+4 + THREE_REG message166, div, $t2, $s6, $a0, 36, 12, test_ints, test_ints+4 + THREE_REG message167, div, $s7, $t1, $a2, 12, 32, test_ints, test_ints+4 + THREE_REG message168, div, $t3, $t0, $a0, 16, 16, test_ints, test_ints+4 + THREE_REG message169, div, $t1, $a1, $s1, 24, 0, test_ints, test_ints+4 + THREE_REG message170, div, $a1, $a1, $t3, 8, 40, test_ints, test_ints+4 + THREE_REG message171, div, $s7, $s2, $t3, 44, 36, test_ints, test_ints+4 + THREE_REG message172, div, $a4, $a1, $t1, 4, 16, test_ints, test_ints+4 + THREE_REG message173, div, $t2, $s4, $a0, 16, 4, test_ints, test_ints+4 + THREE_REG message174, div, $a6, $s3, $s4, 8, 16, test_ints, test_ints+4 + THREE_REG message175, div, $s4, $a4, $a1, 20, 24, test_ints, test_ints+4 + THREE_REG message176, div, $s5, $s6, $t0, 32, 40, test_ints, test_ints+4 + THREE_REG message177, div, $s7, $s3, $a3, 40, 8, test_ints, test_ints+4 + THREE_REG message178, div, $a5, $s3, $t0, 8, 36, test_ints, test_ints+4 + THREE_REG message179, div, $a7, $a1, $a0, 44, 28, test_ints, test_ints+4 + THREE_REG message180, div, $s0, $a6, $t1, 32, 40, test_ints, test_ints+4 + +# divu + THREE_REG message181, divu, $t0, $a4, $s0, 4, 0, test_ints, test_ints+4 + THREE_REG message182, divu, $a3, $s6, $s4, 44, 4, test_ints, test_ints+4 + THREE_REG message183, divu, $t1, $t2, $a2, 32, 0, test_ints, test_ints+4 + THREE_REG message184, divu, $t1, $t1, $s0, 20, 28, test_ints, test_ints+4 + THREE_REG message185, divu, $s0, $a4, $a5, 0, 16, test_ints, test_ints+4 + THREE_REG message186, divu, $s2, $a0, $s1, 44, 20, test_ints, test_ints+4 + THREE_REG message187, divu, $a2, $t0, $t1, 24, 28, test_ints, test_ints+4 + THREE_REG message188, divu, $s7, $t1, $a4, 44, 32, test_ints, test_ints+4 + THREE_REG message189, divu, $s7, $t0, $t3, 36, 40, test_ints, test_ints+4 + THREE_REG message190, divu, $t0, $t2, $a6, 0, 12, test_ints, test_ints+4 + THREE_REG message191, divu, $t2, $a4, $t3, 28, 0, test_ints, test_ints+4 + THREE_REG message192, divu, $a3, $s5, $t1, 0, 32, test_ints, test_ints+4 + THREE_REG message193, divu, $a1, $a6, $s1, 8, 40, test_ints, test_ints+4 + THREE_REG message194, divu, $t2, $s5, $t2, 40, 0, test_ints, test_ints+4 + THREE_REG message195, divu, $t3, $s1, $a1, 40, 16, test_ints, test_ints+4 + THREE_REG message196, divu, $t2, $s6, $t1, 32, 0, test_ints, test_ints+4 + THREE_REG message197, divu, $s5, $s6, $a6, 16, 16, test_ints, test_ints+4 + THREE_REG message198, divu, $a2, $a7, $s2, 28, 36, test_ints, test_ints+4 + THREE_REG message199, divu, $a3, $s5, $t2, 16, 8, test_ints, test_ints+4 + THREE_REG message200, divu, $t3, $a3, $s1, 40, 28, test_ints, test_ints+4 + THREE_REG message201, divu, $s6, $t1, $a7, 28, 4, test_ints, test_ints+4 + THREE_REG message202, divu, $a6, $a5, $a1, 44, 8, test_ints, test_ints+4 + THREE_REG message203, divu, $s3, $a0, $s7, 4, 8, test_ints, test_ints+4 + THREE_REG message204, divu, $s4, $a3, $s4, 12, 16, test_ints, test_ints+4 + THREE_REG message205, divu, $a4, $s2, $a0, 44, 24, test_ints, test_ints+4 + THREE_REG message206, divu, $s7, $s6, $s2, 0, 20, test_ints, test_ints+4 + THREE_REG message207, divu, $t3, $s2, $s5, 8, 8, test_ints, test_ints+4 + THREE_REG message208, divu, $a0, $a4, $s3, 4, 12, test_ints, test_ints+4 + THREE_REG message209, divu, $a5, $a4, $s4, 16, 0, test_ints, test_ints+4 + THREE_REG message210, divu, $t1, $a5, $s1, 40, 12, test_ints, test_ints+4 + THREE_REG message211, divu, $t0, $a6, $a2, 16, 4, test_ints, test_ints+4 + THREE_REG message212, divu, $s1, $a3, $t0, 28, 20, test_ints, test_ints+4 + THREE_REG message213, divu, $a0, $s3, $s2, 24, 40, test_ints, test_ints+4 + THREE_REG message214, divu, $s0, $a6, $a6, 32, 32, test_ints, test_ints+4 + THREE_REG message215, divu, $t2, $t1, $t0, 40, 16, test_ints, test_ints+4 + THREE_REG message216, divu, $a2, $s4, $a2, 28, 4, test_ints, test_ints+4 + THREE_REG message217, divu, $s6, $t3, $a0, 20, 4, test_ints, test_ints+4 + THREE_REG message218, divu, $a2, $a6, $a2, 40, 20, test_ints, test_ints+4 + THREE_REG message219, divu, $a2, $a2, $s1, 36, 20, test_ints, test_ints+4 + THREE_REG message220, divu, $t2, $s5, $a7, 32, 4, test_ints, test_ints+4 + +# mod + THREE_REG message221, mod, $t3, $s6, $s6, 12, 0, test_ints, test_ints+4 + THREE_REG message222, mod, $s4, $s1, $a1, 24, 20, test_ints, test_ints+4 + THREE_REG message223, mod, $a7, $a1, $s3, 12, 8, test_ints, test_ints+4 + THREE_REG message224, mod, $s2, $a1, $a4, 4, 20, test_ints, test_ints+4 + THREE_REG message225, mod, $s6, $s7, $a6, 28, 12, test_ints, test_ints+4 + THREE_REG message226, mod, $a6, $s6, $a6, 4, 0, test_ints, test_ints+4 + THREE_REG message227, mod, $a3, $a4, $t1, 40, 8, test_ints, test_ints+4 + THREE_REG message228, mod, $a6, $s2, $a1, 12, 40, test_ints, test_ints+4 + THREE_REG message229, mod, $a6, $a6, $s1, 4, 16, test_ints, test_ints+4 + THREE_REG message230, mod, $t3, $a0, $t3, 0, 20, test_ints, test_ints+4 + THREE_REG message231, mod, $a2, $s2, $a0, 16, 40, test_ints, test_ints+4 + THREE_REG message232, mod, $s5, $a7, $a0, 28, 24, test_ints, test_ints+4 + THREE_REG message233, mod, $a2, $a2, $s1, 12, 20, test_ints, test_ints+4 + THREE_REG message234, mod, $a1, $s1, $a2, 8, 16, test_ints, test_ints+4 + THREE_REG message235, mod, $s3, $a0, $a6, 32, 20, test_ints, test_ints+4 + THREE_REG message236, mod, $a4, $s4, $a2, 44, 0, test_ints, test_ints+4 + THREE_REG message237, mod, $a7, $s1, $t2, 12, 16, test_ints, test_ints+4 + THREE_REG message238, mod, $t0, $a0, $s1, 0, 0, test_ints, test_ints+4 + THREE_REG message239, mod, $s5, $s3, $a6, 8, 40, test_ints, test_ints+4 + THREE_REG message240, mod, $t2, $a3, $a4, 4, 16, test_ints, test_ints+4 + THREE_REG message241, mod, $a4, $a4, $s2, 44, 20, test_ints, test_ints+4 + THREE_REG message242, mod, $a4, $a7, $a0, 8, 32, test_ints, test_ints+4 + THREE_REG message243, mod, $a0, $a5, $s3, 28, 12, test_ints, test_ints+4 + THREE_REG message244, mod, $s5, $a7, $t1, 8, 12, test_ints, test_ints+4 + THREE_REG message245, mod, $s1, $t0, $t3, 28, 40, test_ints, test_ints+4 + THREE_REG message246, mod, $s5, $a5, $s6, 36, 40, test_ints, test_ints+4 + THREE_REG message247, mod, $a4, $s6, $s6, 8, 4, test_ints, test_ints+4 + THREE_REG message248, mod, $a3, $s3, $a4, 12, 36, test_ints, test_ints+4 + THREE_REG message249, mod, $t2, $a4, $s7, 4, 8, test_ints, test_ints+4 + THREE_REG message250, mod, $a0, $s7, $s6, 4, 40, test_ints, test_ints+4 + THREE_REG message251, mod, $a2, $t2, $a5, 36, 36, test_ints, test_ints+4 + THREE_REG message252, mod, $t0, $s7, $s3, 24, 32, test_ints, test_ints+4 + THREE_REG message253, mod, $s1, $a6, $s2, 16, 8, test_ints, test_ints+4 + THREE_REG message254, mod, $a7, $a7, $a3, 44, 40, test_ints, test_ints+4 + THREE_REG message255, mod, $s5, $a1, $t2, 32, 20, test_ints, test_ints+4 + THREE_REG message256, mod, $a5, $a0, $t2, 16, 36, test_ints, test_ints+4 + THREE_REG message257, mod, $a7, $s6, $s0, 20, 24, test_ints, test_ints+4 + THREE_REG message258, mod, $a5, $a1, $a3, 32, 24, test_ints, test_ints+4 + THREE_REG message259, mod, $t3, $t2, $s1, 40, 24, test_ints, test_ints+4 + THREE_REG message260, mod, $a1, $t1, $a1, 36, 8, test_ints, test_ints+4 + +# modu + THREE_REG message261, modu, $s7, $a2, $a2, 8, 40, test_ints, test_ints+4 + THREE_REG message262, modu, $t1, $t3, $s6, 12, 16, test_ints, test_ints+4 + THREE_REG message263, modu, $s7, $a3, $t2, 12, 32, test_ints, test_ints+4 + THREE_REG message264, modu, $s6, $a1, $a1, 4, 4, test_ints, test_ints+4 + THREE_REG message265, modu, $a4, $s0, $s7, 36, 4, test_ints, test_ints+4 + THREE_REG message266, modu, $s1, $t2, $s0, 8, 4, test_ints, test_ints+4 + THREE_REG message267, modu, $s1, $t2, $s1, 44, 16, test_ints, test_ints+4 + THREE_REG message268, modu, $a3, $a1, $a3, 4, 32, test_ints, test_ints+4 + THREE_REG message269, modu, $a7, $a5, $a3, 20, 24, test_ints, test_ints+4 + THREE_REG message270, modu, $a3, $s3, $s5, 32, 24, test_ints, test_ints+4 + THREE_REG message271, modu, $a3, $a0, $s0, 24, 8, test_ints, test_ints+4 + THREE_REG message272, modu, $t3, $a0, $t0, 44, 8, test_ints, test_ints+4 + THREE_REG message273, modu, $a3, $s0, $a0, 36, 24, test_ints, test_ints+4 + THREE_REG message274, modu, $a4, $s0, $a4, 0, 28, test_ints, test_ints+4 + THREE_REG message275, modu, $s5, $a7, $a7, 32, 28, test_ints, test_ints+4 + THREE_REG message276, modu, $t3, $s4, $s7, 4, 40, test_ints, test_ints+4 + THREE_REG message277, modu, $a7, $s0, $s1, 44, 12, test_ints, test_ints+4 + THREE_REG message278, modu, $a6, $a6, $t2, 40, 8, test_ints, test_ints+4 + THREE_REG message279, modu, $s5, $t2, $s5, 4, 24, test_ints, test_ints+4 + THREE_REG message280, modu, $t1, $s2, $a3, 36, 16, test_ints, test_ints+4 + THREE_REG message281, modu, $s5, $t2, $t1, 0, 20, test_ints, test_ints+4 + THREE_REG message282, modu, $a1, $s4, $t3, 32, 0, test_ints, test_ints+4 + THREE_REG message283, modu, $a7, $s7, $t1, 32, 12, test_ints, test_ints+4 + THREE_REG message284, modu, $s7, $a3, $s1, 24, 40, test_ints, test_ints+4 + THREE_REG message285, modu, $s6, $t3, $s7, 32, 32, test_ints, test_ints+4 + THREE_REG message286, modu, $s2, $t1, $s6, 8, 40, test_ints, test_ints+4 + THREE_REG message287, modu, $t0, $t3, $s1, 36, 36, test_ints, test_ints+4 + THREE_REG message288, modu, $s0, $a6, $t0, 12, 32, test_ints, test_ints+4 + THREE_REG message289, modu, $a5, $s6, $s5, 8, 20, test_ints, test_ints+4 + THREE_REG message290, modu, $t0, $s1, $a6, 20, 28, test_ints, test_ints+4 + THREE_REG message291, modu, $s7, $s3, $s6, 44, 16, test_ints, test_ints+4 + THREE_REG message292, modu, $s3, $a1, $a0, 36, 40, test_ints, test_ints+4 + THREE_REG message293, modu, $s3, $s6, $a7, 0, 0, test_ints, test_ints+4 + THREE_REG message294, modu, $s3, $a0, $a6, 28, 12, test_ints, test_ints+4 + THREE_REG message295, modu, $a4, $a4, $s5, 40, 32, test_ints, test_ints+4 + THREE_REG message296, modu, $t0, $a6, $s7, 8, 32, test_ints, test_ints+4 + THREE_REG message297, modu, $a3, $s2, $s6, 20, 40, test_ints, test_ints+4 + THREE_REG message298, modu, $t2, $s0, $s6, 8, 28, test_ints, test_ints+4 + THREE_REG message299, modu, $a2, $a1, $a0, 36, 0, test_ints, test_ints+4 + THREE_REG message300, modu, $s3, $s4, $a5, 4, 36, test_ints, test_ints+4 + +# muh + THREE_REG message301, muh, $a4, $s6, $a3, 8, 0, test_ints, test_ints + THREE_REG message302, muh, $a1, $a6, $t2, 16, 4, test_ints, test_ints + THREE_REG message303, muh, $a1, $s3, $a3, 28, 20, test_ints, test_ints + THREE_REG message304, muh, $t0, $t1, $a1, 8, 0, test_ints, test_ints + THREE_REG message305, muh, $t3, $t0, $s1, 44, 4, test_ints, test_ints + THREE_REG message306, muh, $s7, $a3, $s1, 32, 32, test_ints, test_ints + THREE_REG message307, muh, $a0, $t1, $a6, 12, 44, test_ints, test_ints + THREE_REG message308, muh, $s2, $s0, $a5, 16, 20, test_ints, test_ints + THREE_REG message309, muh, $t2, $s5, $a0, 4, 20, test_ints, test_ints + THREE_REG message310, muh, $s5, $s1, $s2, 12, 32, test_ints, test_ints + THREE_REG message311, muh, $t2, $a6, $s0, 0, 24, test_ints, test_ints + THREE_REG message312, muh, $a6, $a7, $s5, 44, 12, test_ints, test_ints + THREE_REG message313, muh, $t1, $a0, $s0, 32, 12, test_ints, test_ints + THREE_REG message314, muh, $a7, $a6, $t0, 36, 28, test_ints, test_ints + THREE_REG message315, muh, $a5, $s3, $a0, 4, 36, test_ints, test_ints + THREE_REG message316, muh, $s5, $s3, $s6, 16, 24, test_ints, test_ints + THREE_REG message317, muh, $t2, $s6, $s0, 28, 40, test_ints, test_ints + THREE_REG message318, muh, $t2, $t1, $a1, 12, 0, test_ints, test_ints + THREE_REG message319, muh, $s5, $s1, $t0, 20, 4, test_ints, test_ints + THREE_REG message320, muh, $s4, $s1, $s3, 16, 40, test_ints, test_ints + THREE_REG message321, muh, $t2, $a5, $a5, 12, 8, test_ints, test_ints + THREE_REG message322, muh, $a2, $s4, $a5, 4, 0, test_ints, test_ints + THREE_REG message323, muh, $a7, $t3, $a3, 16, 8, test_ints, test_ints + THREE_REG message324, muh, $s1, $s6, $s7, 28, 24, test_ints, test_ints + THREE_REG message325, muh, $a0, $a4, $t3, 32, 4, test_ints, test_ints + THREE_REG message326, muh, $a4, $a0, $a6, 28, 16, test_ints, test_ints + THREE_REG message327, muh, $a0, $t2, $t1, 24, 20, test_ints, test_ints + THREE_REG message328, muh, $s4, $a0, $a1, 36, 20, test_ints, test_ints + THREE_REG message329, muh, $a2, $t1, $a1, 4, 20, test_ints, test_ints + THREE_REG message330, muh, $t3, $s6, $a7, 28, 4, test_ints, test_ints + THREE_REG message331, muh, $t1, $a7, $s5, 0, 12, test_ints, test_ints + THREE_REG message332, muh, $s3, $s4, $s0, 4, 0, test_ints, test_ints + THREE_REG message333, muh, $a0, $t2, $s2, 8, 16, test_ints, test_ints + THREE_REG message334, muh, $t3, $a2, $s0, 32, 12, test_ints, test_ints + THREE_REG message335, muh, $s2, $s6, $s0, 28, 12, test_ints, test_ints + THREE_REG message336, muh, $s5, $a2, $a6, 36, 36, test_ints, test_ints + THREE_REG message337, muh, $s7, $s2, $t0, 4, 44, test_ints, test_ints + THREE_REG message338, muh, $s4, $a0, $s3, 32, 36, test_ints, test_ints + THREE_REG message339, muh, $a3, $s4, $a7, 4, 8, test_ints, test_ints + THREE_REG message340, muh, $s7, $s4, $a4, 16, 20, test_ints, test_ints + +# muhu + THREE_REG message341, muhu, $t0, $a6, $s3, 32, 20, test_ints, test_ints + THREE_REG message342, muhu, $a3, $a2, $a3, 36, 44, test_ints, test_ints + THREE_REG message343, muhu, $s5, $t0, $t1, 20, 36, test_ints, test_ints + THREE_REG message344, muhu, $a4, $s5, $t1, 0, 4, test_ints, test_ints + THREE_REG message345, muhu, $s7, $s3, $t2, 40, 4, test_ints, test_ints + THREE_REG message346, muhu, $a0, $s2, $s1, 4, 40, test_ints, test_ints + THREE_REG message347, muhu, $a6, $a5, $s4, 24, 4, test_ints, test_ints + THREE_REG message348, muhu, $a1, $s5, $s7, 0, 24, test_ints, test_ints + THREE_REG message349, muhu, $s2, $t1, $s2, 32, 12, test_ints, test_ints + THREE_REG message350, muhu, $s0, $a4, $a4, 4, 16, test_ints, test_ints + THREE_REG message351, muhu, $s2, $s4, $t0, 0, 44, test_ints, test_ints + THREE_REG message352, muhu, $s5, $s4, $t1, 40, 20, test_ints, test_ints + THREE_REG message353, muhu, $a3, $a1, $s6, 28, 28, test_ints, test_ints + THREE_REG message354, muhu, $s0, $s0, $s4, 44, 32, test_ints, test_ints + THREE_REG message355, muhu, $t2, $a6, $s6, 16, 40, test_ints, test_ints + THREE_REG message356, muhu, $s5, $s0, $a2, 36, 8, test_ints, test_ints + THREE_REG message357, muhu, $a7, $s3, $a6, 44, 12, test_ints, test_ints + THREE_REG message358, muhu, $a5, $s0, $t0, 40, 40, test_ints, test_ints + THREE_REG message359, muhu, $t1, $t1, $a3, 32, 32, test_ints, test_ints + THREE_REG message360, muhu, $a2, $s4, $s4, 24, 12, test_ints, test_ints + THREE_REG message361, muhu, $s1, $a4, $a5, 28, 20, test_ints, test_ints + THREE_REG message362, muhu, $s3, $s0, $s5, 24, 20, test_ints, test_ints + THREE_REG message363, muhu, $a7, $s5, $a1, 8, 32, test_ints, test_ints + THREE_REG message364, muhu, $a4, $s3, $t0, 32, 40, test_ints, test_ints + THREE_REG message365, muhu, $t2, $s2, $s7, 8, 8, test_ints, test_ints + THREE_REG message366, muhu, $a0, $t0, $a6, 0, 44, test_ints, test_ints + THREE_REG message367, muhu, $a5, $s5, $t3, 12, 0, test_ints, test_ints + THREE_REG message368, muhu, $t0, $s6, $t0, 8, 32, test_ints, test_ints + THREE_REG message369, muhu, $a6, $s1, $s5, 12, 28, test_ints, test_ints + THREE_REG message370, muhu, $a1, $s3, $t3, 20, 16, test_ints, test_ints + THREE_REG message371, muhu, $t1, $t0, $s6, 16, 24, test_ints, test_ints + THREE_REG message372, muhu, $s0, $a4, $s6, 24, 20, test_ints, test_ints + THREE_REG message373, muhu, $s1, $s3, $s6, 20, 40, test_ints, test_ints + THREE_REG message374, muhu, $s7, $t1, $s1, 44, 28, test_ints, test_ints + THREE_REG message375, muhu, $a1, $s1, $s1, 44, 0, test_ints, test_ints + THREE_REG message376, muhu, $t0, $t0, $a0, 44, 24, test_ints, test_ints + THREE_REG message377, muhu, $a4, $a4, $a2, 40, 4, test_ints, test_ints + THREE_REG message378, muhu, $s4, $t2, $s5, 40, 32, test_ints, test_ints + THREE_REG message379, muhu, $s6, $a0, $a7, 20, 36, test_ints, test_ints + THREE_REG message380, muhu, $a2, $t0, $t2, 12, 28, test_ints, test_ints + +# mul[32] + THREE_REG message381, mul[32], $t2, $a4, $s1, 28, 12, test_ints, test_ints + THREE_REG message382, mul[32], $a5, $a7, $s0, 20, 12, test_ints, test_ints + THREE_REG message383, mul[32], $s6, $a1, $s3, 32, 28, test_ints, test_ints + THREE_REG message384, mul[32], $a0, $s4, $t1, 24, 24, test_ints, test_ints + THREE_REG message385, mul[32], $s5, $s0, $s2, 4, 20, test_ints, test_ints + THREE_REG message386, mul[32], $s3, $s7, $t1, 40, 8, test_ints, test_ints + THREE_REG message387, mul[32], $t1, $s4, $a6, 40, 28, test_ints, test_ints + THREE_REG message388, mul[32], $t2, $s3, $s2, 8, 20, test_ints, test_ints + THREE_REG message389, mul[32], $a5, $a4, $s2, 4, 32, test_ints, test_ints + THREE_REG message390, mul[32], $a2, $s1, $t0, 12, 44, test_ints, test_ints + THREE_REG message391, mul[32], $a6, $a5, $a4, 20, 24, test_ints, test_ints + THREE_REG message392, mul[32], $a5, $s4, $a5, 44, 24, test_ints, test_ints + THREE_REG message393, mul[32], $s7, $s4, $t2, 20, 40, test_ints, test_ints + THREE_REG message394, mul[32], $a1, $s3, $a1, 0, 20, test_ints, test_ints + THREE_REG message395, mul[32], $s2, $s1, $a5, 36, 24, test_ints, test_ints + THREE_REG message396, mul[32], $s1, $s7, $s0, 20, 24, test_ints, test_ints + THREE_REG message397, mul[32], $a3, $s4, $a3, 28, 20, test_ints, test_ints + THREE_REG message398, mul[32], $s5, $t1, $a5, 8, 32, test_ints, test_ints + THREE_REG message399, mul[32], $s4, $t1, $t0, 40, 28, test_ints, test_ints + THREE_REG message400, mul[32], $s6, $a4, $a2, 12, 32, test_ints, test_ints + THREE_REG message401, mul[32], $a4, $t2, $s1, 36, 28, test_ints, test_ints + THREE_REG message402, mul[32], $a0, $s3, $a6, 16, 0, test_ints, test_ints + THREE_REG message403, mul[32], $a4, $s7, $s0, 0, 44, test_ints, test_ints + THREE_REG message404, mul[32], $a1, $a5, $t0, 12, 0, test_ints, test_ints + THREE_REG message405, mul[32], $a0, $s3, $s5, 0, 20, test_ints, test_ints + THREE_REG message406, mul[32], $t0, $a2, $s1, 12, 4, test_ints, test_ints + THREE_REG message407, mul[32], $s1, $s7, $s7, 44, 32, test_ints, test_ints + THREE_REG message408, mul[32], $a6, $s3, $a7, 16, 12, test_ints, test_ints + THREE_REG message409, mul[32], $t0, $a1, $t2, 16, 4, test_ints, test_ints + THREE_REG message410, mul[32], $a5, $t2, $t2, 4, 20, test_ints, test_ints + THREE_REG message411, mul[32], $a6, $a1, $a0, 32, 20, test_ints, test_ints + THREE_REG message412, mul[32], $a5, $s0, $t3, 12, 44, test_ints, test_ints + THREE_REG message413, mul[32], $s1, $t0, $a6, 0, 44, test_ints, test_ints + THREE_REG message414, mul[32], $s7, $s7, $t2, 40, 28, test_ints, test_ints + THREE_REG message415, mul[32], $a1, $s2, $s4, 0, 12, test_ints, test_ints + THREE_REG message416, mul[32], $a5, $a5, $t1, 32, 28, test_ints, test_ints + THREE_REG message417, mul[32], $a6, $a2, $a0, 8, 24, test_ints, test_ints + THREE_REG message418, mul[32], $s2, $a3, $s7, 36, 24, test_ints, test_ints + THREE_REG message419, mul[32], $s6, $s2, $a7, 36, 44, test_ints, test_ints + THREE_REG message420, mul[32], $s6, $t0, $s6, 36, 40, test_ints, test_ints + +# mul[4x4] + TWO_REG_16 message421, mul[4x4], $a1, $s6, 20, 8, test_ints, test_ints + TWO_REG_16 message422, mul[4x4], $a2, $s4, 44, 0, test_ints, test_ints + TWO_REG_16 message423, mul[4x4], $a5, $s3, 44, 12, test_ints, test_ints + TWO_REG_16 message424, mul[4x4], $s2, $s7, 20, 32, test_ints, test_ints + TWO_REG_16 message425, mul[4x4], $s5, $a0, 12, 28, test_ints, test_ints + TWO_REG_16 message426, mul[4x4], $a3, $s6, 20, 40, test_ints, test_ints + TWO_REG_16 message427, mul[4x4], $a3, $a4, 32, 12, test_ints, test_ints + TWO_REG_16 message428, mul[4x4], $s6, $s5, 4, 16, test_ints, test_ints + TWO_REG_16 message429, mul[4x4], $s4, $s6, 40, 40, test_ints, test_ints + TWO_REG_16 message430, mul[4x4], $s2, $s5, 8, 44, test_ints, test_ints + TWO_REG_16 message431, mul[4x4], $s1, $s1, 24, 44, test_ints, test_ints + TWO_REG_16 message432, mul[4x4], $s1, $s3, 44, 40, test_ints, test_ints + TWO_REG_16 message433, mul[4x4], $s4, $s3, 36, 44, test_ints, test_ints + TWO_REG_16 message434, mul[4x4], $s1, $s3, 4, 0, test_ints, test_ints + TWO_REG_16 message435, mul[4x4], $s7, $a5, 12, 40, test_ints, test_ints + TWO_REG_16 message436, mul[4x4], $a3, $s0, 24, 12, test_ints, test_ints + TWO_REG_16 message437, mul[4x4], $a7, $a4, 4, 20, test_ints, test_ints + TWO_REG_16 message438, mul[4x4], $a1, $s4, 36, 8, test_ints, test_ints + TWO_REG_16 message439, mul[4x4], $a5, $s3, 20, 8, test_ints, test_ints + TWO_REG_16 message440, mul[4x4], $a7, $s5, 4, 12, test_ints, test_ints + +# mulu + THREE_REG message441, mulu, $a0, $a2, $s6, 4, 4, test_ints, test_ints + THREE_REG message442, mulu, $a3, $s5, $s1, 16, 32, test_ints, test_ints + THREE_REG message443, mulu, $a3, $a3, $a0, 4, 24, test_ints, test_ints + THREE_REG message444, mulu, $s3, $s1, $s0, 20, 40, test_ints, test_ints + THREE_REG message445, mulu, $a0, $a6, $a5, 20, 36, test_ints, test_ints + THREE_REG message446, mulu, $s6, $t0, $t0, 28, 4, test_ints, test_ints + THREE_REG message447, mulu, $a7, $t3, $s7, 36, 16, test_ints, test_ints + THREE_REG message448, mulu, $t1, $t0, $a5, 8, 36, test_ints, test_ints + THREE_REG message449, mulu, $a5, $a1, $t0, 8, 40, test_ints, test_ints + THREE_REG message450, mulu, $a7, $s1, $s3, 12, 8, test_ints, test_ints + THREE_REG message451, mulu, $a5, $a7, $a0, 8, 0, test_ints, test_ints + THREE_REG message452, mulu, $a2, $t1, $a0, 40, 0, test_ints, test_ints + THREE_REG message453, mulu, $a5, $a6, $s0, 20, 28, test_ints, test_ints + THREE_REG message454, mulu, $a0, $s2, $t0, 40, 16, test_ints, test_ints + THREE_REG message455, mulu, $s1, $s7, $s1, 20, 4, test_ints, test_ints + THREE_REG message456, mulu, $s3, $a4, $a3, 40, 12, test_ints, test_ints + THREE_REG message457, mulu, $a5, $t3, $s2, 40, 8, test_ints, test_ints + THREE_REG message458, mulu, $a7, $s0, $t3, 28, 24, test_ints, test_ints + THREE_REG message459, mulu, $s7, $a5, $a4, 28, 8, test_ints, test_ints + THREE_REG message460, mulu, $a4, $t0, $s0, 0, 24, test_ints, test_ints + THREE_REG message461, mulu, $s0, $a1, $a1, 36, 40, test_ints, test_ints + THREE_REG message462, mulu, $s7, $a0, $a3, 8, 8, test_ints, test_ints + THREE_REG message463, mulu, $a6, $s7, $s5, 36, 4, test_ints, test_ints + THREE_REG message464, mulu, $s7, $a4, $a1, 24, 44, test_ints, test_ints + THREE_REG message465, mulu, $a0, $a2, $s0, 32, 20, test_ints, test_ints + THREE_REG message466, mulu, $a6, $a0, $a5, 8, 32, test_ints, test_ints + THREE_REG message467, mulu, $a3, $s6, $a5, 36, 28, test_ints, test_ints + THREE_REG message468, mulu, $t0, $s4, $s7, 12, 40, test_ints, test_ints + THREE_REG message469, mulu, $a1, $t1, $s1, 28, 24, test_ints, test_ints + THREE_REG message470, mulu, $a3, $s6, $s2, 32, 20, test_ints, test_ints + THREE_REG message471, mulu, $a6, $t0, $a3, 8, 4, test_ints, test_ints + THREE_REG message472, mulu, $s4, $s5, $a5, 8, 44, test_ints, test_ints + THREE_REG message473, mulu, $s2, $s5, $a6, 28, 8, test_ints, test_ints + THREE_REG message474, mulu, $a1, $a3, $a2, 4, 40, test_ints, test_ints + THREE_REG message475, mulu, $t0, $s2, $s4, 40, 20, test_ints, test_ints + THREE_REG message476, mulu, $t2, $a1, $a4, 4, 20, test_ints, test_ints + THREE_REG message477, mulu, $t1, $a7, $s6, 0, 36, test_ints, test_ints + THREE_REG message478, mulu, $a7, $a4, $a6, 0, 24, test_ints, test_ints + THREE_REG message479, mulu, $a6, $s6, $t0, 32, 24, test_ints, test_ints + THREE_REG message480, mulu, $t2, $s5, $a5, 36, 24, test_ints, test_ints + +# sub + THREE_REG message481, sub, $s4, $s1, $a5, 16, 28, test_ints, test_ints + THREE_REG message482, sub, $s6, $a6, $a0, 8, 12, test_ints, test_ints + THREE_REG message483, sub, $a6, $a7, $a6, 16, 12, test_ints, test_ints + THREE_REG message484, sub, $a0, $t3, $a4, 8, 12, test_ints, test_ints + THREE_REG message485, sub, $t2, $s4, $t2, 40, 0, test_ints, test_ints + THREE_REG message486, sub, $a0, $a5, $a2, 4, 8, test_ints, test_ints + THREE_REG message487, sub, $a4, $a1, $t3, 36, 4, test_ints, test_ints + THREE_REG message488, sub, $t3, $s0, $t0, 44, 24, test_ints, test_ints + THREE_REG message489, sub, $s7, $t1, $s2, 24, 4, test_ints, test_ints + THREE_REG message490, sub, $s1, $a2, $s0, 4, 0, test_ints, test_ints + THREE_REG message491, sub, $s4, $t0, $s5, 40, 40, test_ints, test_ints + THREE_REG message492, sub, $s1, $s6, $t3, 12, 44, test_ints, test_ints + THREE_REG message493, sub, $t1, $a0, $a5, 4, 20, test_ints, test_ints + THREE_REG message494, sub, $s6, $s0, $s1, 8, 28, test_ints, test_ints + THREE_REG message495, sub, $a0, $a6, $a5, 40, 16, test_ints, test_ints + THREE_REG message496, sub, $a6, $s3, $a2, 44, 36, test_ints, test_ints + THREE_REG message497, sub, $s2, $s3, $a5, 44, 20, test_ints, test_ints + THREE_REG message498, sub, $t3, $t1, $a7, 28, 0, test_ints, test_ints + THREE_REG message499, sub, $s2, $t0, $a0, 28, 36, test_ints, test_ints + THREE_REG message500, sub, $a2, $s2, $s5, 44, 32, test_ints, test_ints + THREE_REG message501, sub, $a1, $s7, $s2, 24, 20, test_ints, test_ints + THREE_REG message502, sub, $s2, $t0, $s1, 0, 12, test_ints, test_ints + THREE_REG message503, sub, $s2, $s7, $s6, 28, 24, test_ints, test_ints + THREE_REG message504, sub, $t3, $s6, $a7, 40, 20, test_ints, test_ints + THREE_REG message505, sub, $s0, $s1, $a2, 0, 32, test_ints, test_ints + THREE_REG message506, sub, $a7, $a2, $t2, 20, 24, test_ints, test_ints + THREE_REG message507, sub, $s3, $a6, $s5, 36, 32, test_ints, test_ints + THREE_REG message508, sub, $s3, $a4, $s4, 32, 0, test_ints, test_ints + THREE_REG message509, sub, $s0, $a2, $a3, 24, 20, test_ints, test_ints + THREE_REG message510, sub, $a6, $s6, $s7, 36, 32, test_ints, test_ints + THREE_REG message511, sub, $a1, $s5, $a1, 28, 40, test_ints, test_ints + THREE_REG message512, sub, $s2, $a2, $t0, 32, 12, test_ints, test_ints + THREE_REG message513, sub, $s6, $s3, $s5, 32, 36, test_ints, test_ints + THREE_REG message514, sub, $s1, $s3, $s1, 8, 44, test_ints, test_ints + THREE_REG message515, sub, $s1, $a2, $a5, 36, 32, test_ints, test_ints + THREE_REG message517, sub, $a3, $a2, $s2, 32, 4, test_ints, test_ints + THREE_REG message518, sub, $t0, $a6, $a0, 32, 12, test_ints, test_ints + THREE_REG message519, sub, $a7, $t3, $t2, 20, 28, test_ints, test_ints + THREE_REG message520, sub, $a3, $a2, $a2, 32, 16, test_ints, test_ints + +# subu[32] + THREE_REG message521, subu[32], $a5, $a6, $s2, 40, 28, test_ints, test_ints + THREE_REG message522, subu[32], $a7, $s0, $a2, 36, 36, test_ints, test_ints + THREE_REG message523, subu[32], $t2, $a4, $a4, 16, 36, test_ints, test_ints + THREE_REG message524, subu[32], $a1, $t0, $t3, 4, 4, test_ints, test_ints + THREE_REG message525, subu[32], $t2, $s5, $s4, 4, 40, test_ints, test_ints + THREE_REG message526, subu[32], $a3, $s4, $a0, 20, 4, test_ints, test_ints + THREE_REG message527, subu[32], $s1, $a2, $a3, 28, 32, test_ints, test_ints + THREE_REG message528, subu[32], $s6, $t2, $a4, 32, 0, test_ints, test_ints + THREE_REG message529, subu[32], $t1, $a6, $s4, 4, 12, test_ints, test_ints + THREE_REG message530, subu[32], $a5, $s7, $a3, 36, 0, test_ints, test_ints + THREE_REG message531, subu[32], $a4, $s7, $s5, 16, 0, test_ints, test_ints + THREE_REG message532, subu[32], $s3, $s3, $t1, 16, 0, test_ints, test_ints + THREE_REG message533, subu[32], $a6, $s5, $t2, 4, 16, test_ints, test_ints + THREE_REG message534, subu[32], $s6, $a7, $s7, 8, 28, test_ints, test_ints + THREE_REG message535, subu[32], $s7, $s0, $s5, 12, 36, test_ints, test_ints + THREE_REG message536, subu[32], $s4, $a5, $t0, 0, 40, test_ints, test_ints + THREE_REG message537, subu[32], $t1, $s4, $a1, 8, 20, test_ints, test_ints + THREE_REG message538, subu[32], $a6, $a6, $s4, 12, 24, test_ints, test_ints + THREE_REG message539, subu[32], $a1, $a1, $s7, 28, 24, test_ints, test_ints + THREE_REG message540, subu[32], $s3, $a6, $s1, 40, 0, test_ints, test_ints + THREE_REG message541, subu[32], $t0, $a1, $t0, 4, 36, test_ints, test_ints + THREE_REG message542, subu[32], $t2, $a2, $t2, 40, 40, test_ints, test_ints + THREE_REG message543, subu[32], $a4, $a3, $a2, 36, 40, test_ints, test_ints + THREE_REG message544, subu[32], $s7, $s3, $a4, 0, 8, test_ints, test_ints + THREE_REG message545, subu[32], $a6, $s5, $a7, 4, 16, test_ints, test_ints + THREE_REG message546, subu[32], $s1, $a4, $s2, 40, 12, test_ints, test_ints + THREE_REG message547, subu[32], $t3, $a6, $a4, 28, 16, test_ints, test_ints + THREE_REG message548, subu[32], $t1, $a5, $s2, 28, 32, test_ints, test_ints + THREE_REG message549, subu[32], $a0, $t3, $a7, 8, 20, test_ints, test_ints + THREE_REG message550, subu[32], $t1, $a2, $s0, 36, 8, test_ints, test_ints + THREE_REG message551, subu[32], $s7, $t3, $s7, 24, 0, test_ints, test_ints + THREE_REG message552, subu[32], $s3, $t0, $t1, 24, 40, test_ints, test_ints + THREE_REG message553, subu[32], $s0, $s5, $a5, 32, 32, test_ints, test_ints + THREE_REG message554, subu[32], $a1, $a2, $s2, 12, 4, test_ints, test_ints + THREE_REG message555, subu[32], $a2, $a3, $s1, 4, 20, test_ints, test_ints + THREE_REG message556, subu[32], $a6, $s3, $t3, 8, 32, test_ints, test_ints + THREE_REG message557, subu[32], $s5, $a1, $a4, 16, 0, test_ints, test_ints + THREE_REG message558, subu[32], $t0, $s4, $a4, 4, 40, test_ints, test_ints + THREE_REG message559, subu[32], $s2, $a5, $s3, 28, 40, test_ints, test_ints + THREE_REG message560, subu[32], $a3, $a0, $s4, 20, 44, test_ints, test_ints + +# subu[16] + THREE_REG message561, subu[16], $a1, $a3, $a2, 40, 36, test_ints, test_ints + THREE_REG message562, subu[16], $a0, $s0, $s0, 44, 12, test_ints, test_ints + THREE_REG message563, subu[16], $a0, $s1, $a0, 0, 4, test_ints, test_ints + THREE_REG message564, subu[16], $a0, $a1, $s1, 32, 40, test_ints, test_ints + THREE_REG message565, subu[16], $a3, $a3, $s0, 24, 24, test_ints, test_ints + THREE_REG message566, subu[16], $a2, $a2, $a3, 40, 44, test_ints, test_ints + THREE_REG message567, subu[16], $s2, $a3, $s3, 36, 40, test_ints, test_ints + THREE_REG message568, subu[16], $a0, $a1, $a2, 32, 16, test_ints, test_ints + THREE_REG message569, subu[16], $s1, $s0, $s1, 8, 20, test_ints, test_ints + THREE_REG message570, subu[16], $s3, $s2, $s2, 16, 44, test_ints, test_ints + THREE_REG message571, subu[16], $a0, $a0, $s2, 0, 24, test_ints, test_ints + THREE_REG message572, subu[16], $s0, $s2, $a0, 44, 0, test_ints, test_ints + THREE_REG message573, subu[16], $s0, $s2, $s0, 12, 28, test_ints, test_ints + THREE_REG message574, subu[16], $a2, $a3, $a0, 0, 44, test_ints, test_ints + THREE_REG message575, subu[16], $a0, $a2, $a3, 8, 0, test_ints, test_ints + THREE_REG message576, subu[16], $a0, $s1, $s2, 24, 36, test_ints, test_ints + THREE_REG message577, subu[16], $a1, $s3, $a1, 44, 28, test_ints, test_ints + THREE_REG message578, subu[16], $a0, $s0, $a2, 0, 44, test_ints, test_ints + THREE_REG message579, subu[16], $a2, $s0, $a1, 24, 28, test_ints, test_ints + THREE_REG message580, subu[16], $a0, $a0, $a2, 16, 4, test_ints, test_ints + THREE_REG message581, subu[16], $a1, $a1, $s3, 20, 44, test_ints, test_ints + THREE_REG message582, subu[16], $s3, $s1, $s0, 20, 16, test_ints, test_ints + THREE_REG message583, subu[16], $s1, $s3, $a3, 28, 40, test_ints, test_ints + THREE_REG message584, subu[16], $s2, $s3, $a2, 32, 28, test_ints, test_ints + THREE_REG message585, subu[16], $s2, $a3, $s0, 28, 36, test_ints, test_ints + THREE_REG message586, subu[16], $a3, $a0, $a2, 8, 16, test_ints, test_ints + THREE_REG message587, subu[16], $s3, $s3, $a1, 8, 32, test_ints, test_ints + THREE_REG message588, subu[16], $a0, $s1, $a2, 32, 8, test_ints, test_ints + THREE_REG message589, subu[16], $s2, $a2, $a1, 36, 4, test_ints, test_ints + THREE_REG message590, subu[16], $a0, $s3, $a0, 24, 16, test_ints, test_ints + THREE_REG message591, subu[16], $s3, $a0, $a3, 28, 16, test_ints, test_ints + THREE_REG message592, subu[16], $s0, $s3, $a0, 24, 4, test_ints, test_ints + THREE_REG message593, subu[16], $a0, $s1, $s0, 24, 12, test_ints, test_ints + THREE_REG message594, subu[16], $a1, $a2, $a0, 12, 28, test_ints, test_ints + THREE_REG message595, subu[16], $a3, $a1, $a1, 16, 8, test_ints, test_ints + THREE_REG message596, subu[16], $a2, $s0, $a1, 8, 44, test_ints, test_ints + THREE_REG message597, subu[16], $a1, $a1, $s3, 0, 20, test_ints, test_ints + THREE_REG message598, subu[16], $s3, $a1, $s0, 44, 28, test_ints, test_ints + THREE_REG message599, subu[16], $a1, $a0, $s1, 36, 8, test_ints, test_ints + THREE_REG message600, subu[16], $a0, $s2, $s0, 4, 4, test_ints, test_ints + +# addiu[32] + TWO_REG_1_IMM message601, addiu[32], $a3, $a0, 24, test_ints, 7140 + TWO_REG_1_IMM message602, addiu[32], $a4, $a4, 40, test_ints, 49885 + TWO_REG_1_IMM message603, addiu[32], $a6, $a0, 16, test_ints, 1959 + TWO_REG_1_IMM message604, addiu[32], $a6, $a7, 0, test_ints, 45791 + TWO_REG_1_IMM message605, addiu[32], $s3, $a5, 12, test_ints, 19034 + TWO_REG_1_IMM message606, addiu[32], $s0, $a4, 40, test_ints, 12529 + TWO_REG_1_IMM message607, addiu[32], $a5, $a4, 8, test_ints, 40680 + TWO_REG_1_IMM message608, addiu[32], $t1, $s3, 4, test_ints, 828 + TWO_REG_1_IMM message609, addiu[32], $a3, $a0, 20, test_ints, 20951 + TWO_REG_1_IMM message610, addiu[32], $t0, $a3, 16, test_ints, 55726 + TWO_REG_1_IMM message611, addiu[32], $a4, $s0, 8, test_ints, 53562 + TWO_REG_1_IMM message612, addiu[32], $s0, $s6, 20, test_ints, 42143 + TWO_REG_1_IMM message613, addiu[32], $s3, $s0, 4, test_ints, 16555 + TWO_REG_1_IMM message614, addiu[32], $a4, $a0, 20, test_ints, 24593 + TWO_REG_1_IMM message615, addiu[32], $t0, $s7, 36, test_ints, 44457 + TWO_REG_1_IMM message616, addiu[32], $a6, $s7, 8, test_ints, 61417 + TWO_REG_1_IMM message617, addiu[32], $a7, $s3, 0, test_ints, 62551 + TWO_REG_1_IMM message618, addiu[32], $a6, $s5, 40, test_ints, 24670 + TWO_REG_1_IMM message619, addiu[32], $a1, $a4, 16, test_ints, 41561 + TWO_REG_1_IMM message620, addiu[32], $s2, $s5, 32, test_ints, 39341 + TWO_REG_1_IMM message621, addiu[32], $s5, $a2, 16, test_ints, 36181 + TWO_REG_1_IMM message622, addiu[32], $s6, $s5, 12, test_ints, 36862 + TWO_REG_1_IMM message623, addiu[32], $s0, $s0, 0, test_ints, 21558 + TWO_REG_1_IMM message624, addiu[32], $a3, $s2, 28, test_ints, 28810 + TWO_REG_1_IMM message625, addiu[32], $s5, $s0, 24, test_ints, 42131 + TWO_REG_1_IMM message626, addiu[32], $s5, $s0, 40, test_ints, 57450 + TWO_REG_1_IMM message627, addiu[32], $a4, $t2, 0, test_ints, 20082 + TWO_REG_1_IMM message628, addiu[32], $s4, $a0, 44, test_ints, 17217 + TWO_REG_1_IMM message629, addiu[32], $s6, $s7, 44, test_ints, 11556 + TWO_REG_1_IMM message630, addiu[32], $a1, $t2, 12, test_ints, 54065 + +# addiu[48] + ONE_REG_1_IMM message631, addiu[48], $a6, 28, test_ints, -465671856 + ONE_REG_1_IMM message632, addiu[48], $a7, 32, test_ints, 1143693630 + ONE_REG_1_IMM message633, addiu[48], $t1, 16, test_ints, 1561085778 + ONE_REG_1_IMM message634, addiu[48], $t2, 8, test_ints, -617608244 + ONE_REG_1_IMM message635, addiu[48], $a7, 44, test_ints, 1288814930 + ONE_REG_1_IMM message636, addiu[48], $t2, 8, test_ints, -1256568320 + ONE_REG_1_IMM message637, addiu[48], $a5, 12, test_ints, 236779048 + ONE_REG_1_IMM message638, addiu[48], $a5, 20, test_ints, -42931667 + ONE_REG_1_IMM message639, addiu[48], $a0, 4, test_ints, 1928300342 + ONE_REG_1_IMM message640, addiu[48], $s4, 36, test_ints, -1529565618 + ONE_REG_1_IMM message641, addiu[48], $a4, 8, test_ints, -500125624 + ONE_REG_1_IMM message642, addiu[48], $a0, 24, test_ints, 850131496 + ONE_REG_1_IMM message643, addiu[48], $s0, 36, test_ints, -587248398 + ONE_REG_1_IMM message644, addiu[48], $s7, 24, test_ints, -921250080 + ONE_REG_1_IMM message645, addiu[48], $a4, 32, test_ints, -1791276953 + ONE_REG_1_IMM message646, addiu[48], $s7, 36, test_ints, 1476... [truncated message content] |
|
From: Julian S. <js...@ac...> - 2020-01-02 13:30:12
|
I landed a fix, O2a7d3ae768f9e5b29acd5cb743c3fb13640a391c. It all seems a bit dubious to me, but given that the resulting code actually works, I don't see that we have much option here. J |
|
From: Julian S. <se...@so...> - 2020-01-02 13:27:58
|
https://sourceware.org/git/gitweb.cgi?p=valgrind.git;h=2a7d3ae768f9e5b29acd5cb743c3fb13640a391c commit 2a7d3ae768f9e5b29acd5cb743c3fb13640a391c Author: Julian Seward <js...@ac...> Date: Thu Jan 2 14:27:24 2020 +0100 sys_statx: don't complain if both |filename| and |buf| are NULL. So as to work around the Rust library's dubious use of statx. Diff: --- coregrind/m_syswrap/syswrap-linux.c | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/coregrind/m_syswrap/syswrap-linux.c b/coregrind/m_syswrap/syswrap-linux.c index 87c513a..96c309e 100644 --- a/coregrind/m_syswrap/syswrap-linux.c +++ b/coregrind/m_syswrap/syswrap-linux.c @@ -3692,10 +3692,19 @@ PRE(sys_statx) PRINT("sys_statx ( %ld, %#" FMT_REGWORD "x(%s), %ld, %ld, %#" FMT_REGWORD "x )", (Word)ARG1,ARG2,(char*)(Addr)ARG2,(Word)ARG3,(Word)ARG4,ARG5); PRE_REG_READ5(long, "statx", - int, dirfd, char *, file_name, int, flags, + int, dirfd, char *, filename, int, flags, unsigned int, mask, struct statx *, buf); - PRE_MEM_RASCIIZ( "statx(file_name)", ARG2 ); - PRE_MEM_WRITE( "statx(buf)", ARG5, sizeof(struct vki_statx) ); + // Work around Rust's dubious use of statx, as described here: + // https://github.com/rust-lang/rust/blob/ + // ccd238309f9dce92a05a23c2959e2819668c69a4/ + // src/libstd/sys/unix/fs.rs#L128-L142 + // in which it passes NULL for both filename and buf, and then looks at the + // return value, so as to determine whether or not this syscall is supported. + Bool both_filename_and_buf_are_null = ARG2 == 0 && ARG5 == 0; + if (!both_filename_and_buf_are_null) { + PRE_MEM_RASCIIZ( "statx(filename)", ARG2 ); + PRE_MEM_WRITE( "statx(buf)", ARG5, sizeof(struct vki_statx) ); + } } POST(sys_statx) { |
|
From: Tom H. <to...@co...> - 2020-01-02 11:01:41
|
On 02/01/2020 09:48, Julian Seward wrote: > Ryan, I am seeing this problem also when running Gecko now, as compiled > with rustc 1.40. > >> `statx` is a relatively new system call, only appearing in Linux 4.11. >> Rust uses a trick where it calls `statx` with two NULL pointers to see >> if the kernel/glibc support it because it's faster than calling it with >> a real filename. If it returns `EFAULT` the system call is supported, >> otherwise it returns `ENOSYS`. The comments in the Rust source code >> imply this is a known trick. > > Can you point me at the comments in the Rust source code? I read the man > page for statx pretty carefully, and saw nothing there implying that NULL > is an acceptable value for the |filename| argument. I also didn't see > anything like that in the kernel sources (but I could easily have missed > it, it's a twisty maze in there). Well it sounds like it's relying on side effects of the implementation. No doubt the kernel will try to call copy_from_user or something similar on the filename argument and that will trigger EFAULT if the address is not a valid address in the processes address space, which NULL won't be. So EFAULT means the system call is implemented as the kernel has tried to access the filename, and ENOSYS means it isn't implemented. You could do much the same thing with any system call that takes a user space address as an argument. Tom -- Tom Hughes (to...@co...) http://compton.nu/ |
|
From: Julian S. <js...@ac...> - 2020-01-02 09:48:48
|
Ryan, I am seeing this problem also when running Gecko now, as compiled with rustc 1.40. > `statx` is a relatively new system call, only appearing in Linux 4.11. > Rust uses a trick where it calls `statx` with two NULL pointers to see > if the kernel/glibc support it because it's faster than calling it with > a real filename. If it returns `EFAULT` the system call is supported, > otherwise it returns `ENOSYS`. The comments in the Rust source code > imply this is a known trick. Can you point me at the comments in the Rust source code? I read the man page for statx pretty carefully, and saw nothing there implying that NULL is an acceptable value for the |filename| argument. I also didn't see anything like that in the kernel sources (but I could easily have missed it, it's a twisty maze in there). J |
|
From: Julian S. <se...@so...> - 2020-01-02 08:35:10
|
https://sourceware.org/git/gitweb.cgi?p=valgrind.git;h=cadd90993504678607a4f95dfe5d1df5207c1eb0 commit cadd90993504678607a4f95dfe5d1df5207c1eb0 Author: Julian Seward <js...@ac...> Date: Thu Jan 2 09:32:19 2020 +0100 amd64 insn selector: improved handling of Or1/And1 trees. This splits function iselCondCode into iselCondCode_C and iselCondCode_R, the former of which is the old one that computes boolean expressions into an amd64 condition code, but the latter being new, and computes boolean expressions into the lowest bit of an integer register. This enables much better code generation for Or1/And1 trees, which now result quite commonly from the new &&-recovery machinery in the front end. Diff: --- VEX/priv/host_amd64_isel.c | 132 ++++++++++++++++++++++++++++++--------------- 1 file changed, 90 insertions(+), 42 deletions(-) diff --git a/VEX/priv/host_amd64_isel.c b/VEX/priv/host_amd64_isel.c index 6b70e54..c3cd61c 100644 --- a/VEX/priv/host_amd64_isel.c +++ b/VEX/priv/host_amd64_isel.c @@ -234,8 +234,11 @@ static void iselInt128Expr_wrk ( /*OUT*/HReg* rHi, HReg* rLo, static void iselInt128Expr ( /*OUT*/HReg* rHi, HReg* rLo, ISelEnv* env, const IRExpr* e ); -static AMD64CondCode iselCondCode_wrk ( ISelEnv* env, const IRExpr* e ); -static AMD64CondCode iselCondCode ( ISelEnv* env, const IRExpr* e ); +static AMD64CondCode iselCondCode_C_wrk ( ISelEnv* env, const IRExpr* e ); +static AMD64CondCode iselCondCode_C ( ISelEnv* env, const IRExpr* e ); + +static HReg iselCondCode_R_wrk ( ISelEnv* env, const IRExpr* e ); +static HReg iselCondCode_R ( ISelEnv* env, const IRExpr* e ); static HReg iselDblExpr_wrk ( ISelEnv* env, const IRExpr* e ); static HReg iselDblExpr ( ISelEnv* env, const IRExpr* e ); @@ -649,7 +652,7 @@ void doHelperCall ( /*OUT*/UInt* stackAdjustAfterCall, && guard->Iex.Const.con->Ico.U1 == True) { /* unconditional -- do nothing */ } else { - cc = iselCondCode( env, guard ); + cc = iselCondCode_C( env, guard ); } } @@ -1611,7 +1614,7 @@ static HReg iselIntExpr_R_wrk ( ISelEnv* env, const IRExpr* e ) case Iop_1Uto32: case Iop_1Uto8: { HReg dst = newVRegI(env); - AMD64CondCode cond = iselCondCode(env, e->Iex.Unop.arg); + AMD64CondCode cond = iselCondCode_C(env, e->Iex.Unop.arg); addInstr(env, AMD64Instr_Set64(cond,dst)); return dst; } @@ -1619,10 +1622,9 @@ static HReg iselIntExpr_R_wrk ( ISelEnv* env, const IRExpr* e ) case Iop_1Sto16: case Iop_1Sto32: case Iop_1Sto64: { - /* could do better than this, but for now ... */ - HReg dst = newVRegI(env); - AMD64CondCode cond = iselCondCode(env, e->Iex.Unop.arg); - addInstr(env, AMD64Instr_Set64(cond,dst)); + HReg dst = newVRegI(env); + HReg tmp = iselCondCode_R(env, e->Iex.Unop.arg); + addInstr(env, mk_iMOVsd_RR(tmp, dst)); addInstr(env, AMD64Instr_Sh64(Ash_SHL, 63, dst)); addInstr(env, AMD64Instr_Sh64(Ash_SAR, 63, dst)); return dst; @@ -1955,7 +1957,7 @@ static HReg iselIntExpr_R_wrk ( ISelEnv* env, const IRExpr* e ) HReg r0 = iselIntExpr_R(env, e->Iex.ITE.iffalse); HReg dst = newVRegI(env); addInstr(env, mk_iMOVsd_RR(r1,dst)); - AMD64CondCode cc = iselCondCode(env, e->Iex.ITE.cond); + AMD64CondCode cc = iselCondCode_C(env, e->Iex.ITE.cond); addInstr(env, AMD64Instr_CMov64(cc ^ 1, r0, dst)); return dst; } @@ -2281,20 +2283,24 @@ static AMD64RM* iselIntExpr_RM_wrk ( ISelEnv* env, const IRExpr* e ) } -/* --------------------- CONDCODE --------------------- */ +/* --------------------- CONDCODE as %rflag test --------------------- */ /* Generate code to evaluated a bit-typed expression, returning the condition code which would correspond when the expression would - notionally have returned 1. */ + notionally have returned 1. -static AMD64CondCode iselCondCode ( ISelEnv* env, const IRExpr* e ) + Note that iselCondCode_C and iselCondCode_R are mutually recursive. For + future changes to either of them, take care not to introduce an infinite + loop involving the two of them. +*/ +static AMD64CondCode iselCondCode_C ( ISelEnv* env, const IRExpr* e ) { /* Uh, there's nothing we can sanity check here, unfortunately. */ - return iselCondCode_wrk(env,e); + return iselCondCode_C_wrk(env,e); } /* DO NOT CALL THIS DIRECTLY ! */ -static AMD64CondCode iselCondCode_wrk ( ISelEnv* env, const IRExpr* e ) +static AMD64CondCode iselCondCode_C_wrk ( ISelEnv* env, const IRExpr* e ) { vassert(e); vassert(typeOfIRExpr(env->type_env,e) == Ity_I1); @@ -2321,7 +2327,7 @@ static AMD64CondCode iselCondCode_wrk ( ISelEnv* env, const IRExpr* e ) /* Not1(...) */ if (e->tag == Iex_Unop && e->Iex.Unop.op == Iop_Not1) { /* Generate code for the arg, and negate the test condition */ - return 1 ^ iselCondCode(env, e->Iex.Unop.arg); + return 1 ^ iselCondCode_C(env, e->Iex.Unop.arg); } /* --- patterns rooted at: 64to1 --- */ @@ -2428,7 +2434,7 @@ static AMD64CondCode iselCondCode_wrk ( ISelEnv* env, const IRExpr* e ) switch (e->Iex.Binop.op) { case Iop_CmpEQ8: case Iop_CasCmpEQ8: return Acc_Z; case Iop_CmpNE8: case Iop_CasCmpNE8: return Acc_NZ; - default: vpanic("iselCondCode(amd64): CmpXX8(expr,0:I8)"); + default: vpanic("iselCondCode_C(amd64): CmpXX8(expr,0:I8)"); } } else { HReg r1 = iselIntExpr_R(env, e->Iex.Binop.arg1); @@ -2440,7 +2446,7 @@ static AMD64CondCode iselCondCode_wrk ( ISelEnv* env, const IRExpr* e ) switch (e->Iex.Binop.op) { case Iop_CmpEQ8: case Iop_CasCmpEQ8: return Acc_Z; case Iop_CmpNE8: case Iop_CasCmpNE8: return Acc_NZ; - default: vpanic("iselCondCode(amd64): CmpXX8(expr,expr)"); + default: vpanic("iselCondCode_C(amd64): CmpXX8(expr,expr)"); } } } @@ -2460,7 +2466,7 @@ static AMD64CondCode iselCondCode_wrk ( ISelEnv* env, const IRExpr* e ) switch (e->Iex.Binop.op) { case Iop_CmpEQ16: case Iop_CasCmpEQ16: return Acc_Z; case Iop_CmpNE16: case Iop_CasCmpNE16: return Acc_NZ; - default: vpanic("iselCondCode(amd64): CmpXX16"); + default: vpanic("iselCondCode_C(amd64): CmpXX16"); } } @@ -2514,7 +2520,7 @@ static AMD64CondCode iselCondCode_wrk ( ISelEnv* env, const IRExpr* e ) case Iop_CmpLT64U: return Acc_B; case Iop_CmpLE64S: return Acc_LE; case Iop_CmpLE64U: return Acc_BE; - default: vpanic("iselCondCode(amd64): CmpXX64"); + default: vpanic("iselCondCode_C(amd64): CmpXX64"); } } @@ -2540,31 +2546,73 @@ static AMD64CondCode iselCondCode_wrk ( ISelEnv* env, const IRExpr* e ) case Iop_CmpLT32U: return Acc_B; case Iop_CmpLE32S: return Acc_LE; case Iop_CmpLE32U: return Acc_BE; - default: vpanic("iselCondCode(amd64): CmpXX32"); + default: vpanic("iselCondCode_C(amd64): CmpXX32"); } } /* And1(x,y), Or1(x,y) */ - /* FIXME: We could (and probably should) do a lot better here. If both args - are in temps already then we can just emit a reg-reg And/Or directly, - followed by the final Test. */ if (e->tag == Iex_Binop && (e->Iex.Binop.op == Iop_And1 || e->Iex.Binop.op == Iop_Or1)) { - // We could probably be cleverer about this. In the meantime .. - HReg x_as_64 = newVRegI(env); - AMD64CondCode cc_x = iselCondCode(env, e->Iex.Binop.arg1); - addInstr(env, AMD64Instr_Set64(cc_x, x_as_64)); - HReg y_as_64 = newVRegI(env); - AMD64CondCode cc_y = iselCondCode(env, e->Iex.Binop.arg2); - addInstr(env, AMD64Instr_Set64(cc_y, y_as_64)); - AMD64AluOp aop = e->Iex.Binop.op == Iop_And1 ? Aalu_AND : Aalu_OR; - addInstr(env, AMD64Instr_Alu64R(aop, AMD64RMI_Reg(x_as_64), y_as_64)); - addInstr(env, AMD64Instr_Test64(1, y_as_64)); + // Get the result in an int reg, then test the least significant bit. + HReg tmp = iselCondCode_R(env, e); + addInstr(env, AMD64Instr_Test64(1, tmp)); return Acc_NZ; } ppIRExpr(e); - vpanic("iselCondCode(amd64)"); + vpanic("iselCondCode_C(amd64)"); +} + + +/* --------------------- CONDCODE as int reg --------------------- */ + +/* Generate code to evaluated a bit-typed expression, returning the resulting + value in bit 0 of an integer register. WARNING: all of the other bits in the + register can be arbitrary. Callers must mask them off or otherwise ignore + them, as necessary. + + Note that iselCondCode_C and iselCondCode_R are mutually recursive. For + future changes to either of them, take care not to introduce an infinite + loop involving the two of them. +*/ +static HReg iselCondCode_R ( ISelEnv* env, const IRExpr* e ) +{ + /* Uh, there's nothing we can sanity check here, unfortunately. */ + return iselCondCode_R_wrk(env,e); +} + +/* DO NOT CALL THIS DIRECTLY ! */ +static HReg iselCondCode_R_wrk ( ISelEnv* env, const IRExpr* e ) +{ + vassert(e); + vassert(typeOfIRExpr(env->type_env,e) == Ity_I1); + + /* var */ + if (e->tag == Iex_RdTmp) { + return lookupIRTemp(env, e->Iex.RdTmp.tmp); + } + + /* And1(x,y), Or1(x,y) */ + if (e->tag == Iex_Binop + && (e->Iex.Binop.op == Iop_And1 || e->Iex.Binop.op == Iop_Or1)) { + HReg x_as_64 = iselCondCode_R(env, e->Iex.Binop.arg1); + HReg y_as_64 = iselCondCode_R(env, e->Iex.Binop.arg2); + HReg res = newVRegI(env); + addInstr(env, mk_iMOVsd_RR(y_as_64, res)); + AMD64AluOp aop = e->Iex.Binop.op == Iop_And1 ? Aalu_AND : Aalu_OR; + addInstr(env, AMD64Instr_Alu64R(aop, AMD64RMI_Reg(x_as_64), res)); + return res; + } + + /* Anything else, we hand off to iselCondCode_C and force the value into a + register. */ + HReg res = newVRegI(env); + AMD64CondCode cc = iselCondCode_C(env, e); + addInstr(env, AMD64Instr_Set64(cc, res)); + return res; + + ppIRExpr(e); + vpanic("iselCondCode_R(amd64)"); } @@ -2833,7 +2881,7 @@ static HReg iselFltExpr_wrk ( ISelEnv* env, const IRExpr* e ) r0 = iselFltExpr(env, e->Iex.ITE.iffalse); dst = newVRegV(env); addInstr(env, mk_vMOVsd_RR(r1,dst)); - AMD64CondCode cc = iselCondCode(env, e->Iex.ITE.cond); + AMD64CondCode cc = iselCondCode_C(env, e->Iex.ITE.cond); addInstr(env, AMD64Instr_SseCMov(cc ^ 1, r0, dst)); return dst; } @@ -3224,7 +3272,7 @@ static HReg iselDblExpr_wrk ( ISelEnv* env, const IRExpr* e ) r0 = iselDblExpr(env, e->Iex.ITE.iffalse); dst = newVRegV(env); addInstr(env, mk_vMOVsd_RR(r1,dst)); - AMD64CondCode cc = iselCondCode(env, e->Iex.ITE.cond); + AMD64CondCode cc = iselCondCode_C(env, e->Iex.ITE.cond); addInstr(env, AMD64Instr_SseCMov(cc ^ 1, r0, dst)); return dst; } @@ -3927,7 +3975,7 @@ static HReg iselVecExpr_wrk ( ISelEnv* env, const IRExpr* e ) HReg r0 = iselVecExpr(env, e->Iex.ITE.iffalse); HReg dst = newVRegV(env); addInstr(env, mk_vMOVsd_RR(r1,dst)); - AMD64CondCode cc = iselCondCode(env, e->Iex.ITE.cond); + AMD64CondCode cc = iselCondCode_C(env, e->Iex.ITE.cond); addInstr(env, AMD64Instr_SseCMov(cc ^ 1, r0, dst)); return dst; } @@ -4567,7 +4615,7 @@ static void iselDVecExpr_wrk ( /*OUT*/HReg* rHi, /*OUT*/HReg* rLo, HReg dstLo = newVRegV(env); addInstr(env, mk_vMOVsd_RR(r1Hi,dstHi)); addInstr(env, mk_vMOVsd_RR(r1Lo,dstLo)); - AMD64CondCode cc = iselCondCode(env, e->Iex.ITE.cond); + AMD64CondCode cc = iselCondCode_C(env, e->Iex.ITE.cond); addInstr(env, AMD64Instr_SseCMov(cc ^ 1, r0Hi, dstHi)); addInstr(env, AMD64Instr_SseCMov(cc ^ 1, r0Lo, dstLo)); *rHi = dstHi; @@ -4628,7 +4676,7 @@ static void iselStmt ( ISelEnv* env, IRStmt* stmt ) } else { addInstr(env, mk_iMOVsd_RR(rAlt, rDst)); } - AMD64CondCode cc = iselCondCode(env, lg->guard); + AMD64CondCode cc = iselCondCode_C(env, lg->guard); if (szB == 16) { addInstr(env, AMD64Instr_SseCLoad(cc, amAddr, rDst)); } else { @@ -4659,7 +4707,7 @@ static void iselStmt ( ISelEnv* env, IRStmt* stmt ) = szB == 16 ? iselVecExpr(env, sg->data) : iselIntExpr_R(env, sg->data); AMD64CondCode cc - = iselCondCode(env, sg->guard); + = iselCondCode_C(env, sg->guard); if (szB == 16) { addInstr(env, AMD64Instr_SseCStore(cc, rSrc, amAddr)); } else { @@ -4853,7 +4901,7 @@ static void iselStmt ( ISelEnv* env, IRStmt* stmt ) return; } if (ty == Ity_I1) { - AMD64CondCode cond = iselCondCode(env, stmt->Ist.WrTmp.data); + AMD64CondCode cond = iselCondCode_C(env, stmt->Ist.WrTmp.data); HReg dst = lookupIRTemp(env, tmp); addInstr(env, AMD64Instr_Set64(cond, dst)); return; @@ -5069,7 +5117,7 @@ static void iselStmt ( ISelEnv* env, IRStmt* stmt ) if (stmt->Ist.Exit.dst->tag != Ico_U64) vpanic("iselStmt(amd64): Ist_Exit: dst is not a 64-bit value"); - AMD64CondCode cc = iselCondCode(env, stmt->Ist.Exit.guard); + AMD64CondCode cc = iselCondCode_C(env, stmt->Ist.Exit.guard); AMD64AMode* amRIP = AMD64AMode_IR(stmt->Ist.Exit.offsIP, hregAMD64_RBP()); |
|
From: Julian S. <se...@so...> - 2020-01-02 08:26:29
|
https://sourceware.org/git/gitweb.cgi?p=valgrind.git;h=4eaa80103df9d1d396cc4b7427ea99faac11329d commit 4eaa80103df9d1d396cc4b7427ea99faac11329d Author: Julian Seward <js...@ac...> Date: Thu Jan 2 09:23:46 2020 +0100 amd64 back end: generate 32-bit shift instructions for 32-bit IR shifts. Until now these have been handled by possibly widening the value to 64 bits, if necessary, followed by a 64-bit shift. That wastes instructions and code space. Diff: --- VEX/priv/host_amd64_defs.c | 48 ++++++++++++++++++++++++++++++++++++++++++++++ VEX/priv/host_amd64_defs.h | 9 ++++++++- VEX/priv/host_amd64_isel.c | 30 +++++++++++++++++++---------- 3 files changed, 76 insertions(+), 11 deletions(-) diff --git a/VEX/priv/host_amd64_defs.c b/VEX/priv/host_amd64_defs.c index 29127c1..3d237e1 100644 --- a/VEX/priv/host_amd64_defs.c +++ b/VEX/priv/host_amd64_defs.c @@ -626,6 +626,14 @@ AMD64Instr* AMD64Instr_Sh64 ( AMD64ShiftOp op, UInt src, HReg dst ) { i->Ain.Sh64.dst = dst; return i; } +AMD64Instr* AMD64Instr_Sh32 ( AMD64ShiftOp op, UInt src, HReg dst ) { + AMD64Instr* i = LibVEX_Alloc_inline(sizeof(AMD64Instr)); + i->tag = Ain_Sh32; + i->Ain.Sh32.op = op; + i->Ain.Sh32.src = src; + i->Ain.Sh32.dst = dst; + return i; +} AMD64Instr* AMD64Instr_Test64 ( UInt imm32, HReg dst ) { AMD64Instr* i = LibVEX_Alloc_inline(sizeof(AMD64Instr)); i->tag = Ain_Test64; @@ -1090,6 +1098,14 @@ void ppAMD64Instr ( const AMD64Instr* i, Bool mode64 ) vex_printf("$%d,", (Int)i->Ain.Sh64.src); ppHRegAMD64(i->Ain.Sh64.dst); return; + case Ain_Sh32: + vex_printf("%sl ", showAMD64ShiftOp(i->Ain.Sh32.op)); + if (i->Ain.Sh32.src == 0) + vex_printf("%%cl,"); + else + vex_printf("$%d,", (Int)i->Ain.Sh32.src); + ppHRegAMD64_lo32(i->Ain.Sh32.dst); + return; case Ain_Test64: vex_printf("testq $%d,", (Int)i->Ain.Test64.imm32); ppHRegAMD64(i->Ain.Test64.dst); @@ -1471,6 +1487,11 @@ void getRegUsage_AMD64Instr ( HRegUsage* u, const AMD64Instr* i, Bool mode64 ) if (i->Ain.Sh64.src == 0) addHRegUse(u, HRmRead, hregAMD64_RCX()); return; + case Ain_Sh32: + addHRegUse(u, HRmModify, i->Ain.Sh32.dst); + if (i->Ain.Sh32.src == 0) + addHRegUse(u, HRmRead, hregAMD64_RCX()); + return; case Ain_Test64: addHRegUse(u, HRmRead, i->Ain.Test64.dst); return; @@ -1808,6 +1829,9 @@ void mapRegs_AMD64Instr ( HRegRemap* m, AMD64Instr* i, Bool mode64 ) case Ain_Sh64: mapReg(m, &i->Ain.Sh64.dst); return; + case Ain_Sh32: + mapReg(m, &i->Ain.Sh32.dst); + return; case Ain_Test64: mapReg(m, &i->Ain.Test64.dst); return; @@ -2762,6 +2786,30 @@ Int emit_AMD64Instr ( /*MB_MOD*/Bool* is_profInc, } break; + case Ain_Sh32: + opc_cl = opc_imm = subopc = 0; + switch (i->Ain.Sh32.op) { + case Ash_SHR: opc_cl = 0xD3; opc_imm = 0xC1; subopc = 5; break; + case Ash_SAR: opc_cl = 0xD3; opc_imm = 0xC1; subopc = 7; break; + case Ash_SHL: opc_cl = 0xD3; opc_imm = 0xC1; subopc = 4; break; + default: goto bad; + } + if (i->Ain.Sh32.src == 0) { + rex = clearWBit( rexAMode_R_enc_reg(0, i->Ain.Sh32.dst) ); + if (rex != 0x40) *p++ = rex; + *p++ = toUChar(opc_cl); + p = doAMode_R_enc_reg(p, subopc, i->Ain.Sh32.dst); + goto done; + } else { + rex = clearWBit( rexAMode_R_enc_reg(0, i->Ain.Sh32.dst) ); + if (rex != 0x40) *p++ = rex; + *p++ = toUChar(opc_imm); + p = doAMode_R_enc_reg(p, subopc, i->Ain.Sh32.dst); + *p++ = (UChar)(i->Ain.Sh32.src); + goto done; + } + break; + case Ain_Test64: /* testq sign-extend($imm32), %reg */ *p++ = rexAMode_R_enc_reg(0, i->Ain.Test64.dst); diff --git a/VEX/priv/host_amd64_defs.h b/VEX/priv/host_amd64_defs.h index 3dfa9fb..e2ed261 100644 --- a/VEX/priv/host_amd64_defs.h +++ b/VEX/priv/host_amd64_defs.h @@ -359,7 +359,8 @@ typedef Ain_Imm64, /* Generate 64-bit literal to register */ Ain_Alu64R, /* 64-bit mov/arith/logical, dst=REG */ Ain_Alu64M, /* 64-bit mov/arith/logical, dst=MEM */ - Ain_Sh64, /* 64-bit shift/rotate, dst=REG or MEM */ + Ain_Sh64, /* 64-bit shift, dst=REG */ + Ain_Sh32, /* 32-bit shift, dst=REG */ Ain_Test64, /* 64-bit test (AND, set flags, discard result) */ Ain_Unary64, /* 64-bit not and neg */ Ain_Lea64, /* 64-bit compute EA into a reg */ @@ -442,6 +443,11 @@ typedef HReg dst; } Sh64; struct { + AMD64ShiftOp op; + UInt src; /* shift amount, or 0 means %cl */ + HReg dst; + } Sh32; + struct { UInt imm32; HReg dst; } Test64; @@ -744,6 +750,7 @@ extern AMD64Instr* AMD64Instr_Unary64 ( AMD64UnaryOp op, HReg dst ); extern AMD64Instr* AMD64Instr_Lea64 ( AMD64AMode* am, HReg dst ); extern AMD64Instr* AMD64Instr_Alu32R ( AMD64AluOp, AMD64RMI*, HReg ); extern AMD64Instr* AMD64Instr_Sh64 ( AMD64ShiftOp, UInt, HReg ); +extern AMD64Instr* AMD64Instr_Sh32 ( AMD64ShiftOp, UInt, HReg ); extern AMD64Instr* AMD64Instr_Test64 ( UInt imm32, HReg dst ); extern AMD64Instr* AMD64Instr_MulL ( Bool syned, AMD64RM* ); extern AMD64Instr* AMD64Instr_Div ( Bool syned, Int sz, AMD64RM* ); diff --git a/VEX/priv/host_amd64_isel.c b/VEX/priv/host_amd64_isel.c index dfaabb4..6b70e54 100644 --- a/VEX/priv/host_amd64_isel.c +++ b/VEX/priv/host_amd64_isel.c @@ -1030,9 +1030,12 @@ static HReg iselIntExpr_R_wrk ( ISelEnv* env, const IRExpr* e ) HReg regL = iselIntExpr_R(env, e->Iex.Binop.arg1); addInstr(env, mk_iMOVsd_RR(regL,dst)); - /* Do any necessary widening for 32/16/8 bit operands */ + /* Do any necessary widening for 16/8 bit operands. Also decide on the + final width at which the shift is to be done. */ + Bool shift64 = False; switch (e->Iex.Binop.op) { case Iop_Shr64: case Iop_Shl64: case Iop_Sar64: + shift64 = True; break; case Iop_Shl32: case Iop_Shl16: case Iop_Shl8: break; @@ -1045,18 +1048,16 @@ static HReg iselIntExpr_R_wrk ( ISelEnv* env, const IRExpr* e ) Aalu_AND, AMD64RMI_Imm(0xFFFF), dst)); break; case Iop_Shr32: - addInstr(env, AMD64Instr_MovxLQ(False, dst, dst)); break; case Iop_Sar8: - addInstr(env, AMD64Instr_Sh64(Ash_SHL, 56, dst)); - addInstr(env, AMD64Instr_Sh64(Ash_SAR, 56, dst)); + addInstr(env, AMD64Instr_Sh32(Ash_SHL, 24, dst)); + addInstr(env, AMD64Instr_Sh32(Ash_SAR, 24, dst)); break; case Iop_Sar16: - addInstr(env, AMD64Instr_Sh64(Ash_SHL, 48, dst)); - addInstr(env, AMD64Instr_Sh64(Ash_SAR, 48, dst)); + addInstr(env, AMD64Instr_Sh32(Ash_SHL, 16, dst)); + addInstr(env, AMD64Instr_Sh32(Ash_SAR, 16, dst)); break; case Iop_Sar32: - addInstr(env, AMD64Instr_MovxLQ(True, dst, dst)); break; default: ppIROp(e->Iex.Binop.op); @@ -1071,14 +1072,23 @@ static HReg iselIntExpr_R_wrk ( ISelEnv* env, const IRExpr* e ) vassert(e->Iex.Binop.arg2->Iex.Const.con->tag == Ico_U8); nshift = e->Iex.Binop.arg2->Iex.Const.con->Ico.U8; vassert(nshift >= 0); - if (nshift > 0) + if (nshift > 0) { /* Can't allow nshift==0 since that means %cl */ - addInstr(env, AMD64Instr_Sh64(shOp, nshift, dst)); + if (shift64) { + addInstr(env, AMD64Instr_Sh64(shOp, nshift, dst)); + } else { + addInstr(env, AMD64Instr_Sh32(shOp, nshift, dst)); + } + } } else { /* General case; we have to force the amount into %cl. */ HReg regR = iselIntExpr_R(env, e->Iex.Binop.arg2); addInstr(env, mk_iMOVsd_RR(regR,hregAMD64_RCX())); - addInstr(env, AMD64Instr_Sh64(shOp, 0/* %cl */, dst)); + if (shift64) { + addInstr(env, AMD64Instr_Sh64(shOp, 0/* %cl */, dst)); + } else { + addInstr(env, AMD64Instr_Sh32(shOp, 0/* %cl */, dst)); + } } return dst; } |
|
From: Julian S. <se...@so...> - 2020-01-02 08:14:14
|
https://sourceware.org/git/gitweb.cgi?p=valgrind.git;h=7239439e84881aeb1788bb31e59268533e3d78ff commit 7239439e84881aeb1788bb31e59268533e3d78ff Author: Julian Seward <js...@ac...> Date: Thu Jan 2 09:10:06 2020 +0100 Enable expensive handling of CmpEQ64/CmpNE64 for amd64 by default. This has unfortunately become necessary because optimising compilers are generating 64-bit equality comparisons on partially defined values on this target. There will shortly be two followup commits which partially mitigate the resulting performance loss. Diff: --- memcheck/mc_translate.c | 1 + 1 file changed, 1 insertion(+) diff --git a/memcheck/mc_translate.c b/memcheck/mc_translate.c index bd29ea0..87b8ac6 100644 --- a/memcheck/mc_translate.c +++ b/memcheck/mc_translate.c @@ -8480,6 +8480,7 @@ IRSB* MC_(instrument) ( VgCallbackClosure* closure, # elif defined(VGA_amd64) mce.dlbo.dl_Add64 = DLauto; mce.dlbo.dl_CmpEQ32_CmpNE32 = DLexpensive; + mce.dlbo.dl_CmpEQ64_CmpNE64 = DLexpensive; # elif defined(VGA_ppc64le) // Needed by (at least) set_AV_CR6() in the front end. mce.dlbo.dl_CmpEQ64_CmpNE64 = DLexpensive; |
|
From: Julian S. <se...@so...> - 2020-01-02 07:02:56
|
https://sourceware.org/git/gitweb.cgi?p=valgrind.git;h=79dd0bd6e88a65f435799d5d84165c260c9bbda7 commit 79dd0bd6e88a65f435799d5d84165c260c9bbda7 Author: Julian Seward <js...@ac...> Date: Thu Jan 2 08:00:07 2020 +0100 Fold Iop_CmpEQ32x8(x,x) to all-1s .. .. hence treating it as a dependency-breaking idiom. Also handle the resulting IRConst_V256(0xFFFFFFFF) in the amd64 insn selector. (dup of 96de5118f5332ae145912ebe91b8fa143df74b8d from 'grail') Possibly fixes #409429. Diff: --- VEX/priv/host_amd64_isel.c | 8 ++++++++ VEX/priv/ir_opt.c | 5 ++++- 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/VEX/priv/host_amd64_isel.c b/VEX/priv/host_amd64_isel.c index 8dc3068..dfaabb4 100644 --- a/VEX/priv/host_amd64_isel.c +++ b/VEX/priv/host_amd64_isel.c @@ -4003,6 +4003,14 @@ static void iselDVecExpr_wrk ( /*OUT*/HReg* rHi, /*OUT*/HReg* rLo, *rLo = vLo; return; } + case 0xFFFFFFFF: { + HReg vHi = generate_ones_V128(env); + HReg vLo = newVRegV(env); + addInstr(env, mk_vMOVsd_RR(vHi, vLo)); + *rHi = vHi; + *rLo = vLo; + return; + } default: break; /* give up. Until such time as is necessary. */ } diff --git a/VEX/priv/ir_opt.c b/VEX/priv/ir_opt.c index 37e39bc..c5b7a2f 100644 --- a/VEX/priv/ir_opt.c +++ b/VEX/priv/ir_opt.c @@ -1298,6 +1298,8 @@ static IRExpr* mkOnesOfPrimopResultType ( IROp op ) case Iop_CmpEQ16x8: case Iop_CmpEQ32x4: return IRExpr_Const(IRConst_V128(0xFFFF)); + case Iop_CmpEQ32x8: + return IRExpr_Const(IRConst_V256(0xFFFFFFFF)); default: ppIROp(op); vpanic("mkOnesOfPrimopResultType: bad primop"); @@ -2353,7 +2355,7 @@ static IRExpr* fold_Expr_WRK ( IRExpr** env, IRExpr* e ) case Iop_Xor64: case Iop_XorV128: case Iop_XorV256: - /* Xor8/16/32/64/V128(t,t) ==> 0, for some IRTemp t */ + /* Xor8/16/32/64/V128/V256(t,t) ==> 0, for some IRTemp t */ if (sameIRExprs(env, e->Iex.Binop.arg1, e->Iex.Binop.arg2)) { e2 = mkZeroOfPrimopResultType(e->Iex.Binop.op); break; @@ -2406,6 +2408,7 @@ static IRExpr* fold_Expr_WRK ( IRExpr** env, IRExpr* e ) case Iop_CmpEQ8x16: case Iop_CmpEQ16x8: case Iop_CmpEQ32x4: + case Iop_CmpEQ32x8: if (sameIRExprs(env, e->Iex.Binop.arg1, e->Iex.Binop.arg2)) { e2 = mkOnesOfPrimopResultType(e->Iex.Binop.op); break; |
|
From: Julian S. <se...@so...> - 2020-01-02 06:29:40
|
https://sourceware.org/git/gitweb.cgi?p=valgrind.git;h=61a634b6077e9f0481e6b9a9d636ad3ee24faf6f commit 61a634b6077e9f0481e6b9a9d636ad3ee24faf6f Author: Julian Seward <js...@ac...> Date: Sun Dec 15 20:14:37 2019 +0100 'grail' fixes for MIPS: This isn't a good result. It merely disables the new functionality on MIPS because enabling it causes segfaults, even with --tool=none, the cause of which are not obvious. It is only chasing through conditional branches that is disabled, though. Chasing through unconditional branches (jumps and calls to known destinations) is still enabled. * guest_generic_bb_to_IR.c bb_to_IR(): Disable, hopefully temporarily, the key &&-recovery transformation on MIPS. * VEX/priv/host_mips_isel.c iselWordExpr_R_wrk(), iselCondCode_wrk(): - add support for Iop_And1, Iop_Or1, and IRConst_U1. This code is my best guess about what is correct, but is #if 0'd for now. - Properly guard some Iex_Binop cases that lacked a leading check that the expression actually was a Binop. Diff: --- VEX/priv/guest_generic_bb_to_IR.c | 5 +++- VEX/priv/host_mips_isel.c | 62 ++++++++++++++++++++++++++++++--------- 2 files changed, 52 insertions(+), 15 deletions(-) diff --git a/VEX/priv/guest_generic_bb_to_IR.c b/VEX/priv/guest_generic_bb_to_IR.c index 0b8f852..507c75e 100644 --- a/VEX/priv/guest_generic_bb_to_IR.c +++ b/VEX/priv/guest_generic_bb_to_IR.c @@ -1451,7 +1451,10 @@ IRSB* bb_to_IR ( Memcheck to crash, for as-yet unknown reasons. It also exposes some unhandled Iex_ITE cases in the s390x instruction selector. For now, disable. */ - && arch_guest != VexArchS390X) + && arch_guest != VexArchS390X + /* sewardj 2019Dec14: It also causes crashing on MIPS, even for + --tool=none. */ + && arch_guest != VexArchMIPS64 && arch_guest != VexArchMIPS32) { if (debug_print) { vex_printf("\n-+-+ (ext# %d) Considering cbranch to" diff --git a/VEX/priv/host_mips_isel.c b/VEX/priv/host_mips_isel.c index c49d152..f14f654 100644 --- a/VEX/priv/host_mips_isel.c +++ b/VEX/priv/host_mips_isel.c @@ -2364,6 +2364,13 @@ static HReg iselWordExpr_R_wrk(ISelEnv * env, IRExpr * e) case Ico_U8: l = (Long) (Int) (Char) con->Ico.U8; break; +#if 0 + // Not needed until chasing cond branches in bb_to_IR is enabled on + // MIPS. See comment on And1/Or1 below. + case Ico_U1: + l = con->Ico.U1 ? 1 : 0; + break; +#endif default: vpanic("iselIntExpr_R.const(mips)"); } @@ -2644,18 +2651,19 @@ static MIPSCondCode iselCondCode_wrk(ISelEnv * env, IRExpr * e) vassert(e); vassert(typeOfIRExpr(env->type_env, e) == Ity_I1); /* Cmp*32*(x,y) ? */ - if (e->Iex.Binop.op == Iop_CmpEQ32 - || e->Iex.Binop.op == Iop_CmpNE32 - || e->Iex.Binop.op == Iop_CmpNE64 - || e->Iex.Binop.op == Iop_CmpLT32S - || e->Iex.Binop.op == Iop_CmpLT32U - || e->Iex.Binop.op == Iop_CmpLT64U - || e->Iex.Binop.op == Iop_CmpLE32S - || e->Iex.Binop.op == Iop_CmpLE64S - || e->Iex.Binop.op == Iop_CmpLT64S - || e->Iex.Binop.op == Iop_CmpEQ64 - || e->Iex.Binop.op == Iop_CasCmpEQ32 - || e->Iex.Binop.op == Iop_CasCmpEQ64) { + if (e->tag == Iex_Binop + && (e->Iex.Binop.op == Iop_CmpEQ32 + || e->Iex.Binop.op == Iop_CmpNE32 + || e->Iex.Binop.op == Iop_CmpNE64 + || e->Iex.Binop.op == Iop_CmpLT32S + || e->Iex.Binop.op == Iop_CmpLT32U + || e->Iex.Binop.op == Iop_CmpLT64U + || e->Iex.Binop.op == Iop_CmpLE32S + || e->Iex.Binop.op == Iop_CmpLE64S + || e->Iex.Binop.op == Iop_CmpLT64S + || e->Iex.Binop.op == Iop_CmpEQ64 + || e->Iex.Binop.op == Iop_CasCmpEQ32 + || e->Iex.Binop.op == Iop_CasCmpEQ64)) { Bool syned = (e->Iex.Binop.op == Iop_CmpLT32S || e->Iex.Binop.op == Iop_CmpLE32S @@ -2726,7 +2734,7 @@ static MIPSCondCode iselCondCode_wrk(ISelEnv * env, IRExpr * e) dst, mode64)); return cc; } - if (e->Iex.Binop.op == Iop_Not1) { + if (e->tag == Iex_Unop && e->Iex.Binop.op == Iop_Not1) { HReg r_dst = newVRegI(env); HReg r_srcL = iselWordExpr_R(env, e->Iex.Unop.arg); MIPSRH *r_srcR = MIPSRH_Reg(r_srcL); @@ -2742,7 +2750,33 @@ static MIPSCondCode iselCondCode_wrk(ISelEnv * env, IRExpr * e) r_dst, mode64)); return MIPScc_NE; } - if (e->tag == Iex_RdTmp || e->tag == Iex_Unop) { +#if 0 + // sewardj 2019Dec14: this is my best attempt at And1/Or1, but I am not + // sure if it is correct. In any case it is not needed until chasing cond + // branches is enabled on MIPS. Currently it is disabled, in function bb_to_IR + // (see comments there). + if (e->tag == Iex_Binop + && (e->Iex.Binop.op == Iop_And1 || e->Iex.Binop.op == Iop_Or1)) { + HReg r_argL = iselWordExpr_R(env, e->Iex.Binop.arg1); + HReg r_argR = iselWordExpr_R(env, e->Iex.Binop.arg2); + HReg r_dst = newVRegI(env); + addInstr(env, MIPSInstr_Alu(e->Iex.Binop.op == Iop_And1 ? Malu_AND : Malu_OR, + r_dst, r_argL, MIPSRH_Reg(r_argR))); + addInstr(env, MIPSInstr_Alu(Malu_AND, r_dst, r_dst, MIPSRH_Imm(False, 1))); + /* Store result to guest_COND */ + /* sewardj 2019Dec13: this seems wrong to me. The host-side instruction + selector shouldn't touch the guest-side state, except in response to + Iex_Get and Ist_Put. */ + MIPSAMode *am_addr = MIPSAMode_IR(0, GuestStatePointer(mode64)); + + addInstr(env, MIPSInstr_Store(4, + MIPSAMode_IR(am_addr->Mam.IR.index + COND_OFFSET(mode64), + am_addr->Mam.IR.base), + r_dst, mode64)); + return MIPScc_EQ; + } +#endif + if (e->tag == Iex_RdTmp) { HReg r_dst = iselWordExpr_R_wrk(env, e); /* Store result to guest_COND */ MIPSAMode *am_addr = MIPSAMode_IR(0, GuestStatePointer(mode64)); |
|
From: Julian S. <se...@so...> - 2020-01-02 06:29:35
|
https://sourceware.org/git/gitweb.cgi?p=valgrind.git;h=8d510c468a20b7528e2fca870f3236b4e2cb965f commit 8d510c468a20b7528e2fca870f3236b4e2cb965f Author: Julian Seward <js...@ac...> Date: Sun Dec 1 07:01:20 2019 +0100 'grail' fixes for s390x: This isn't a good result. It merely disables the new functionality on s390x, for the reason stated below. * guest_generic_bb_to_IR.c bb_to_IR(): Disable, hopefully temporarily, the key &&-recovery transformation on s390x, since it causes Memcheck to crash for reasons I couldn't figure out. It also exposes some missing Iex_ITE cases in the s390x insn selector, although those shouldn't be a big deal to fix. Maybe it's some strangeness to do with the s390x "ex" instruction. I don't exactly understand how that trickery works, but from some study of it, I didn't see anything obviously wrong. It is only chasing through conditional branches that is disabled for s390x. Chasing through unconditional branches (jumps and calls to known destinations) is still enabled. * host_s390_isel.c s390_isel_cc(): No functional change. Code has been added here to handle the new Iop_And1 and Iop_Or1, and it is somewhat tested, but is not needed until conditional branch chasing is enabled on s390x. Diff: --- VEX/priv/guest_generic_bb_to_IR.c | 8 +++++++- VEX/priv/host_s390_isel.c | 40 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 47 insertions(+), 1 deletion(-) diff --git a/VEX/priv/guest_generic_bb_to_IR.c b/VEX/priv/guest_generic_bb_to_IR.c index 6a1d4dc..0b8f852 100644 --- a/VEX/priv/guest_generic_bb_to_IR.c +++ b/VEX/priv/guest_generic_bb_to_IR.c @@ -1446,7 +1446,13 @@ IRSB* bb_to_IR ( // Try for an extend based on a conditional branch, specifically in the // hope of identifying and recovering, an "A && B" condition spread across // two basic blocks. - if (irsb_be.tag == Be_Cond) { + if (irsb_be.tag == Be_Cond + /* sewardj 2019Nov30: Alas, chasing cond branches on s390 causes + Memcheck to crash, for as-yet unknown reasons. It also exposes + some unhandled Iex_ITE cases in the s390x instruction selector. + For now, disable. */ + && arch_guest != VexArchS390X) + { if (debug_print) { vex_printf("\n-+-+ (ext# %d) Considering cbranch to" " SX=0x%llx FT=0x%llx -+-+\n\n", diff --git a/VEX/priv/host_s390_isel.c b/VEX/priv/host_s390_isel.c index 30e5c76..97614c8 100644 --- a/VEX/priv/host_s390_isel.c +++ b/VEX/priv/host_s390_isel.c @@ -3535,6 +3535,46 @@ s390_isel_cc(ISelEnv *env, IRExpr *cond) IRExpr *arg2 = cond->Iex.Binop.arg2; HReg reg1, reg2; + /* sewardj 2019Nov30: This will be needed when chasing through conditional + branches in guest_generic_bb_to_IR.c is enabled on s390x. + Unfortunately that is currently disabled on s390x as it causes + mysterious segfaults and also exposes some unhandled Iex_ITE cases in + this instruction selector. The following Iop_And1/Iop_Or1 cases are + also needed when enabled. The code below is *believed* to be correct, + and has been lightly tested, but it is #if 0'd until such time as we + need it. */ +# if 0 + /* FIXME: We could (and probably should) do a lot better here, by using + the iselCondCode_C/_R scheme used in the amd64 insn selector. */ + if (cond->Iex.Binop.op == Iop_And1 || cond->Iex.Binop.op == Iop_Or1) { + /* In short: force both operands into registers, AND or OR them, mask + off all but the lowest bit, then convert the result back into a + condition code. */ + const s390_opnd_RMI one = s390_opnd_imm(1); + + HReg x_as_64 = newVRegI(env); + s390_cc_t cc_x = s390_isel_cc(env, arg1); + addInstr(env, s390_insn_cc2bool(x_as_64, cc_x)); + addInstr(env, s390_insn_alu(8, S390_ALU_AND, x_as_64, one)); + + HReg y_as_64 = newVRegI(env); + s390_cc_t cc_y = s390_isel_cc(env, arg2); + addInstr(env, s390_insn_cc2bool(y_as_64, cc_y)); + addInstr(env, s390_insn_alu(8, S390_ALU_AND, y_as_64, one)); + + s390_alu_t opkind + = cond->Iex.Binop.op == Iop_And1 ? S390_ALU_AND : S390_ALU_OR; + addInstr(env, s390_insn_alu(/*size=*/8, + opkind, x_as_64, s390_opnd_reg(y_as_64))); + + addInstr(env, s390_insn_alu(/*size=*/8, S390_ALU_AND, x_as_64, one)); + addInstr(env, s390_insn_test(/*size=*/8, s390_opnd_reg(x_as_64))); + return S390_CC_NE; + } +# endif /* 0 */ + + // |sizeofIRType| asserts on Ity_I1, so we can't do it until after we're + // sure that Iop_And1 and Iop_Or1 can't make it this far. size = sizeofIRType(typeOfIRExpr(env->type_env, arg1)); switch (cond->Iex.Binop.op) { |
|
From: Julian S. <se...@so...> - 2020-01-02 06:29:30
|
https://sourceware.org/git/gitweb.cgi?p=valgrind.git;h=1fa3bc8f54b409929af2bbb9afd8916c982d70ee commit 1fa3bc8f54b409929af2bbb9afd8916c982d70ee Author: Julian Seward <js...@ac...> Date: Sun Nov 24 15:13:54 2019 +0100 'grail' fixes for arm64: * guest_arm64_toIR.c: use |sigill_diag| to guard auxiliary diagnostic printing in case of decode failure * guest_generic_bb_to_IR.c expr_is_guardable(), stmt_is_guardable(): handle a few more cases that didn't turn up so far on x86 or amd64 * host_arm64_defs.[ch]: - new instruction ARM64Instr_Set64, to copy a condition code value into a register (the CSET instruction) - use this to reimplement Iop_And1 and Iop_Or1 Diff: --- VEX/priv/guest_arm64_toIR.c | 45 +++++++++++++------- VEX/priv/guest_generic_bb_to_IR.c | 19 +++++++-- VEX/priv/host_arm64_defs.c | 27 ++++++++++++ VEX/priv/host_arm64_defs.h | 7 +++ VEX/priv/host_arm64_isel.c | 89 +++++++++++++++++++++++++++++++++++++++ 5 files changed, 168 insertions(+), 19 deletions(-) diff --git a/VEX/priv/guest_arm64_toIR.c b/VEX/priv/guest_arm64_toIR.c index 6eb896c..bee348a 100644 --- a/VEX/priv/guest_arm64_toIR.c +++ b/VEX/priv/guest_arm64_toIR.c @@ -2402,7 +2402,7 @@ Bool dbm_DecodeBitMasks ( /*OUT*/ULong* wmask, /*OUT*/ULong* tmask, static Bool dis_ARM64_data_processing_immediate(/*MB_OUT*/DisResult* dres, - UInt insn) + UInt insn, Bool sigill_diag) { # define INSN(_bMax,_bMin) SLICE_UInt(insn, (_bMax), (_bMin)) @@ -2737,7 +2737,9 @@ Bool dis_ARM64_data_processing_immediate(/*MB_OUT*/DisResult* dres, } after_extr: - vex_printf("ARM64 front end: data_processing_immediate\n"); + if (sigill_diag) { + vex_printf("ARM64 front end: data_processing_immediate\n"); + } return False; # undef INSN } @@ -2804,7 +2806,7 @@ static IRTemp getShiftedIRegOrZR ( Bool is64, static Bool dis_ARM64_data_processing_register(/*MB_OUT*/DisResult* dres, - UInt insn) + UInt insn, Bool sigill_diag) { # define INSN(_bMax,_bMin) SLICE_UInt(insn, (_bMax), (_bMin)) @@ -3581,7 +3583,9 @@ Bool dis_ARM64_data_processing_register(/*MB_OUT*/DisResult* dres, /* fall through */ } - vex_printf("ARM64 front end: data_processing_register\n"); + if (sigill_diag) { + vex_printf("ARM64 front end: data_processing_register\n"); + } return False; # undef INSN } @@ -4646,7 +4650,9 @@ static IRTemp gen_indexed_EA ( /*OUT*/HChar* buf, UInt insn, Bool isInt ) return res; fail: - vex_printf("gen_indexed_EA: unhandled case optS == 0x%x\n", optS); + if (0 /*really, sigill_diag, but that causes too much plumbing*/) { + vex_printf("gen_indexed_EA: unhandled case optS == 0x%x\n", optS); + } return IRTemp_INVALID; } @@ -4717,8 +4723,7 @@ const HChar* nameArr_Q_SZ ( UInt bitQ, UInt size ) static Bool dis_ARM64_load_store(/*MB_OUT*/DisResult* dres, UInt insn, - const VexAbiInfo* abiinfo -) + const VexAbiInfo* abiinfo, Bool sigill_diag) { # define INSN(_bMax,_bMin) SLICE_UInt(insn, (_bMax), (_bMin)) @@ -6859,7 +6864,10 @@ Bool dis_ARM64_load_store(/*MB_OUT*/DisResult* dres, UInt insn, return True; } - vex_printf("ARM64 front end: load_store\n"); + if (sigill_diag) { + vex_printf("ARM64 front end: load_store\n"); + } + return False; # undef INSN } @@ -6872,7 +6880,7 @@ Bool dis_ARM64_load_store(/*MB_OUT*/DisResult* dres, UInt insn, static Bool dis_ARM64_branch_etc(/*MB_OUT*/DisResult* dres, UInt insn, const VexArchInfo* archinfo, - const VexAbiInfo* abiinfo) + const VexAbiInfo* abiinfo, Bool sigill_diag) { # define INSN(_bMax,_bMin) SLICE_UInt(insn, (_bMax), (_bMin)) @@ -7241,6 +7249,8 @@ Bool dis_ARM64_branch_etc(/*MB_OUT*/DisResult* dres, UInt insn, /* D5 0B 7B 001 Rt dc cvau, rT */ if ((INSN(31,0) & 0xFFFFFFE0) == 0xD50B7B20) { + /* JRS 2019Nov24: should we handle DC_CIVAC the same? + || (INSN(31,0) & 0xFFFFFFE0) == 0xD50B7E20 */ /* Exactly the same scheme as for IC IVAU, except we observe the dMinLine size, and request an Ijk_FlushDCache instead of Ijk_InvalICache. */ @@ -7360,7 +7370,9 @@ Bool dis_ARM64_branch_etc(/*MB_OUT*/DisResult* dres, UInt insn, return True; } - vex_printf("ARM64 front end: branch_etc\n"); + if (sigill_diag) { + vex_printf("ARM64 front end: branch_etc\n"); + } return False; # undef INSN } @@ -14798,7 +14810,8 @@ Bool disInstr_ARM64_WRK ( /*MB_OUT*/DisResult* dres, const UChar* guest_instr, const VexArchInfo* archinfo, - const VexAbiInfo* abiinfo + const VexAbiInfo* abiinfo, + Bool sigill_diag ) { // A macro to fish bits out of 'insn'. @@ -14922,20 +14935,20 @@ Bool disInstr_ARM64_WRK ( switch (INSN(28,25)) { case BITS4(1,0,0,0): case BITS4(1,0,0,1): // Data processing - immediate - ok = dis_ARM64_data_processing_immediate(dres, insn); + ok = dis_ARM64_data_processing_immediate(dres, insn, sigill_diag); break; case BITS4(1,0,1,0): case BITS4(1,0,1,1): // Branch, exception generation and system instructions - ok = dis_ARM64_branch_etc(dres, insn, archinfo, abiinfo); + ok = dis_ARM64_branch_etc(dres, insn, archinfo, abiinfo, sigill_diag); break; case BITS4(0,1,0,0): case BITS4(0,1,1,0): case BITS4(1,1,0,0): case BITS4(1,1,1,0): // Loads and stores - ok = dis_ARM64_load_store(dres, insn, abiinfo); + ok = dis_ARM64_load_store(dres, insn, abiinfo, sigill_diag); break; case BITS4(0,1,0,1): case BITS4(1,1,0,1): // Data processing - register - ok = dis_ARM64_data_processing_register(dres, insn); + ok = dis_ARM64_data_processing_register(dres, insn, sigill_diag); break; case BITS4(0,1,1,1): case BITS4(1,1,1,1): // Data processing - SIMD and floating point @@ -14998,7 +15011,7 @@ DisResult disInstr_ARM64 ( IRSB* irsb_IN, /* Try to decode */ Bool ok = disInstr_ARM64_WRK( &dres, &guest_code_IN[delta_IN], - archinfo, abiinfo ); + archinfo, abiinfo, sigill_diag_IN ); if (ok) { /* All decode successes end up here. */ vassert(dres.len == 4 || dres.len == 20); diff --git a/VEX/priv/guest_generic_bb_to_IR.c b/VEX/priv/guest_generic_bb_to_IR.c index 81cc493..677cfca 100644 --- a/VEX/priv/guest_generic_bb_to_IR.c +++ b/VEX/priv/guest_generic_bb_to_IR.c @@ -420,9 +420,12 @@ static Bool expr_is_guardable ( const IRExpr* e ) return !primopMightTrap(e->Iex.Unop.op); case Iex_Binop: return !primopMightTrap(e->Iex.Binop.op); + case Iex_Triop: + return !primopMightTrap(e->Iex.Triop.details->op); case Iex_ITE: case Iex_CCall: case Iex_Get: + case Iex_Const: return True; default: vex_printf("\n"); ppIRExpr(e); vex_printf("\n"); @@ -442,13 +445,23 @@ static Bool expr_is_guardable ( const IRExpr* e ) static Bool stmt_is_guardable ( const IRStmt* st ) { switch (st->tag) { + // These are easily guarded. case Ist_IMark: case Ist_Put: return True; - case Ist_Store: // definitely not - case Ist_CAS: // definitely not - case Ist_Exit: // We could in fact spec this, if required + // These are definitely not guardable, or at least it's way too much + // hassle to do so. + case Ist_CAS: + case Ist_LLSC: + case Ist_MBE: return False; + // These could be guarded, with some effort, if really needed, but + // currently aren't guardable. + case Ist_Store: + case Ist_Exit: + return False; + // This is probably guardable, but it depends on the RHS of the + // assignment. case Ist_WrTmp: return expr_is_guardable(st->Ist.WrTmp.data); default: diff --git a/VEX/priv/host_arm64_defs.c b/VEX/priv/host_arm64_defs.c index dba2f18..33acae9 100644 --- a/VEX/priv/host_arm64_defs.c +++ b/VEX/priv/host_arm64_defs.c @@ -870,6 +870,13 @@ ARM64Instr* ARM64Instr_Unary ( HReg dst, HReg src, ARM64UnaryOp op ) { i->ARM64in.Unary.op = op; return i; } +ARM64Instr* ARM64Instr_Set64 ( HReg dst, ARM64CondCode cond ) { + ARM64Instr* i = LibVEX_Alloc_inline(sizeof(ARM64Instr)); + i->tag = ARM64in_Set64; + i->ARM64in.Set64.dst = dst; + i->ARM64in.Set64.cond = cond; + return i; +} ARM64Instr* ARM64Instr_MovI ( HReg dst, HReg src ) { ARM64Instr* i = LibVEX_Alloc_inline(sizeof(ARM64Instr)); i->tag = ARM64in_MovI; @@ -1417,6 +1424,11 @@ void ppARM64Instr ( const ARM64Instr* i ) { vex_printf(", "); ppHRegARM64(i->ARM64in.Unary.src); return; + case ARM64in_Set64: + vex_printf("cset "); + ppHRegARM64(i->ARM64in.Set64.dst); + vex_printf(", %s", showARM64CondCode(i->ARM64in.Set64.cond)); + return; case ARM64in_MovI: vex_printf("mov "); ppHRegARM64(i->ARM64in.MovI.dst); @@ -1953,6 +1965,9 @@ void getRegUsage_ARM64Instr ( HRegUsage* u, const ARM64Instr* i, Bool mode64 ) addHRegUse(u, HRmWrite, i->ARM64in.Unary.dst); addHRegUse(u, HRmRead, i->ARM64in.Unary.src); return; + case ARM64in_Set64: + addHRegUse(u, HRmWrite, i->ARM64in.Set64.dst); + return; case ARM64in_MovI: addHRegUse(u, HRmWrite, i->ARM64in.MovI.dst); addHRegUse(u, HRmRead, i->ARM64in.MovI.src); @@ -2295,6 +2310,9 @@ void mapRegs_ARM64Instr ( HRegRemap* m, ARM64Instr* i, Bool mode64 ) i->ARM64in.Unary.dst = lookupHRegRemap(m, i->ARM64in.Unary.dst); i->ARM64in.Unary.src = lookupHRegRemap(m, i->ARM64in.Unary.src); return; + case ARM64in_Set64: + i->ARM64in.Set64.dst = lookupHRegRemap(m, i->ARM64in.Set64.dst); + return; case ARM64in_MovI: i->ARM64in.MovI.dst = lookupHRegRemap(m, i->ARM64in.MovI.dst); i->ARM64in.MovI.src = lookupHRegRemap(m, i->ARM64in.MovI.src); @@ -3482,6 +3500,15 @@ Int emit_ARM64Instr ( /*MB_MOD*/Bool* is_profInc, } goto bad; } + case ARM64in_Set64: { + /* 1 00 1101 0100 11111 invert(cond) 01 11111 Rd CSET Rd, Cond */ + UInt rDst = iregEnc(i->ARM64in.Set64.dst); + UInt cc = (UInt)i->ARM64in.Set64.cond; + vassert(cc < 14); + *p++ = X_3_8_5_6_5_5(X100, X11010100, X11111, + ((cc ^ 1) << 2) | X01, X11111, rDst); + goto done; + } case ARM64in_MovI: { /* We generate the "preferred form", ORR Xd, XZR, Xm 101 01010 00 0 m 000000 11111 d diff --git a/VEX/priv/host_arm64_defs.h b/VEX/priv/host_arm64_defs.h index aa4f943..db50056 100644 --- a/VEX/priv/host_arm64_defs.h +++ b/VEX/priv/host_arm64_defs.h @@ -463,6 +463,7 @@ typedef ARM64in_Test, ARM64in_Shift, ARM64in_Unary, + ARM64in_Set64, ARM64in_MovI, /* int reg-reg move */ ARM64in_Imm64, ARM64in_LdSt64, @@ -566,6 +567,11 @@ typedef HReg src; ARM64UnaryOp op; } Unary; + /* CSET -- Convert a condition code to a 64-bit value (0 or 1). */ + struct { + HReg dst; + ARM64CondCode cond; + } Set64; /* MOV dst, src -- reg-reg move for integer registers */ struct { HReg dst; @@ -915,6 +921,7 @@ extern ARM64Instr* ARM64Instr_Logic ( HReg, HReg, ARM64RIL*, ARM64LogicOp ); extern ARM64Instr* ARM64Instr_Test ( HReg, ARM64RIL* ); extern ARM64Instr* ARM64Instr_Shift ( HReg, HReg, ARM64RI6*, ARM64ShiftOp ); extern ARM64Instr* ARM64Instr_Unary ( HReg, HReg, ARM64UnaryOp ); +extern ARM64Instr* ARM64Instr_Set64 ( HReg, ARM64CondCode ); extern ARM64Instr* ARM64Instr_MovI ( HReg, HReg ); extern ARM64Instr* ARM64Instr_Imm64 ( HReg, ULong ); extern ARM64Instr* ARM64Instr_LdSt64 ( Bool isLoad, HReg, ARM64AMode* ); diff --git a/VEX/priv/host_arm64_isel.c b/VEX/priv/host_arm64_isel.c index 0fa16e7..eb7630e 100644 --- a/VEX/priv/host_arm64_isel.c +++ b/VEX/priv/host_arm64_isel.c @@ -1310,6 +1310,21 @@ static ARM64CondCode iselCondCode_wrk ( ISelEnv* env, IRExpr* e ) return ARM64cc_NE; } + /* Constant 1:Bit */ + if (e->tag == Iex_Const) { + /* This is a very stupid translation. Hopefully it doesn't occur much, + if ever. */ + vassert(e->Iex.Const.con->tag == Ico_U1); + vassert(e->Iex.Const.con->Ico.U1 == True + || e->Iex.Const.con->Ico.U1 == False); + HReg rTmp = newVRegI(env); + addInstr(env, ARM64Instr_Imm64(rTmp, 0)); + ARM64RIL* one = mb_mkARM64RIL_I(1); + vassert(one); + addInstr(env, ARM64Instr_Test(rTmp, one)); + return e->Iex.Const.con->Ico.U1 ? ARM64cc_EQ : ARM64cc_NE; + } + /* Not1(e) */ if (e->tag == Iex_Unop && e->Iex.Unop.op == Iop_Not1) { /* Generate code for the arg, and negate the test condition */ @@ -1452,6 +1467,31 @@ static ARM64CondCode iselCondCode_wrk ( ISelEnv* env, IRExpr* e ) } } + /* --- And1(x,y), Or1(x,y) --- */ + /* FIXME: We could (and probably should) do a lot better here, by using the + iselCondCode_C/_R scheme used in the amd64 insn selector. */ + if (e->tag == Iex_Binop + && (e->Iex.Binop.op == Iop_And1 || e->Iex.Binop.op == Iop_Or1)) { + HReg x_as_64 = newVRegI(env); + ARM64CondCode cc_x = iselCondCode(env, e->Iex.Binop.arg1); + addInstr(env, ARM64Instr_Set64(x_as_64, cc_x)); + + HReg y_as_64 = newVRegI(env); + ARM64CondCode cc_y = iselCondCode(env, e->Iex.Binop.arg2); + addInstr(env, ARM64Instr_Set64(y_as_64, cc_y)); + + HReg tmp = newVRegI(env); + ARM64LogicOp lop + = e->Iex.Binop.op == Iop_And1 ? ARM64lo_AND : ARM64lo_OR; + addInstr(env, ARM64Instr_Logic(tmp, x_as_64, ARM64RIL_R(y_as_64), lop)); + + ARM64RIL* one = mb_mkARM64RIL_I(1); + vassert(one); + addInstr(env, ARM64Instr_Test(tmp, one)); + + return ARM64cc_NE; + } + ppIRExpr(e); vpanic("iselCondCode"); } @@ -2995,6 +3035,55 @@ static HReg iselV128Expr_wrk ( ISelEnv* env, IRExpr* e ) } /* if (e->tag == Iex_Triop) */ + if (0 && e->tag == Iex_ITE) { + /* JRS 2019Nov24: I think this is right, and it is somewhat tested, but + not as much as I'd like. Hence disabled till it can be tested more. */ + // This is pretty feeble. We'd do better to generate BSL here. + HReg rX = newVRegI(env); + + ARM64CondCode cc = iselCondCode(env, e->Iex.ITE.cond); + addInstr(env, ARM64Instr_Set64(rX, cc)); + // cond: rX = 1 !cond: rX = 0 + + // Mask the Set64 result. This is paranoia (should be unnecessary). + ARM64RIL* one = mb_mkARM64RIL_I(1); + vassert(one); + addInstr(env, ARM64Instr_Logic(rX, rX, one, ARM64lo_AND)); + // cond: rX = 1 !cond: rX = 0 + + // Propagate to all bits in the 64 bit word by subtracting 1 from it. + // This also inverts the sense of the value. + addInstr(env, ARM64Instr_Arith(rX, rX, ARM64RIA_I12(1,0), + /*isAdd=*/False)); + // cond: rX = 0-(62)-0 !cond: rX = 1-(62)-1 + + // Duplicate rX into a vector register + HReg vMask = newVRegV(env); + addInstr(env, ARM64Instr_VQfromXX(vMask, rX, rX)); + // cond: vMask = 0-(126)-0 !cond: vMask = 1-(126)-1 + + HReg vIfTrue = iselV128Expr(env, e->Iex.ITE.iftrue); + HReg vIfFalse = iselV128Expr(env, e->Iex.ITE.iffalse); + + // Mask out iffalse value as needed + addInstr(env, + ARM64Instr_VBinV(ARM64vecb_AND, vIfFalse, vIfFalse, vMask)); + + // Invert the mask so we can use it for the iftrue value + addInstr(env, ARM64Instr_VUnaryV(ARM64vecu_NOT, vMask, vMask)); + // cond: vMask = 1-(126)-1 !cond: vMask = 0-(126)-0 + + // Mask out iftrue value as needed + addInstr(env, + ARM64Instr_VBinV(ARM64vecb_AND, vIfTrue, vIfTrue, vMask)); + + // Merge the masked iftrue and iffalse results. + HReg res = newVRegV(env); + addInstr(env, ARM64Instr_VBinV(ARM64vecb_ORR, res, vIfTrue, vIfFalse)); + + return res; + } + v128_expr_bad: ppIRExpr(e); vpanic("iselV128Expr_wrk"); |
|
From: Julian S. <se...@so...> - 2020-01-02 06:29:30
|
https://sourceware.org/git/gitweb.cgi?p=valgrind.git;h=076a79a48e251067758e1e9d8e50681450ed3889 commit 076a79a48e251067758e1e9d8e50681450ed3889 Author: Julian Seward <js...@ac...> Date: Wed Nov 27 08:52:45 2019 +0100 'grail' fixes for ppc32 and ppc64: * do_minimal_initial_iropt_BB: for ppc64, flatten rather than assert flatness. (Kludge. Sigh.) * priv/host_ppc_isel.c iselCondCode_wrk(): handle And1 and Or1, the not-particularly-optimal way * priv/host_ppc_isel.c iselCondCode_wrk(): handle Ico_U1(0). Diff: --- VEX/priv/host_ppc_isel.c | 31 ++++++++++++++++++++++++++++--- VEX/priv/ir_opt.c | 11 ++++++++++- 2 files changed, 38 insertions(+), 4 deletions(-) diff --git a/VEX/priv/host_ppc_isel.c b/VEX/priv/host_ppc_isel.c index 5e2a3b8..9c954da 100644 --- a/VEX/priv/host_ppc_isel.c +++ b/VEX/priv/host_ppc_isel.c @@ -3095,13 +3095,15 @@ static PPCCondCode iselCondCode_wrk ( ISelEnv* env, const IRExpr* e, vassert(typeOfIRExpr(env->type_env,e) == Ity_I1); /* Constant 1:Bit */ - if (e->tag == Iex_Const && e->Iex.Const.con->Ico.U1 == True) { - // Make a compare that will always be true: + if (e->tag == Iex_Const) { + // Make a compare that will always be true (or always false): + vassert(e->Iex.Const.con->Ico.U1 == True || e->Iex.Const.con->Ico.U1 == False); HReg r_zero = newVRegI(env); addInstr(env, PPCInstr_LI(r_zero, 0, env->mode64)); addInstr(env, PPCInstr_Cmp(False/*unsigned*/, True/*32bit cmp*/, 7/*cr*/, r_zero, PPCRH_Reg(r_zero))); - return mk_PPCCondCode( Pct_TRUE, Pcf_7EQ ); + return mk_PPCCondCode( e->Iex.Const.con->Ico.U1 ? Pct_TRUE : Pct_FALSE, + Pcf_7EQ ); } /* Not1(...) */ @@ -3260,6 +3262,29 @@ static PPCCondCode iselCondCode_wrk ( ISelEnv* env, const IRExpr* e, return mk_PPCCondCode( Pct_TRUE, Pcf_7EQ ); } + /* --- And1(x,y), Or1(x,y) --- */ + /* FIXME: We could (and probably should) do a lot better here, by using the + iselCondCode_C/_R scheme used in the amd64 insn selector. */ + if (e->tag == Iex_Binop + && (e->Iex.Binop.op == Iop_And1 || e->Iex.Binop.op == Iop_Or1)) { + HReg x_as_int = newVRegI(env); + PPCCondCode cc_x = iselCondCode(env, e->Iex.Binop.arg1, IEndianess); + addInstr(env, PPCInstr_Set(cc_x, x_as_int)); + + HReg y_as_int = newVRegI(env); + PPCCondCode cc_y = iselCondCode(env, e->Iex.Binop.arg2, IEndianess); + addInstr(env, PPCInstr_Set(cc_y, y_as_int)); + + HReg tmp = newVRegI(env); + PPCAluOp op = e->Iex.Binop.op == Iop_And1 ? Palu_AND : Palu_OR; + addInstr(env, PPCInstr_Alu(op, tmp, x_as_int, PPCRH_Reg(y_as_int))); + + addInstr(env, PPCInstr_Alu(Palu_AND, tmp, tmp, PPCRH_Imm(False,1))); + addInstr(env, PPCInstr_Cmp(False/*unsigned*/, True/*32bit cmp*/, + 7/*cr*/, tmp, PPCRH_Imm(False,1))); + return mk_PPCCondCode( Pct_TRUE, Pcf_7EQ ); + } + vex_printf("iselCondCode(ppc): No such tag(%u)\n", e->tag); ppIRExpr(e); vpanic("iselCondCode(ppc)"); diff --git a/VEX/priv/ir_opt.c b/VEX/priv/ir_opt.c index cb75be8..37e39bc 100644 --- a/VEX/priv/ir_opt.c +++ b/VEX/priv/ir_opt.c @@ -6679,7 +6679,16 @@ IRSB* do_iropt_BB( processed by do_minimal_initial_iropt_BB. And that will have flattened them out. */ // FIXME Remove this assertion once the 'grail' machinery seems stable - vassert(isFlatIRSB(bb0)); + // FIXME2 The TOC-redirect-hacks generators in m_translate.c -- gen_PUSH() + // and gen_PO() -- don't generate flat IR, and so cause this assertion + // to fail. For the time being, hack around this by flattening, + // rather than asserting for flatness, on the afflicted platforms. + // This is a kludge, yes. + if (guest_arch == VexArchPPC64) { + bb0 = flatten_BB(bb0); // Kludge! + } else { + vassert(isFlatIRSB(bb0)); // How it Really Should Be (tm). + } /* If at level 0, stop now. */ if (vex_control.iropt_level <= 0) return bb0; |
|
From: Julian S. <se...@so...> - 2020-01-02 06:29:24
|
https://sourceware.org/git/gitweb.cgi?p=valgrind.git;h=1df8c25b42b3834b65fffd34a445e2cf26179753 commit 1df8c25b42b3834b65fffd34a445e2cf26179753 Author: Julian Seward <js...@ac...> Date: Wed Nov 27 06:37:42 2019 +0100 'grail' fixes for arm32: * priv/guest_generic_bb_to_IR.c expr_is_guardable(), stmt_is_guardable(): add some missing cases * do_minimal_initial_iropt_BB: add comment (no functional change) * priv/host_arm_isel.c iselCondCode_wrk(): handle And1 and Or1, the not-particularly-optimal way Diff: --- VEX/priv/guest_generic_bb_to_IR.c | 4 ++++ VEX/priv/host_arm_isel.c | 24 ++++++++++++++++++++++++ VEX/priv/ir_opt.c | 2 ++ 3 files changed, 30 insertions(+) diff --git a/VEX/priv/guest_generic_bb_to_IR.c b/VEX/priv/guest_generic_bb_to_IR.c index 677cfca..6a1d4dc 100644 --- a/VEX/priv/guest_generic_bb_to_IR.c +++ b/VEX/priv/guest_generic_bb_to_IR.c @@ -426,6 +426,7 @@ static Bool expr_is_guardable ( const IRExpr* e ) case Iex_CCall: case Iex_Get: case Iex_Const: + case Iex_RdTmp: return True; default: vex_printf("\n"); ppIRExpr(e); vex_printf("\n"); @@ -446,6 +447,7 @@ static Bool stmt_is_guardable ( const IRStmt* st ) { switch (st->tag) { // These are easily guarded. + case Ist_NoOp: case Ist_IMark: case Ist_Put: return True; @@ -458,6 +460,7 @@ static Bool stmt_is_guardable ( const IRStmt* st ) // These could be guarded, with some effort, if really needed, but // currently aren't guardable. case Ist_Store: + case Ist_StoreG: case Ist_Exit: return False; // This is probably guardable, but it depends on the RHS of the @@ -492,6 +495,7 @@ static void add_guarded_stmt_to_end_of ( /*MOD*/IRSB* bb, /*IN*/ IRStmt* st, IRTemp guard ) { switch (st->tag) { + case Ist_NoOp: case Ist_IMark: case Ist_WrTmp: addStmtToIRSB(bb, st); diff --git a/VEX/priv/host_arm_isel.c b/VEX/priv/host_arm_isel.c index 510336b..acbd39a 100644 --- a/VEX/priv/host_arm_isel.c +++ b/VEX/priv/host_arm_isel.c @@ -1293,6 +1293,30 @@ static ARMCondCode iselCondCode_wrk ( ISelEnv* env, IRExpr* e ) return e->Iex.Const.con->Ico.U1 ? ARMcc_EQ : ARMcc_NE; } + /* --- And1(x,y), Or1(x,y) --- */ + /* FIXME: We could (and probably should) do a lot better here, by using the + iselCondCode_C/_R scheme used in the amd64 insn selector. */ + if (e->tag == Iex_Binop + && (e->Iex.Binop.op == Iop_And1 || e->Iex.Binop.op == Iop_Or1)) { + HReg x_as_32 = newVRegI(env); + ARMCondCode cc_x = iselCondCode(env, e->Iex.Binop.arg1); + addInstr(env, ARMInstr_Mov(x_as_32, ARMRI84_I84(0,0))); + addInstr(env, ARMInstr_CMov(cc_x, x_as_32, ARMRI84_I84(1,0))); + + HReg y_as_32 = newVRegI(env); + ARMCondCode cc_y = iselCondCode(env, e->Iex.Binop.arg2); + addInstr(env, ARMInstr_Mov(y_as_32, ARMRI84_I84(0,0))); + addInstr(env, ARMInstr_CMov(cc_y, y_as_32, ARMRI84_I84(1,0))); + + HReg tmp = newVRegI(env); + ARMAluOp aop = e->Iex.Binop.op == Iop_And1 ? ARMalu_AND : ARMalu_OR; + addInstr(env, ARMInstr_Alu(aop, tmp, x_as_32, ARMRI84_R(y_as_32))); + + ARMRI84* one = ARMRI84_I84(1,0); + addInstr(env, ARMInstr_CmpOrTst(False/*test*/, tmp, one)); + return ARMcc_NE; + } + // JRS 2013-Jan-03: this seems completely nonsensical /* --- CasCmpEQ* --- */ /* Ist_Cas has a dummy argument to compare with, so comparison is diff --git a/VEX/priv/ir_opt.c b/VEX/priv/ir_opt.c index aa259ae..cb75be8 100644 --- a/VEX/priv/ir_opt.c +++ b/VEX/priv/ir_opt.c @@ -6780,6 +6780,8 @@ IRSB* do_minimal_initial_iropt_BB(IRSB* bb0) { redundant_get_removal_BB ( bb ); // Do minimal constant prop: copy prop and constant prop only. No folding. + // JRS FIXME 2019Nov25: this is too weak to be effective on arm32. For that, + // specifying doFolding=True makes a huge difference. bb = cprop_BB_WRK ( bb, /*mustRetainNoOps=*/True, /*doFolding=*/False ); |
|
From: Julian S. <se...@so...> - 2020-01-02 06:29:18
|
https://sourceware.org/git/gitweb.cgi?p=valgrind.git;h=e404fe924c08c0946b836aa6c1aa85f7850029e4 commit e404fe924c08c0946b836aa6c1aa85f7850029e4 Author: Julian Seward <js...@ac...> Date: Fri Nov 22 19:27:43 2019 +0100 bb_to_IR(): Avoid causing spurious SIGILL-diagnostic messages .. .. when speculating into conditional-branch destinations. A simple change requiring a big comment explaining the rationale. Diff: --- VEX/priv/guest_generic_bb_to_IR.c | 34 ++++++++++++++++++++++++++++++++-- 1 file changed, 32 insertions(+), 2 deletions(-) diff --git a/VEX/priv/guest_generic_bb_to_IR.c b/VEX/priv/guest_generic_bb_to_IR.c index f890c33..81cc493 100644 --- a/VEX/priv/guest_generic_bb_to_IR.c +++ b/VEX/priv/guest_generic_bb_to_IR.c @@ -1358,6 +1358,34 @@ IRSB* bb_to_IR ( // Try for an extend. What kind we do depends on how the current trace // ends. + /* Regarding the use of |sigill_diag| in the extension logic below. This + is a Bool which controls whether or not the individual insn + disassemblers print an error message in the case where they don't + recognise an instruction. Generally speaking this is set to True, but + VEX's client can set it to False if it wants. + + Now that we are speculatively chasing both arms of a conditional + branch, this can lead to the following problem: one of those arms + contains an undecodable instruction. That insn is not reached at run + time, because the branch itself tests some CPU hwcaps info (or + whatever) and execution goes down the other path. However, it has the + bad side effect that the speculative disassembly will nevertheless + produce an error message when |sigill_diag| is True. + + To avoid this, in calls to |disassemble_basic_block_till_stop| for + speculative code, we pass False instead of |sigill_diag|. Note that + any (unconditional-chase) call to |disassemble_basic_block_till_stop| + that happens after a conditional chase that results in recovery of an + &&-idiom, is still really non-speculative, because the &&-idiom + translation can only happen when both paths lead to the same + continuation point. The result is that we know that the initial BB, + and BBs recovered via chasing an unconditional branch, are sure to be + executed, even if that unconditional branch follows a conditional + branch which got folded into an &&-idiom. So we don't need to change + the |sigill_diag| value used for them. It's only for the + conditional-branch SX and FT disassembly that it must be set to + |False|. + */ BlockEnd irsb_be; analyse_block_end(&irsb_be, irsb, guest_IP_sbstart, guest_word_type, chase_into_ok, callback_opaque, @@ -1423,7 +1451,8 @@ IRSB* bb_to_IR ( /*OUT*/ &sx_instrs_used, &sx_verbose_seen, &sx_base, &sx_len, /*MOD*/ emptyIRSB(), /*IN*/ irsb_be.Be.Cond.deltaSX, - instrs_avail_spec, guest_IP_sbstart, host_endness, sigill_diag, + instrs_avail_spec, guest_IP_sbstart, host_endness, + /*sigill_diag=*/False, // See comment above arch_guest, archinfo_guest, abiinfo_both, guest_word_type, debug_print, dis_instr_fn, guest_code, offB_GUEST_IP ); @@ -1445,7 +1474,8 @@ IRSB* bb_to_IR ( /*OUT*/ &ft_instrs_used, &ft_verbose_seen, &ft_base, &ft_len, /*MOD*/ emptyIRSB(), /*IN*/ irsb_be.Be.Cond.deltaFT, - instrs_avail_spec, guest_IP_sbstart, host_endness, sigill_diag, + instrs_avail_spec, guest_IP_sbstart, host_endness, + /*sigill_diag=*/False, // See comment above arch_guest, archinfo_guest, abiinfo_both, guest_word_type, debug_print, dis_instr_fn, guest_code, offB_GUEST_IP ); |
|
From: Julian S. <se...@so...> - 2020-01-02 06:29:09
|
https://sourceware.org/git/gitweb.cgi?p=valgrind.git;h=0c4d8bd04a7fc773a2d01d390d2cc6a97d493bde commit 0c4d8bd04a7fc773a2d01d390d2cc6a97d493bde Author: Julian Seward <js...@ac...> Date: Thu Nov 21 08:55:43 2019 +0100 Add statistics printing for the new trace construction algorithm. Diff: --- VEX/priv/guest_generic_bb_to_IR.c | 6 ++++++ VEX/priv/guest_generic_bb_to_IR.h | 2 ++ VEX/priv/main_main.c | 4 ++++ VEX/pub/libvex.h | 6 ++++++ coregrind/m_translate.c | 17 +++++++++++++++++ 5 files changed, 35 insertions(+) diff --git a/VEX/priv/guest_generic_bb_to_IR.c b/VEX/priv/guest_generic_bb_to_IR.c index 16d83a8..7477641 100644 --- a/VEX/priv/guest_generic_bb_to_IR.c +++ b/VEX/priv/guest_generic_bb_to_IR.c @@ -1209,6 +1209,8 @@ IRSB* bb_to_IR ( /*OUT*/VexGuestExtents* vge, /*OUT*/UInt* n_sc_extents, /*OUT*/UInt* n_guest_instrs, /* stats only */ + /*OUT*/UShort* n_uncond_in_trace, /* stats only */ + /*OUT*/UShort* n_cond_in_trace, /* stats only */ /*MOD*/VexRegisterUpdates* pxControl, /*IN*/ void* callback_opaque, /*IN*/ DisOneInstrFn dis_instr_fn, @@ -1252,6 +1254,8 @@ IRSB* bb_to_IR ( vge->n_used = 0; *n_sc_extents = 0; *n_guest_instrs = 0; + *n_uncond_in_trace = 0; + *n_cond_in_trace = 0; /* And a new IR superblock to dump the result into. */ IRSB* irsb = emptyIRSB(); @@ -1375,6 +1379,7 @@ IRSB* bb_to_IR ( add_extent(vge, bb_base, bb_len); update_instr_budget(&instrs_avail, &verbose_mode, bb_instrs_used, bb_verbose_seen); + *n_uncond_in_trace += 1; } // if (be.tag == Be_Uncond) // Try for an extend based on a conditional branch, specifically in the @@ -1567,6 +1572,7 @@ IRSB* bb_to_IR ( add_extent(vge, sx_base, sx_len); update_instr_budget(&instrs_avail, &verbose_mode, sx_instrs_used, sx_verbose_seen); + *n_cond_in_trace += 1; } break; } // if (be.tag == Be_Cond) diff --git a/VEX/priv/guest_generic_bb_to_IR.h b/VEX/priv/guest_generic_bb_to_IR.h index 08d33ad..cad6768 100644 --- a/VEX/priv/guest_generic_bb_to_IR.h +++ b/VEX/priv/guest_generic_bb_to_IR.h @@ -143,6 +143,8 @@ IRSB* bb_to_IR ( /*OUT*/VexGuestExtents* vge, /*OUT*/UInt* n_sc_extents, /*OUT*/UInt* n_guest_instrs, /* stats only */ + /*OUT*/UShort* n_uncond_in_trace, /* stats only */ + /*OUT*/UShort* n_cond_in_trace, /* stats only */ /*MOD*/VexRegisterUpdates* pxControl, /*IN*/ void* callback_opaque, /*IN*/ DisOneInstrFn dis_instr_fn, diff --git a/VEX/priv/main_main.c b/VEX/priv/main_main.c index 0da2b46..5acab9e 100644 --- a/VEX/priv/main_main.c +++ b/VEX/priv/main_main.c @@ -554,6 +554,8 @@ IRSB* LibVEX_FrontEnd ( /*MOD*/ VexTranslateArgs* vta, res->n_sc_extents = 0; res->offs_profInc = -1; res->n_guest_instrs = 0; + res->n_uncond_in_trace = 0; + res->n_cond_in_trace = 0; #ifndef VEXMULTIARCH /* yet more sanity checks ... */ @@ -581,6 +583,8 @@ IRSB* LibVEX_FrontEnd ( /*MOD*/ VexTranslateArgs* vta, irsb = bb_to_IR ( vta->guest_extents, &res->n_sc_extents, &res->n_guest_instrs, + &res->n_uncond_in_trace, + &res->n_cond_in_trace, pxControl, vta->callback_opaque, disInstrFn, diff --git a/VEX/pub/libvex.h b/VEX/pub/libvex.h index 5a6a0e8..5d3733d 100644 --- a/VEX/pub/libvex.h +++ b/VEX/pub/libvex.h @@ -651,6 +651,12 @@ typedef /* Stats only: the number of guest insns included in the translation. It may be zero (!). */ UInt n_guest_instrs; + /* Stats only: the number of unconditional branches incorporated into the + trace. */ + UShort n_uncond_in_trace; + /* Stats only: the number of conditional branches incorporated into the + trace. */ + UShort n_cond_in_trace; } VexTranslateResult; diff --git a/coregrind/m_translate.c b/coregrind/m_translate.c index ae1cfcd..332202a 100644 --- a/coregrind/m_translate.c +++ b/coregrind/m_translate.c @@ -64,6 +64,11 @@ /*--- Stats ---*/ /*------------------------------------------------------------*/ +static ULong n_TRACE_total_constructed = 0; +static ULong n_TRACE_total_guest_insns = 0; +static ULong n_TRACE_total_uncond_branches_followed = 0; +static ULong n_TRACE_total_cond_branches_followed = 0; + static ULong n_SP_updates_new_fast = 0; static ULong n_SP_updates_new_generic_known = 0; static ULong n_SP_updates_die_fast = 0; @@ -77,6 +82,13 @@ static ULong n_PX_VexRegUpdAllregsAtEachInsn = 0; void VG_(print_translation_stats) ( void ) { + VG_(message) + (Vg_DebugMsg, + "translate: %'llu guest insns, %'llu traces, " + "%'llu uncond chased, %llu cond chased\n", + n_TRACE_total_guest_insns, n_TRACE_total_constructed, + n_TRACE_total_uncond_branches_followed, + n_TRACE_total_cond_branches_followed); UInt n_SP_updates = n_SP_updates_new_fast + n_SP_updates_new_generic_known + n_SP_updates_die_fast + n_SP_updates_die_generic_known + n_SP_updates_generic_unknown; @@ -1819,6 +1831,11 @@ Bool VG_(translate) ( ThreadId tid, vg_assert(tres.n_sc_extents >= 0 && tres.n_sc_extents <= 3); vg_assert(tmpbuf_used <= N_TMPBUF); vg_assert(tmpbuf_used > 0); + + n_TRACE_total_constructed += 1; + n_TRACE_total_guest_insns += tres.n_guest_instrs; + n_TRACE_total_uncond_branches_followed += tres.n_uncond_in_trace; + n_TRACE_total_cond_branches_followed += tres.n_cond_in_trace; } /* END new scope specially for 'seg' */ /* Tell aspacem of all segments that have had translations taken |