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
(1) |
3
|
|
4
|
5
(1) |
6
(2) |
7
(1) |
8
(1) |
9
(2) |
10
|
|
11
|
12
|
13
(6) |
14
(4) |
15
(1) |
16
(4) |
17
(2) |
|
18
(1) |
19
(8) |
20
(8) |
21
(2) |
22
(3) |
23
(3) |
24
|
|
25
|
26
|
27
(1) |
28
|
29
|
30
|
31
(2) |
|
From: Petar J. <pe...@so...> - 2019-08-21 17:09:57
|
https://sourceware.org/git/gitweb.cgi?p=valgrind.git;h=eddb917a6c67e1361b95ac2e49badf7bf7b3f8be commit eddb917a6c67e1361b95ac2e49badf7bf7b3f8be Author: Petar Jovanovic <mip...@gm...> Date: Wed Aug 21 16:08:42 2019 +0000 mips: Add nanoMIPS support to Valgrind 1/4 Necessary changes to support nanoMIPS on Linux. Part 1/4 - VEX changes Patch by Aleksandar Rikalo, Dimitrije Nikolic, Tamara Vlahovic and Aleksandra Karadzic. nanoMIPS architecture in brief Designed for embedded devices, nanoMIPS is a variable lengths instruction set architecture (ISA) offering high performance in substantially reduced code size. The nanoMIPS ISA combines recoded and new 16-, 32-, and 48-bit instructions to achieve an ideal balance of performance and code density. It incorporates all MIPS32 instructions and architecture modules including MIPS DSP and MIPS MT, as well as new instructions for advanced code size reduction. nanoMIPS is supported in release 6 of the MIPS architecture. It is first implemented in the new MIPS I7200 multi-threaded multi-core processor series. Compiler support is included in the MIPS GNU-based development tools. Related KDE issue: #400872. Diff: --- Makefile.vex.am | 11 +- VEX/priv/common_nanomips_defs.h | 374 +++++ VEX/priv/guest_nanomips_defs.h | 74 + VEX/priv/guest_nanomips_helpers.c | 127 ++ VEX/priv/guest_nanomips_toIR.c | 3101 +++++++++++++++++++++++++++++++++++++ VEX/priv/host_nanomips_defs.c | 2080 +++++++++++++++++++++++++ VEX/priv/host_nanomips_defs.h | 428 +++++ VEX/priv/host_nanomips_isel.c | 1567 +++++++++++++++++++ VEX/priv/main_main.c | 74 + VEX/pub/libvex.h | 3 +- VEX/pub/libvex_basictypes.h | 4 + VEX/pub/libvex_guest_mips32.h | 3 + 12 files changed, 7843 insertions(+), 3 deletions(-) diff --git a/Makefile.vex.am b/Makefile.vex.am index 10e1890..98d8483 100644 --- a/Makefile.vex.am +++ b/Makefile.vex.am @@ -48,6 +48,7 @@ noinst_HEADERS = \ priv/guest_s390_defs.h \ priv/guest_mips_defs.h \ priv/mips_defs.h \ + priv/guest_nanomips_defs.h \ priv/host_generic_regs.h \ priv/host_generic_simd64.h \ priv/host_generic_simd128.h \ @@ -61,7 +62,9 @@ noinst_HEADERS = \ priv/host_s390_defs.h \ priv/s390_disasm.h \ priv/s390_defs.h \ - priv/host_mips_defs.h + priv/host_mips_defs.h \ + priv/host_nanomips_defs.h \ + priv/common_nanomips_defs.h BUILT_SOURCES = pub/libvex_guest_offsets.h CLEANFILES = pub/libvex_guest_offsets.h @@ -146,6 +149,8 @@ LIBVEX_SOURCES_COMMON = \ priv/guest_mips_helpers.c \ priv/guest_mipsdsp_toIR.c \ priv/guest_mips_toIR.c \ + priv/guest_nanomips_helpers.c \ + priv/guest_nanomips_toIR.c \ priv/host_generic_regs.c \ priv/host_generic_simd64.c \ priv/host_generic_simd128.c \ @@ -167,7 +172,9 @@ LIBVEX_SOURCES_COMMON = \ priv/host_s390_isel.c \ priv/s390_disasm.c \ priv/host_mips_defs.c \ - priv/host_mips_isel.c + priv/host_nanomips_defs.c \ + priv/host_mips_isel.c \ + priv/host_nanomips_isel.c LIBVEXMULTIARCH_SOURCES = priv/multiarch_main_main.c diff --git a/VEX/priv/common_nanomips_defs.h b/VEX/priv/common_nanomips_defs.h new file mode 100644 index 0000000..ee79943 --- /dev/null +++ b/VEX/priv/common_nanomips_defs.h @@ -0,0 +1,374 @@ + +/*---------------------------------------------------------------*/ +/*--- begin common_nanomips_defs.h ---*/ +/*---------------------------------------------------------------*/ + +/* + This file is part of Valgrind, a dynamic binary instrumentation + framework. + + Copyright (C) 2017-2018 RT-RK + mip...@rt... + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307, USA. + + The GNU General Public License is contained in the file COPYING. +*/ +#ifndef __VEX_COMMON_NANOMIPS_DEFS_H +#define __VEX_COMMON_NANOMIPS_DEFS_H + +typedef enum { + P_ADDIURI = 0x00, + ADDIUPC32 = 0x01, + MOVE_BALC = 0x02, + P16MV = 0x04, + LW16 = 0x05, + BC16 = 0x06, + P16SR = 0x07, + P32A = 0x08, + PBAL = 0x0A, + P16SHIFT = 0x0C, + LWSP = 0x0D, + BALC16 = 0x0E, + P164X4 = 0x0F, + PGPW = 0x10, + PGPBH = 0x11, + PJ = 0x12, + P16C = 0x14, + LWGP16 = 0x15, + P16LB = 0x17, + P48I = 0x18, + P16A1 = 0x1C, + LW4X4 = 0x1D, + P16LH = 0x1F, + PU12 = 0x20, + PLSU12 = 0x21, + PBR1 = 0x22, + P16A2 = 0x24, + SW16 = 0x25, + BEQZC16 = 0x26, + PLSS9 = 0x29, + PBR2 = 0x2A, + P16ADDU = 0x2C, + SWSP = 0x2D, + BNEZC16 = 0x2E, + MOVEP = 0x2F, + PBRI = 0x32, + LI16 = 0x34, + SWGP16 = 0x35, + P16BR = 0x36, + P_LUI = 0x38, + ANDI16 = 0x3C, + SW4X4 = 0x3D, + MOVEPREV = 0x3F, +} nanoMIPSopcodes; + +typedef enum { + P48I_LI = 0x00, + P48I_ADDIU = 0x01, + P48I_ADDIU_GP = 0x02, + P48I_ADDIUPC = 0x03, + P48I_LWPC = 0x0B, + P48I_SWPC = 0x0F, +} nanoP48I; + +typedef enum { + JALRC32 = 0x00, + JALRCHB = 0x01, + PBALRSC = 0x08 +} nano_PJ; + +typedef enum { + PLSS0 = 0x00, + PLSS1 = 0x01, + PLSE0 = 0x02, + PLSWM = 0x04, + PLSUAWM = 0x05, + PLSDM = 0x06, + PLSUADM = 0x07, +} nanoPLSS9; + +typedef enum { + PU12_ORI = 0x00, + PU12_XORI = 0x01, + PU12_ANDI = 0x02, + PU12_PSR = 0x03, + PU12_SLTI = 0x04, + PU12_SLTIU = 0x05, + PU12_SEQI = 0x06, + PU12_ADDIU_NEG = 0x08, + PU12_PSHIFT = 0x0C, + PU12_PROTX = 0x0D, + PU12_PINS = 0x0E, + PU12_PEXT = 0x0F +} nanoPU12; + +typedef enum { + RI_PSYSCALL = 0x1, + RI_BREAK = 0x2, + RI_SDBBP = 0x3 +} nanoP16RI; + +typedef enum { + PRI_SIGRIE = 0x0, + PRI_PSYSCALL = 0x1, + PRI_BREAK = 0x2, + PRI_SDBBP = 0x3 +} nanoPRI; + +typedef enum { + P32A_POOL32A0 = 0x00, + P32A_POOL32A7 = 0x07 +} nano_P32A; + +typedef enum { + _POOL32A0_PTRAP = 0x00, + _POOL32A0_SEB = 0x01, + _POOL32A0_SLLV = 0x02, + _POOL32A0_MUL32 = 0x03, + _POOL32A0_MFC0 = 0x06, + _POOL32A0_MFHC0 = 0x07, + _POOL32A0_SEH = 0x09, + _POOL32A0_SRLV = 0x0A, + _POOL32A0_MUH = 0x0B, + _POOL32A0_MTC0 = 0x0E, + _POOL32A0_MTHC0 = 0x0F, + _POOL32A0_SRAV = 0x12, + _POOL32A0_MULU = 0x13, + _POOL32A0_MFGC0 = 0x16, + _POOL32A0_MFHGC0 = 0x17, + _POOL32A0_ROTRV = 0x1A, + _POOL32A0_MUHU = 0x1B, + _POOL32A0_MTGC0 = 0x1E, + _POOL32A0_MTHGC0 = 0x1F, + _POOL32A0_ADD = 0x22, + _POOL32A0_DIV = 0x23, + _POOL32A0_DMFC0 = 0x26, + _POOL32A0_ADDU32 = 0x2A, + _POOL32A0_MOD = 0x2B, + _POOL32A0_DMTC0 = 0x2E, + _POOL32A0_SUB = 0x32, + _POOL32A0_DIVU = 0x33, + _POOL32A0_DMFGC0 = 0x36, + _POOL32A0_RDHWR = 0x38, + _POOL32A0_SUBU32 = 0x3A, + _POOL32A0_MODU = 0x3B, + _POOL32A0_DMTGC0 = 0x3E, + _POOL32A0_PCMOVE = 0x42, + _POOL32A0_FORK = 0x45, + _POOL32A0_MFTR = 0x46, + _POOL32A0_MFHTR = 0x47, + _POOL32A0_AND32 = 0x4A, + _POOL32A0_YIELD = 0x4D, + _POOL32A0_MTTR = 0x4E, + _POOL32A0_MTHTR = 0x4F, + _POOL32A0_OR32 = 0x52, + _POOL32A0_PMTVPE = 0x56, + _POOL32A0_NOR = 0x5A, + _POOL32A0_XOR32 = 0x62, + _POOL32A0_SLT = 0x6A, + _POOL32A0_PSLTU = 0x72, + _POOL32A0_SOV = 0x7A, +} nano_POOL32A0; + +typedef enum { + _POOL32A7_PLSX = 0x00, + _POOL32A7_LSA = 0x01, + _POOL32A7_EXTW = 0x03, + _POOL32A7_P32Axf = 0x07, +} nano_POOL32A7; + +typedef enum { + nano_POOL32Axf4_CLO = 0x25, + nano_POOL32Axf4_CLZ = 0x2D, +} nano_POOL32Axf4; + +typedef enum { + PLSX_PPLSX = 0x00, + PLSX_PPLSXS = 0x01, +} nano_PLSX; + +typedef enum { + LBX = 0x00, + SBX = 0x01, + LBUX = 0x02, + LHX = 0x04, + SHX = 0x05, + LHUX = 0x06, + LWUX = 0x07, + LWX = 0x08, + SWX = 0x09, + LWC1X = 0x0A, + SWC1X = 0x0B, + LDX = 0x0C, + SDX = 0x0D, + LDC1X = 0x0E, + SDC1X = 0x0F +} nano_PPLSX; + +typedef enum { + LHXS = 0x04, + SHXS = 0x05, + LHUXS = 0x06, + LWUXS = 0x07, + LWXS32 = 0x08, + SWXS = 0x09, + LWC1XS = 0x0A, + SWC1XS = 0x0B, + LDXS = 0x0C, + SDXS = 0x0D, + LDC1XS = 0x0E, + SDC1XS = 0x0F +} nano_PPLSXS; + +typedef enum { + PLSU12_LB = 0x00, + PLSU12_SB = 0x01, + PLSU12_LBU = 0x02, + PLSU12_PREF = 0x03, + PLSU12_LH = 0x04, + PLSU12_SH = 0x05, + PLSU12_LHU = 0x06, + PLSU12_LWU = 0x07, + PLSU12_LW = 0x08, + PLSU12_SW = 0x09, + PLSU12_LWC1 = 0x0A, + PLSU12_SWC1 = 0x0B, + PLSU12_LD = 0x0C, + PLSU12_SD = 0x0D, + PLSU12_LDC1 = 0x0E, + PLSU12_SDC1 = 0x0F, + +} nano_PLSU12; + +typedef enum { + PSLL = 0x00, + SRL32 = 0x02, + SRA = 0x04, + ROTR = 0x06, + DSLL = 0x08, + DSLL32 = 0x09, + DSRL = 0x0A, + DSRL32 = 0x0B, + DSRA = 0x0C, + DSRA32 = 0x0D, + DROTR = 0x0E, + DROTR32 = 0x0F, +} nano_PSHIFT; + +typedef enum { + LBS9 = 0x00, + SBS9 = 0x01, + LBUS9 = 0x02, + PPREFS9 = 0x03, + LHS9 = 0x04, + SHS9 = 0x05, + LHUS9 = 0x06, + LWUS9 = 0x07, + LWS9 = 0x08, + SWS9 = 0x09, + LWC1S9 = 0x0A, + SWC1S9 = 0x0B, + LDS9 = 0x0C, + SDS9 = 0x0D, + LDC1S9 = 0x0E, + SDC1S9 = 0x0F, +} nano_PLSS0; + +typedef enum { + LBGP = 0x00, + SBGP = 0x01, + LBUGP = 0x02, + ADDIUGPB = 0x03, + PGPLH = 0x04, + PGPSH = 0x05, + PGPCP1 = 0x06, + PGPM64 = 0x07 +} nano_PGPBH; + +typedef enum { + ASET_ACLER = 0x02, + UALH = 0x04, + UASH = 0x05, + CACHE = 0x07, + LWC2 = 0x08, + SWC2 = 0x09, + PLL = 0x0A, + PSC = 0x0B, + LDC2 = 0x0C, + SDC2 = 0x0D, + PLLD = 0x0E, + PSCD = 0x0F +} nano_PLSS1; + +typedef enum { + LL = 0x00, + LLWP = 0x01 +} nano_LL; + +typedef enum { + SC = 0x00, + SCWP = 0x01 +} nano_SC; + +typedef enum { + PBR1_BEQC32 = 0x00, + PBR1_PBR3A = 0x01, + PBR1_BGEC = 0x02, + PBR1_BGEUC = 0x03, +} nano_PBR1; + +typedef enum { + PBR2_BNEC32 = 0x00, + PBR2_BLTC = 0x02, + PBR2_BLTUC = 0x03, +} nano_PBR2; + +typedef enum { + PBRI_BEQIC = 0x00, + PBRI_BBEQZC = 0x01, + PBRI_BGEIC = 0x02, + PBRI_BGEIUC = 0x03, + PBRI_BNEIC = 0x04, + PBRI_BBNEZC = 0x05, + PBRI_BLTIC = 0x06, + PBRI_BLTIUC = 0x07 +} nano_PBRI; + +typedef enum { + PGPW_ADDIU = 0x00, + PGPW_PGPD = 0X01, + PGPW_LW = 0X02, + PGPW_SW = 0X03 +} nano_PGPW; + +typedef enum { + POOL32aXF_4 = 0x04, + POOL32aXF_5 = 0x05, +} nano_POOL32Axf; + +typedef enum { + POOL16C00_NOT = 0x00, + POOL16C00_XOR = 0x04, + POOL16C00_AND = 0x08, + POOL16C00_OR = 0x0C, +} nano_POOL16C_00; + +#endif + +/*---------------------------------------------------------------*/ +/*--- end common_nanomips_defs.h ---*/ +/*---------------------------------------------------------------*/ diff --git a/VEX/priv/guest_nanomips_defs.h b/VEX/priv/guest_nanomips_defs.h new file mode 100644 index 0000000..490ef4b --- /dev/null +++ b/VEX/priv/guest_nanomips_defs.h @@ -0,0 +1,74 @@ + +/*---------------------------------------------------------------*/ +/*--- begin guest_nanomips_defs.h ---*/ +/*---------------------------------------------------------------*/ + +/* + This file is part of Valgrind, a dynamic binary instrumentation + framework. + + Copyright (C) 2017-2018 RT-RK + mip...@rt... + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307, USA. + + The GNU General Public License is contained in the file COPYING. +*/ + +/* Only to be used within the guest-mips directory. */ + +#ifndef __VEX_GUEST_NANOMIPS_DEFS_H +#define __VEX_GUEST_NANOMIPS_DEFS_H + +#include "libvex_basictypes.h" +#include "guest_generic_bb_to_IR.h" /* DisResult */ +#include "common_nanomips_defs.h" + +#if defined (_MIPSEL) + #define MIPS_IEND Iend_LE +#else + #define MIPS_IEND Iend_BE +#endif + +/*---------------------------------------------------------*/ +/*--- mips to IR conversion ---*/ +/*---------------------------------------------------------*/ + +/* Convert one nanoMIPS insn to IR. See the type DisOneInstrFn in + guest_generic_bb_to_IR.h. */ +extern DisResult disInstr_nanoMIPS ( IRSB* irbb, + Bool (*resteerOkFn) (void *, Addr), + Bool resteerCisOk, + void* callback_opaque, + const UChar* guest_code, + Long delta, + Addr guest_IP, + VexArch guest_arch, + const VexArchInfo* archinfo, + const VexAbiInfo* abiinfo, + VexEndness host_endness, + Bool sigill_diag ); + + +extern VexGuestLayout nanomipsGuest_layout; + +extern HWord nanomips_dirtyhelper_rdhwr ( UInt rd ); + +#endif + +/*---------------------------------------------------------------*/ +/*--- end guest_nanomips_defs.h ---*/ +/*---------------------------------------------------------------*/ diff --git a/VEX/priv/guest_nanomips_helpers.c b/VEX/priv/guest_nanomips_helpers.c new file mode 100644 index 0000000..f1bceab --- /dev/null +++ b/VEX/priv/guest_nanomips_helpers.c @@ -0,0 +1,127 @@ + +/*---------------------------------------------------------------*/ +/*--- begin guest_nanomips_helpers.c ---*/ +/*---------------------------------------------------------------*/ + +/* + This file is part of Valgrind, a dynamic binary instrumentation + framework. + + Copyright (C) 2017-2018 RT-RK + mip...@rt... + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307, USA. + + The GNU General Public License is contained in the file COPYING. +*/ + +#include "libvex_basictypes.h" +#include "libvex_emnote.h" +#include "libvex_guest_mips32.h" +#include "libvex_ir.h" +#include "libvex.h" + +#include "main_util.h" +#include "main_globals.h" +#include "guest_generic_bb_to_IR.h" +#include "guest_nanomips_defs.h" + +#if defined (__GNUC__) +#define GCC_VERSION (__GNUC__ * 100 + __GNUC_MINOR__) +#else +#define GCC_VERSION 0 +#endif + +/* This file contains helper functions for mips guest code. Calls to + these functions are generated by the back end. +*/ + +#define ALWAYSDEFD32(field) \ + { offsetof(VexGuestMIPS32State, field), \ + (sizeof ((VexGuestMIPS32State*)0)->field) } + +VexGuestLayout nanomipsGuest_layout = { + /* Total size of the guest state, in bytes. */ + .total_sizeB = sizeof(VexGuestMIPS32State), + /* Describe the stack pointer. */ + .offset_SP = offsetof(VexGuestMIPS32State, guest_r29), + .sizeof_SP = 4, + /* Describe the frame pointer. */ + .offset_FP = offsetof(VexGuestMIPS32State, guest_r30), + .sizeof_FP = 4, + /* Describe the instruction pointer. */ + .offset_IP = offsetof(VexGuestMIPS32State, guest_PC), + .sizeof_IP = 4, + /* Describe any sections to be regarded by Memcheck as + 'always-defined'. */ + .n_alwaysDefd = 8, + /* ? :( */ + .alwaysDefd = { + /* 0 */ ALWAYSDEFD32(guest_r0), + /* 1 */ ALWAYSDEFD32(guest_r1), + /* 2 */ ALWAYSDEFD32(guest_EMNOTE), + /* 3 */ ALWAYSDEFD32(guest_CMSTART), + /* 4 */ ALWAYSDEFD32(guest_CMLEN), + /* 5 */ ALWAYSDEFD32(guest_r29), + /* 6 */ ALWAYSDEFD32(guest_r31), + /* 7 */ ALWAYSDEFD32(guest_ULR) + } +}; + + +#define ASM_VOLATILE_RDHWR(opcode) \ + __asm__ __volatile__(".word 0x204001C0 | "#opcode" << 16 \n\t" \ + : "+r" (x) : : \ + ) + +HWord nanomips_dirtyhelper_rdhwr ( UInt rd ) +{ +#if defined(__nanomips__) + register HWord x __asm__("t4") = 0; + + switch (rd) { + case 0: /* x = CPUNum() */ + ASM_VOLATILE_RDHWR(0); /* rdhwr t4, $0 */ + break; + + case 1: /* x = SYNCI_Step() */ + ASM_VOLATILE_RDHWR(1); /* rdhwr t4, $1 */ + break; + + case 2: /* x = CC() */ + ASM_VOLATILE_RDHWR(2); /* rdhwr t4, $2 */ + break; + + case 3: /* x = CCRes() */ + ASM_VOLATILE_RDHWR(3); /* rdhwr t4, $3 */ + break; + + + default: + vassert(0); + break; + } + + return x; +#else + return 0; +#endif +} + + +/*---------------------------------------------------------------*/ +/*--- end guest_nanomips_helpers.c ---*/ +/*---------------------------------------------------------------*/ diff --git a/VEX/priv/guest_nanomips_toIR.c b/VEX/priv/guest_nanomips_toIR.c new file mode 100644 index 0000000..1a6ed0d --- /dev/null +++ b/VEX/priv/guest_nanomips_toIR.c @@ -0,0 +1,3101 @@ + +/*--------------------------------------------------------------------*/ +/*--- begin guest_nanomips_toIR.c ---*/ +/*--------------------------------------------------------------------*/ + +/* + This file is part of Valgrind, a dynamic binary instrumentation + framework. + + Copyright (C) 2017-2018 RT-RK + mip...@rt... + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307, USA. + + The GNU General Public License is contained in the file COPYING. +*/ + +/* Translates nanoMIPS code to IR. */ + +#include "libvex_basictypes.h" +#include "libvex_ir.h" +#include "libvex.h" +#include "libvex_guest_mips32.h" + +#include "main_util.h" +#include "main_globals.h" +#include "guest_generic_bb_to_IR.h" +#include "guest_nanomips_defs.h" + +#define P16 0x4 + +#define DIP(format, args...) \ + if (vex_traceflags & VEX_TRACE_FE) \ + vex_printf(format, ## args) + +#define OFFB_PC offsetof(VexGuestMIPS32State, guest_PC) + +#define ILLEGAL_INSTRUCTON \ + dres->jk_StopHere = Ijk_SigILL; \ + dres->whatNext = Dis_StopHere; + +#define LLADDR_INVALID (mkU32(0xFFFFFFFF)) + +/* MOD: The IRSB* into which we're generating code. */ +static IRSB *irsb; + +/* CONST: The guest address for the instruction currently being + translated. */ +static Addr32 guest_PC_curr_instr; + +/* Do a endian load of a 16-bit word, regardless of the endianness of the + underlying host. */ +static inline UShort getUShort(const UChar * p) +{ + UShort w = 0; +#if defined (_MIPSEL) + w = (w << 8) | p[1]; + w = (w << 8) | p[0]; +#elif defined (_MIPSEB) + w = (w << 8) | p[0]; + w = (w << 8) | p[1]; +#endif + return w; +} + +/* Do a endian load of a 32-bit code word. */ +static inline UInt getUInt(const UChar * p) +{ + return (getUShort(p) << 16) | getUShort(p + 2); +} + +const UChar GPR3_list[] = { 16, 17, 18, 19, 4, 5, 6, 7 }; +const UChar GPR4_list[] = { 8, 9, 10, 11, 4, 5, 6, 7, 16, 17, 18, 19, + 20, 21, 22, 23 + }; +const UChar GPR4_zero_list[] = { 8, 9, 10, 0, 4, 5, 6, 7, 16, 17, 18, + 19, 20, 21, 22, 23 + }; +const UChar GPR3_src_store_list[] = { 0, 17, 18, 19, 4, 5, 6, 7 }; +const UChar GPR2_reg1_list[] = { 4, 5, 6, 7 }; +const UChar GPR2_reg2_list[] = { 5, 6, 7, 8 }; + +static UInt integerGuestRegOffset(UInt iregNo) +{ + /* Maybe we should use formula ??? */ + switch (iregNo) { + case 0: + return offsetof(VexGuestMIPS32State, guest_r0); + + case 1: + return offsetof(VexGuestMIPS32State, guest_r1); + + case 2: + return offsetof(VexGuestMIPS32State, guest_r2); + + case 3: + return offsetof(VexGuestMIPS32State, guest_r3); + + case 4: + return offsetof(VexGuestMIPS32State, guest_r4); + + case 5: + return offsetof(VexGuestMIPS32State, guest_r5); + + case 6: + return offsetof(VexGuestMIPS32State, guest_r6); + + case 7: + return offsetof(VexGuestMIPS32State, guest_r7); + + case 8: + return offsetof(VexGuestMIPS32State, guest_r8); + + case 9: + return offsetof(VexGuestMIPS32State, guest_r9); + + case 10: + return offsetof(VexGuestMIPS32State, guest_r10); + + case 11: + return offsetof(VexGuestMIPS32State, guest_r11); + + case 12: + return offsetof(VexGuestMIPS32State, guest_r12); + + case 13: + return offsetof(VexGuestMIPS32State, guest_r13); + + case 14: + return offsetof(VexGuestMIPS32State, guest_r14); + + case 15: + return offsetof(VexGuestMIPS32State, guest_r15); + + case 16: + return offsetof(VexGuestMIPS32State, guest_r16); + + case 17: + return offsetof(VexGuestMIPS32State, guest_r17); + + case 18: + return offsetof(VexGuestMIPS32State, guest_r18); + + case 19: + return offsetof(VexGuestMIPS32State, guest_r19); + + case 20: + return offsetof(VexGuestMIPS32State, guest_r20); + + case 21: + return offsetof(VexGuestMIPS32State, guest_r21); + + case 22: + return offsetof(VexGuestMIPS32State, guest_r22); + + case 23: + return offsetof(VexGuestMIPS32State, guest_r23); + + case 24: + return offsetof(VexGuestMIPS32State, guest_r24); + + case 25: + return offsetof(VexGuestMIPS32State, guest_r25); + + case 26: + return offsetof(VexGuestMIPS32State, guest_r26); + + case 27: + return offsetof(VexGuestMIPS32State, guest_r27); + + case 28: + return offsetof(VexGuestMIPS32State, guest_r28); + + case 29: + return offsetof(VexGuestMIPS32State, guest_r29); + + case 30: + return offsetof(VexGuestMIPS32State, guest_r30); + + case 31: + return offsetof(VexGuestMIPS32State, guest_r31); + } + + vassert(0); + return 0; +} + +/* Add a statement to the list held by "irsb". */ +static void stmt(IRStmt * st) +{ + addStmtToIRSB(irsb, st); +} + +static IRExpr *mkU8(UInt i) +{ + vassert(i < 256); + return IRExpr_Const(IRConst_U8((UChar) i)); +} + +/* Create an expression node for a 32-bit integer constant. */ +static IRExpr *mkU32(UInt i) +{ + return IRExpr_Const(IRConst_U32(i)); +} + +static IRExpr *mkU64(ULong i) +{ + return IRExpr_Const(IRConst_U64(i)); +} + +static void putPC(IRExpr * e) +{ + stmt(IRStmt_Put(OFFB_PC, e)); +} + +static void putIReg(UInt archreg, IRExpr * e) +{ + vassert(archreg < 32); + + if (archreg != 0) + stmt(IRStmt_Put(integerGuestRegOffset(archreg), e)); +} + +static IRExpr *getIReg(UInt iregNo) +{ + if (0 == iregNo) { + return mkU32(0x0); + } else { + IRType ty = Ity_I32; + vassert(iregNo < 32); + return IRExpr_Get(integerGuestRegOffset(iregNo), ty); + } +} + +static void putLLaddr(IRExpr * e) +{ + stmt(IRStmt_Put(offsetof(VexGuestMIPS32State, guest_LLaddr), e)); +} + +static IRExpr *getLLaddr(void) +{ + return IRExpr_Get(offsetof(VexGuestMIPS32State, guest_LLaddr), Ity_I32); +} + +static void putLLdata(IRExpr * e) +{ + stmt(IRStmt_Put(offsetof(VexGuestMIPS32State, guest_LLdata), e)); +} + +static IRExpr *getLLdata(void) +{ + return IRExpr_Get(offsetof(VexGuestMIPS32State, guest_LLdata), Ity_I32); +} + +static void putLLdata64(IRExpr * e) +{ + stmt(IRStmt_Put(offsetof(VexGuestMIPS32State, guest_LLdata64), e)); +} + +static IRExpr *getLLdata64(void) +{ + return IRExpr_Get(offsetof(VexGuestMIPS32State, guest_LLdata64), Ity_I64); +} + +static IRExpr *unop(IROp op, IRExpr * a) +{ + return IRExpr_Unop(op, a); +} + +static IRExpr *binop(IROp op, IRExpr * a1, IRExpr * a2) +{ + return IRExpr_Binop(op, a1, a2); +} + +/* Generate a new temporary of the given type. */ +static IRTemp newTemp(IRType ty) +{ + vassert(isPlausibleIRType(ty)); + return newIRTemp(irsb->tyenv, ty); +} + +static void assign(IRTemp dst, IRExpr * e) +{ + stmt(IRStmt_WrTmp(dst, e)); +} + +static void store(IRExpr * addr, IRExpr * data) +{ +#if defined (_MIPSEL) + stmt(IRStmt_Store(Iend_LE, addr, data)); +#elif defined (_MIPSEB) + stmt(IRStmt_Store(Iend_BE, addr, data)); +#endif +} + +static IRExpr *load(IRType ty, IRExpr * addr) +{ + IRExpr *load1 = NULL; +#if defined (_MIPSEL) + load1 = IRExpr_Load(Iend_LE, ty, addr); +#elif defined (_MIPSEB) + load1 = IRExpr_Load(Iend_BE, ty, addr); +#endif + return load1; +} + +static IRExpr *mkexpr(IRTemp tmp) +{ + return IRExpr_RdTmp(tmp); +} + +static UInt extend_sign(UInt value, UChar from_nbits) +{ + UChar shift = 32 - from_nbits; + return (UInt)((((Int) value) << shift) >> shift); +} + +static void ir_for_branch(DisResult *dres, IRExpr *guard, UChar length, + Int offset) +{ + dres->whatNext = Dis_StopHere; + dres->jk_StopHere = Ijk_Boring; + stmt(IRStmt_Exit(guard, Ijk_Boring, + IRConst_U32(guest_PC_curr_instr + length + offset), + OFFB_PC)); + putPC(mkU32(guest_PC_curr_instr + length)); +} + +static void nano_plsu12(DisResult *dres, UInt cins) +{ + UChar rs = (cins >> 16) & 0x1F; + UChar rt = (cins >> 21) & 0x1F; + UShort u = cins & 0x0FFF; + + switch ((cins >> 12) & 0x0F) { + case PLSU12_LB: { /* lb[u12] */ + DIP("lb[u12] r%u %u(r%u)", rt, u, rs); + putIReg(rt, unop(Iop_8Sto32, + load(Ity_I8, binop(Iop_Add32, getIReg(rs), mkU32(u))))); + break; + } + + case PLSU12_LH: { /* lh[u12] */ + DIP("lh[u12] r%u %u(r%u)", rt, u, rs); + putIReg(rt, unop(Iop_16Sto32, + load(Ity_I16, binop(Iop_Add32, getIReg(rs), mkU32(u))))); + break; + } + + case PLSU12_LW: { /* lw[u12] */ + DIP("lw[u12] r%u %u(r%u)", rt, u, rs); + putIReg(rt, load(Ity_I32, binop(Iop_Add32, getIReg(rs), mkU32(u)))); + break; + } + + case PLSU12_LD: { /* ld[u12] */ + DIP("ld[u12] r%u %u(r%u)", rt, u, rs); + vassert(0); + break; + } + + case PLSU12_SB: { /* sb[u12] */ + DIP("sb[12] r%u %u(r%u)", rt, u, rs); + store(binop(Iop_Add32, getIReg(rs), mkU32(u)), unop(Iop_32to8, getIReg(rt))); + break; + } + + case PLSU12_SH: { /* sh[u12] */ + DIP("sh[u12] r%u %u(r%u)", rt, u, rs); + store(binop(Iop_Add32, getIReg(rs), mkU32(u)), unop(Iop_32to16, getIReg(rt))); + break; + } + + case PLSU12_SW: { /* sw[u12] */ + DIP("sw[u12] r%u, %u(r%u)", rt, u, rs); + store(binop(Iop_Add32, getIReg(rs), mkU32(u)), getIReg(rt)); + break; + } + + case PLSU12_SD: { /* sd[u12] */ + DIP("sd[u12] r%u, %u(r%u)", rt, u, rs); + vassert(0); + } + + case PLSU12_LBU: { /* lbu[u12] */ + DIP("lbu r%u, %u(r%u)", rt, u, rs); + putIReg(rt, unop(Iop_8Uto32, + load(Ity_I8, binop(Iop_Add32, getIReg(rs), mkU32(u))))); + break; + } + + case PLSU12_LHU: { /* lhu[u12] */ + DIP("lhu[u12] r%u %u(r%u)", rt, u, rs); + putIReg(rt, unop(Iop_16Uto32, + load(Ity_I16, binop(Iop_Add32, getIReg(rs), mkU32(u))))); + break; + } + + case PLSU12_LWC1: { /* lwc1[u12] */ + DIP("lwc1[u12] r%u %u(r%u)", rt, u, rs); + vassert(0); + break; + } + + case PLSU12_LDC1: { /* ldc1[u12] */ + DIP("ldc1[u12] r%u %u(r%u)", rt, u, rs); + vassert(0); + break; + } + + case PLSU12_PREF: { /* pref[u12] */ + DIP("pref[u12] r%u %u(r%u)", rt, u, rs); + break; + } + + case PLSU12_LWU: { /* lwu[u12] */ + DIP("lwu[u12] r%u %u(r%u)", rt, u, rs); + vassert(0); + break; + } + + case PLSU12_SWC1: { /* swc1[u12] */ + DIP("swc1[u12] r%u %u(r%u)", rt, u, rs); + vassert(0); + break; + } + + case PLSU12_SDC1: { /* sdc1[u12] */ + DIP("sdc1[u12] r%u %u(r%u)", rt, u, rs); + vassert(0); + break; + } + + default: + vassert(0); + } +} + +static void nano_pl32a0(DisResult *dres, UInt cins) +{ + UChar rd = (cins >> 11) & 0x1F; + UChar rs = (cins >> 16) & 0x1F; + UChar rt = (cins >> 21) & 0x1F; + IRTemp t1 = newTemp(Ity_I32); + IRTemp t2 = newTemp(Ity_I64); + + switch ((cins >> 3) & 0x07F) { + case _POOL32A0_PTRAP: { + if ((cins >> 10) & 0x01) { /* tne */ + DIP("tne r%u, r%u", rs, rt); + stmt(IRStmt_Exit(binop(Iop_CmpNE32, getIReg(rs), + getIReg(rt)), Ijk_SigTRAP, + IRConst_U32(guest_PC_curr_instr + 4), + OFFB_PC)); + } else { /* teq */ + DIP("teq r%u, r%u", rs, rt); + stmt(IRStmt_Exit(binop(Iop_CmpEQ32, getIReg(rs), + getIReg(rt)), Ijk_SigTRAP, + IRConst_U32(guest_PC_curr_instr + 4), + OFFB_PC)); + } + + break; + } + + case _POOL32A0_SEB: { /* seb */ + DIP("seb r%u, r%u", rs, rt); + putIReg(rt, unop(Iop_8Sto32, unop(Iop_32to8, getIReg(rs)))); + break; + } + + case _POOL32A0_SEH: { /* seh */ + DIP("seh r%u, r%u", rs, rt); + putIReg(rt, unop(Iop_16Sto32, unop(Iop_32to16, getIReg(rs)))); + break; + } + + case _POOL32A0_SLLV: { /* sllv */ + DIP("sllv r%u, r%u, r%u", rd, rs, rt); + assign(t1, binop(Iop_And32, getIReg(rt), mkU32(0x1f))); + putIReg(rd, binop(Iop_Shl32, getIReg(rs), unop(Iop_32to8, + mkexpr(t1)))); + break; + } + + case _POOL32A0_MUL32: { /* mul */ + DIP("mul[32] r%u, r%u, r%u", rd, rs, rt); + putIReg(rd, unop(Iop_64to32, binop(Iop_MullS32, getIReg(rt), + getIReg(rs)))); + break; + } + + case _POOL32A0_MUH: { /* muh */ + DIP("muh r%u, r%u, r%u", rd, rs, rt); + putIReg(rd, unop(Iop_64HIto32, binop(Iop_MullS32, getIReg(rt), + getIReg(rs)))); + break; + } + + case _POOL32A0_MULU: { /* mulu */ + DIP("mulu r%u, r%u, r%u", rd, rs, rt); + putIReg(rd, unop(Iop_64to32, binop(Iop_MullU32, getIReg(rt), + getIReg(rs)))); + break; + } + + case _POOL32A0_MUHU: { /* muhu */ + DIP("muhu r%u, r%u, r%u", rd, rs, rt); + putIReg(rd, unop(Iop_64HIto32, binop(Iop_MullU32, getIReg(rt), + getIReg(rs)))); + break; + } + + case _POOL32A0_DIV: { /* div */ + DIP("div r%u, r%u, r%u", rd, rs, rt); + putIReg(rd, binop(Iop_DivS32, getIReg(rs), getIReg(rt))); + break; + } + + case _POOL32A0_MOD: { /* mod */ + DIP("mod r%u, r%u, r%u", rd, rs, rt); + putIReg(rd, unop(Iop_64HIto32, binop(Iop_DivModS32to32, getIReg(rs), + getIReg(rt)))); + break; + } + + case _POOL32A0_DIVU: { /* divu */ + DIP("divu r%u, r%u, r%u", rd, rs, rt); + putIReg(rd, binop(Iop_DivU32, getIReg(rs), getIReg(rt))); + break; + } + + case _POOL32A0_MODU: { /* modu */ + DIP("modu r%u, r%u, r%u", rd, rs, rt); + putIReg(rd, unop(Iop_64HIto32, binop(Iop_DivModU32to32, getIReg(rs), + getIReg(rt)))); + break; + } + + case _POOL32A0_SRLV: { /* srlv */ + DIP("srlv r%u, r%u, r%u", rd, rs, rt); + assign(t1, binop(Iop_And32, getIReg(rt), mkU32(0x1f))); + putIReg(rd, binop(Iop_Shr32, + getIReg(rs), unop(Iop_32to8, mkexpr(t1)))); + break; + } + + case _POOL32A0_SRAV: { /* srav */ + DIP("srav r%u, r%u, r%u", rd, rs, rt); + assign(t1, binop(Iop_And32, getIReg(rt), mkU32(0x1f))); + putIReg(rd, binop(Iop_Sar32, + getIReg(rs), unop(Iop_32to8, mkexpr(t1)))); + break; + } + + case _POOL32A0_ROTRV: { /* rotrv */ + DIP("rotv r%u, r%u, r%u", rd, rs, rt); + assign(t1, binop(Iop_And32, getIReg(rt), mkU32(0x1f))); + assign(t2, binop(Iop_32HLto64, getIReg(rs), getIReg(rs))); + putIReg(rd, unop(Iop_64to32, + binop(Iop_Shr64, + mkexpr(t2), unop(Iop_32to8, mkexpr(t1))))); + break; + } + + case _POOL32A0_AND32: { /* and[32] */ + DIP("and[32] r%u, r%u, r%u", rd, rs, rt); + putIReg(rd, binop(Iop_And32, getIReg(rs), getIReg(rt))); + break; + } + + case _POOL32A0_ADD: { /* add */ + DIP("add r%u, r%u, r%u", rd, rs, rt); + // if overflows(sum, nbits=32): raise exception('OV') + putIReg(rd, binop(Iop_Add32, getIReg(rs), getIReg(rt))); + break; + } + + case _POOL32A0_ADDU32: { /* addu[32] */ + DIP("addu[32] r%u, r%u, r%u", rd, rs, rt); + putIReg(rd, binop(Iop_Add32, getIReg(rs), getIReg(rt))); + break; + } + + case _POOL32A0_SUB: { /* sub */ + DIP("sub r%u, r%u, r%u", rd, rs, rt); + // if overflows(result, nbits=32): raise exception('OV') + putIReg(rd, binop(Iop_Sub32, getIReg(rs), getIReg(rt))); + break; + } + + case _POOL32A0_SUBU32: { /* subu[32] */ + DIP("subu[32] r%u, r%u, r%u", rd, rs, rt); + putIReg(rd, binop(Iop_Sub32, getIReg(rs), getIReg(rt))); + break; + } + + case _POOL32A0_OR32: { /* or[32] */ + DIP("or[32] r%u, r%u, r%u", rd, rs, rt); + putIReg(rd, binop(Iop_Or32, getIReg(rs), getIReg(rt))); + break; + } + + case _POOL32A0_NOR: { /* nor */ + DIP("nor r%u, r%u, r%u", rd, rs, rt); + putIReg(rd, unop(Iop_Not32, binop(Iop_Or32, getIReg(rs), + getIReg(rt)))); + break; + } + + case _POOL32A0_XOR32: { /* xor[32] */ + DIP("xor[32] r%u, r%u, r%u", rd, rs, rt); + putIReg(rd, binop(Iop_Xor32, getIReg(rs), getIReg(rt))); + break; + } + + case _POOL32A0_SLT: { /* slt */ + DIP("slt r%u, r%u, r%u", rd, rs, rt); + putIReg(rd, unop(Iop_1Uto32, binop(Iop_CmpLT32S, getIReg(rs), + getIReg(rt)))); + break; + } + + case _POOL32A0_PSLTU: { /* p.sltu */ + if (rd == 0) { + vassert(0); + } else { /* sltu */ + DIP("sltu r%u, r%u, r%u", rd, rs, rt); + putIReg(rd, unop(Iop_1Uto32, binop(Iop_CmpLT32U, getIReg(rs), + getIReg(rt)))); + } + + break; + } + + case _POOL32A0_SOV: { /* sov */ + IRTemp t33 = newTemp(Ity_I32); + IRTemp t0 = newTemp(Ity_I32); + DIP("sov r%u, r%u, r%u", rd, rs, rt); + assign(t1, binop(Iop_Add32, getIReg(rs), getIReg(rt))); + assign(t33, binop(Iop_Add32, + binop(Iop_Sar32, getIReg(rs), mkU8(1)), + binop(Iop_Sar32, getIReg(rt), mkU8(1)))); + assign(t0, binop(Iop_And32, + binop(Iop_And32, + getIReg(rs), getIReg(rt)), mkU32(1))); + putIReg(rd, unop(Iop_1Uto32, + binop(Iop_CmpNE32, + binop(Iop_Sar32, mkexpr(t1), mkU8(1)), + binop(Iop_Add32, mkexpr(t33), mkexpr(t0))))); + // GPR[rd] = 1 if overflows(sum, nbits=32) else 0 + break; + } + + case _POOL32A0_PCMOVE: { /* p.cmove */ + if (cins & 0x400) { /* movn */ + DIP("movn r%u, r%u, r%u", rd, rs, rt); + putIReg(rd, IRExpr_ITE(binop(Iop_CmpNE32, getIReg(rt), mkU32(0x00)), + getIReg(rs), getIReg(rd))); + } else { /* movz */ + DIP("movz r%u, r%u, r%u", rd, rs, rt); + putIReg(rd, IRExpr_ITE(binop(Iop_CmpEQ32, getIReg(rt), mkU32(0x00)), + getIReg(rs), getIReg(rd))); + } + + break; + } + + case _POOL32A0_RDHWR: /* RDHWR */ + DIP("rdhwr r%u, r%u", rt, rs); + + if (rs == 29) { + putIReg(rt, IRExpr_Get(offsetof(VexGuestMIPS32State, guest_ULR), + Ity_I32)); + break; + } else if (rs <= 3) { + IRExpr** arg = mkIRExprVec_1(mkU32(rs)); + IRTemp val = newTemp(Ity_I32); + IRDirty *d = unsafeIRDirty_1_N(val, + 0, + "nanomips_dirtyhelper_rdhwr", + &nanomips_dirtyhelper_rdhwr, + arg); + stmt(IRStmt_Dirty(d)); + putIReg(rt, mkexpr(val)); + break; + } else { + vex_printf("Unsupported RDHWR variant"); + vassert(0); + } + + default: + vex_printf("Unrecognized _POOL32A0 instruction %08X", + (cins >> 3) & 0x07F); + vassert(0); + } +} + +static void nano_pplsx(DisResult *dres, UInt cins) +{ + UChar rd = (cins >> 11) & 0x1F; + UChar rs = (cins >> 16) & 0x1F; + UChar rt = (cins >> 21) & 0x1F; + + switch ((cins >> 7) & 0x0F) { + case LBX: { /* lbx */ + DIP("lbx r%u, %u(r%u)", rd, rs, rt); + putIReg(rd, unop(Iop_8Sto32, + load(Ity_I8, + binop(Iop_Add32, getIReg(rs), getIReg(rt))))); + break; + } + + case SBX: { /* sbx */ + DIP("sbx r%u %u(r%u)", rd, rs, rt); + store(binop(Iop_Add32, getIReg(rs), getIReg(rt)), + unop(Iop_32to8, getIReg(rd))); + break; + } + + case LBUX: { /* lbux */ + DIP("lbux r%u, %u(r%u)", rd, rs, rt); + putIReg(rd, unop(Iop_8Uto32, + load(Ity_I8, + binop(Iop_Add32, getIReg(rs), getIReg(rt))))); + break; + } + + case LHX: { + DIP("lhx r%u, %u(r%u)", rd, rs, rt); + putIReg(rd, unop(Iop_16Sto32, + load(Ity_I16, + binop(Iop_Add32, getIReg(rs), getIReg(rt))))); + break; + } + + case SHX: { + DIP("shx r%u %u(r%u)", rd, rs, rt); + store(binop(Iop_Add32, getIReg(rs), getIReg(rt)), unop(Iop_32to16, + getIReg(rd))); + break; + } + + case LHUX: { + DIP("lbux r%u, %u(r%u)", rd, rs, rt); + putIReg(rd, unop(Iop_16Uto32, + load(Ity_I16, + binop(Iop_Add32, getIReg(rs), getIReg(rt))))); + break; + } + + case LWX: { + DIP("lwx r%u, %u(r%u)", rd, rs, rt); + putIReg(rd, load(Ity_I32, binop(Iop_Add32, getIReg(rs), getIReg(rt)))); + break; + } + + case SWX: { + DIP("swx r%u %u(r%u)", rd, rs, rt); + store(binop(Iop_Add32, getIReg(rs), getIReg(rt)), getIReg(rd)); + break; + } + + default: + vassert(0); + break; + } +} + +static void nano_pplsxs(DisResult *dres, UInt cins) +{ + UChar rd = (cins >> 11) & 0x1F; + UChar rs = (cins >> 16) & 0x1F; + UChar rt = (cins >> 21) & 0x1F; + + switch ((cins >> 7) & 0x0F) { + case LHXS: { + DIP("lhxs r%u, %u(r%u)", rd, rs, rt); + putIReg(rd, unop(Iop_16Sto32, + load(Ity_I16, + binop(Iop_Add32, + binop(Iop_Shl32, getIReg(rs), mkU8(0x01)), + getIReg(rt))))); + break; + } + + case SHXS: { + DIP("shxs r%u %u(r%u)", rd, rs, rt); + store(binop(Iop_Add32, + binop(Iop_Shl32, getIReg(rs), mkU8(0x01)), + getIReg(rt)), + unop(Iop_32to16, getIReg(rd))); + break; + } + + case LHUXS: { + DIP("lbuxs r%u, %u(r%u)", rd, rs, rt); + putIReg(rd, unop(Iop_16Uto32, + load(Ity_I16, + binop(Iop_Add32, + binop(Iop_Shl32, getIReg(rs), mkU8(0x01)), + getIReg(rt))))); + break; + } + + case LWXS32: { + DIP("lwxs[32] r%u, r%u(r%u)", rd, rs, rt); + putIReg(rd, load(Ity_I32, + binop(Iop_Add32, + binop(Iop_Shl32, getIReg(rs), mkU8(0x02)), + getIReg(rt)))); + break; + } + + case SWXS: { + DIP("swxs r%u %u(r%u)", rd, rs, rt); + store(binop(Iop_Add32, + binop(Iop_Shl32, getIReg(rs), mkU8(0x02)), + getIReg(rt)), + getIReg(rd)); + break; + } + + default: + vassert(0); + break; + } +} + +static void nano_plsx(DisResult *dres, UInt cins) +{ + if ((cins >> 6) & 0x01) { + nano_pplsxs(dres, cins); + } else { + nano_pplsx(dres, cins); + } +} + +static void nano_pool32Axf_4(DisResult *dres, UInt cins) +{ + UChar rs = (cins >> 16) & 0x1F; + UChar rt = (cins >> 21) & 0x1F; + IRTemp t1; + + switch ((cins >> 9) & 0x7F) { + case nano_POOL32Axf4_CLO: { /* clo */ + DIP("clo r%u, r%u", rt, rs); + t1 = newTemp(Ity_I1); + assign(t1, binop(Iop_CmpEQ32, getIReg(rs), mkU32(0xffffffff))); + putIReg(rt, IRExpr_ITE(mkexpr(t1), + mkU32(0x00000020), + unop(Iop_Clz32, + unop(Iop_Not32, getIReg(rs))))); + break; + } + + case nano_POOL32Axf4_CLZ: { /* clz */ + DIP("clz r%u, r%u", rt, rs); + putIReg(rt, unop(Iop_Clz32, getIReg(rs))); + break; + } + } +} + +static void nano_p32Axf(DisResult *dres, UInt cins) +{ + switch ((cins >> 6) & 0x7) { + case POOL32aXF_4: + nano_pool32Axf_4(dres, cins); + break; + + case POOL32aXF_5: + vassert(0); + break; + + default: + vex_printf("Unrecognized pool32Axf instruction %08X\n", cins); + vassert(0); + break; + } +} + +static void nano_pool32a7(DisResult *dres, UInt cins) +{ + UChar rd = (cins >> 11) & 0x1F; + UChar rs = (cins >> 16) & 0x1F; + UChar rt = (cins >> 21) & 0x1F; + UChar u2 = (cins >> 9) & 0x03; + UChar shift = (cins >> 6) & 0x1F; + + switch ((cins >> 3) & 7) { + case _POOL32A7_PLSX: + nano_plsx(dres, cins); + break; + + case _POOL32A7_LSA: { /* lsa */ + DIP("lsa r%u r%u, r%u", rd, rs, rt); + putIReg(rd, binop(Iop_Add32, binop(Iop_Shl32, getIReg(rs), mkU8(u2)), + getIReg(rt))); + break; + } + + case _POOL32A7_EXTW: { /*extw*/ + DIP("extw r%u r%u, r%u, %u", rd, rs, rt, shift); + IRTemp t1 = newTemp(Ity_I64); + assign(t1, binop(Iop_32HLto64, getIReg(rt), getIReg(rs))); + putIReg(rd, unop(Iop_64to32, binop(Iop_Shr64, mkexpr(t1), + mkU8(shift)))); + break; + } + + case _POOL32A7_P32Axf: { + nano_p32Axf(dres, cins); + break; + } + + default: + vex_printf("Unrecognized _POOL32A7 instruction %08X", cins); + vassert(0); + } +} + +static void nano_p32a(DisResult *dres, UInt cins) +{ + switch (cins & 0x7) { + case P32A_POOL32A0: + nano_pl32a0(dres, cins); + break; + + case P32A_POOL32A7: + nano_pool32a7(dres, cins); + break; + + default: + vex_printf("Unrecognized P32A instruction %08X", cins); + vassert(0); + } +} + +static void nano_pbal(DisResult *dres, UInt cins) +{ + Int s = extend_sign((cins & 0x1FFFFFE) | ((cins & 1) << 25), 26); + + if (cins & 0x2000000) { /* BALC[32] */ + DIP("balc %0X", guest_PC_curr_instr + 4 + s); + putIReg(31, mkU32(guest_PC_curr_instr + 4)); + dres->jk_StopHere = Ijk_Call; + } else { /* BC[32] */ + DIP("bc %0X", guest_PC_curr_instr + 4 + s); + dres->jk_StopHere = Ijk_Boring; + } + + putPC(mkU32(guest_PC_curr_instr + 4 + s)); + dres->whatNext = Dis_StopHere; +} + +static void nano_ppsr(DisResult *dres, UInt cins) +{ + UInt u = cins & 0xFF8; + UChar count = (cins >> 16) & 0x0F; + UChar rt = (cins >> 21) & 0x1F; + UChar counter = 0; + Bool jr = True; + + switch (cins & 0x03) { + case 0x00: { /* save[32] */ + DIP("save %u, r%u-r%u", u, (rt & 0x1fu) | (rt & 0x10u), + ((rt + count - 1) & 0x1fu) | (rt & 0x10u)); + + 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)), + getIReg(this_rt)); + counter++; + } + + putIReg(29, binop(Iop_Sub32, getIReg(29), mkU32(u))); + break; + } + + case 0x02: /* restore[32] */ + jr = False; //falls through common restore(.jrc) implementation + + case 0x03: { /* restore.jrc[32] */ + DIP("restore%s %u, r%u-r%u", jr ? ".jrc" : "", u, + ((rt + count - 1) & 0x1fu) | (rt & 0x10u), + (rt & 0x1fu) | (rt & 0x10u)); + + while (counter != count) { + Bool use_gp = (cins & 0x04) && (counter + 1 == count); + UChar this_rt = use_gp ? 28 : ((rt + counter) & 0x1F) | (rt & 0x10); + Int offset = u - ((counter + 1) << 2); + putIReg(this_rt,load(Ity_I32, binop(Iop_Add32, + getIReg(29), mkU32(offset)))); + // if this_rt == 29: raise UNPREDICTABLE() + counter++; + } + + putIReg(29, binop(Iop_Add32, getIReg(29), mkU32(u))); + + if (jr) { + putPC(getIReg(31)); + dres->whatNext = Dis_StopHere; + dres->jk_StopHere = Ijk_Ret; + } + + break; + } + + default: + vassert(0); + } +} + +static void nano_psrf(UInt cins) +{ + switch (cins & 0x03) { + case 0x00: { /* savef */ + vex_printf("Instruction savef is missing documentation.\n"); + vassert(0); + break; + } + + case 0x02: { /* restoref */ + vex_printf("Instruction restoref is missing documentation.\n"); + vassert(0); + break; + } + + default: + vassert(0); + } +} + +static void nano_psr(DisResult *dres, UInt cins) +{ + switch ((cins >> 20) & 0x1) { + case 0x00: /* pp.sr */ + nano_ppsr(dres, cins); + break; + + case 0x01: /* p.sr.f */ + nano_psrf(cins); + break; + + default: + vassert(0); + break; + } +} + +static void nano_pri(DisResult *dres, UInt cins) +{ + switch ((cins >> 19) & 3) { + case PRI_SIGRIE: + ILLEGAL_INSTRUCTON + break; + + case PRI_PSYSCALL: + if (cins & 0x40000) { /* HYPCALL */ + vex_printf("Instruction HYPCALL is missing documentation.\n"); + vassert(0); + } else { /* SYSCALL[32] */ + DIP("syscall %u", cins & 0x3FFFF); + dres->jk_StopHere = Ijk_Sys_syscall; + dres->whatNext = Dis_StopHere; + } + + break; + + case PRI_BREAK: /* BREAK[32] */ + DIP("break %u", cins & 0x7FFFF); + dres->jk_StopHere = Ijk_SigTRAP; + dres->whatNext = Dis_StopHere; + break; + + case PRI_SDBBP: + vex_printf("Instruction SDBBP is not supported.\n"); + vassert(0); + break; + + default: + vassert(0); + } +} + +static void nano_psll(UInt cins) +{ + UChar rt = (cins >> 21) & 0x1F; + UChar rs = (cins >> 16) & 0x1F; + UChar shift = cins & 0x1F; + + if (rt == 0 && shift == 0) { /* nop[32] */ + DIP("nop[32]"); + return; + } + + if (rt == 0 && shift == 3) { /* ehb */ + DIP("ehb"); + vassert(0); + return; + } + + if (rt == 0 && shift == 5) { /* pause */ + DIP("pause"); + vassert(0); + // pause_until_llbit_clears(); + return; + } + + if (rt == 0 && shift == 6) { /* sync */ + DIP("sync 0x%x", rs); + /* Just ignore it. */ + return; + } + + DIP("sll r%u, r%u, %u", rt, rs, shift); + putIReg(rt, binop(Iop_Shl32, getIReg(rs), mkU8(shift))); + return; +} + +static void nano_pshift(UInt cins) +{ + UChar rt = (cins >> 21) & 0x1F; + UChar rs = (cins >> 16) & 0x1F; + UChar shift = cins & 0x1F; + + switch ((cins >> 5) & 0xF) { + case PSLL: { /* p.sll */ + nano_psll(cins); + break; + } + + case SRL32: /* srl[32] */ + DIP("srl[32] r%u, r%u, %u", rt, rs, shift); + putIReg(rt, binop(Iop_Shr32, getIReg(rs), mkU8(shift))); + break; + + case SRA: /* sra */ + DIP("sra r%u, r%u, %u", rt, rs, shift); + putIReg(rt, binop(Iop_Sar32, getIReg(rs), mkU8(shift))); + break; + + case ROTR: /* rotr */ + DIP("rotr r%u, r%u, %u", rt, rs, shift); + IRTemp t1 = newTemp(Ity_I64); + assign(t1, binop(Iop_32HLto64, getIReg(rs), getIReg(rs))); + putIReg(rt, unop(Iop_64to32, binop(Iop_Shr64, mkexpr(t1), + mkU8(shift)))); + break; + + case DSLL: { /* dsll */ + DIP("dsll r%u, r%u, %u", rt, rs, shift); + vassert(0); + break; + } + + case DSLL32: { /* dsll32 */ + DIP("dsll32 r%u, r%u, %u", rt, rs, shift); + vassert(0); + break; + } + + case DSRL: { /* dsrl */ + DIP("dsrl r%u, r%u, %u", rt, rs, shift); + vassert(0); + break; + } + + case DSRL32: { /* dsrl32 */ + DIP("dsrl32 r%u, r%u, %u", rt, rs, shift); + vassert(0); + break; + } + + case DSRA: { /* dsra */ + DIP("dsra r%u, r%u, %u", rt, rs, shift); + vassert(0); + break; + } + + case DSRA32: { /* dsra32 */ + DIP("dsra32 r%u, r%u, %u", rt, rs, shift); + vassert(0); + break; + } + + case DROTR: { /* drotr */ + DIP("drotr r%u, r%u, %u", rt, rs, shift); + vassert(0); + break; + } + + case DROTR32: { /* drotr32 */ + DIP("drotr32 r%u, r%u, %u", rt, rs, shift); + vassert(0); + break; + } + + default: + vassert(0); + } +} + +static void nano_protx(UInt cins) +{ + UChar rt = (cins >> 21) & 0x1F; + UChar rs = (cins >> 16) & 0x1F; + UChar shift = cins & 0x1F; + UChar shiftx = ((cins >> 7) & 0xF) << 1; + UChar stripe = (cins & 0x40) ? 1 : 0; + + switch ((cins >> 5) & 0x41) { + case 0x00: { /* rotx */ + int i; + IRTemp t0 = newTemp(Ity_I64); + IRTemp t1 = newTemp(Ity_I64); + IRTemp t2 = newTemp(Ity_I64); + IRTemp t3 = newTemp(Ity_I64); + IRTemp t4 = newTemp(Ity_I64); + IRTemp t5 = newTemp(Ity_I64); + IRTemp tmp = newTemp(Ity_I64); + IRTemp s = newTemp(Ity_I32); + DIP("rotx r%u, r%u, %u, %u, %u", rt, rs, shift, shiftx, stripe); + assign(t0, binop(Iop_Or64, getIReg(rs), binop(Iop_Shl64, + getIReg(rs), mkU8(32)))); + assign(t1, mkexpr(t0)); + + for (i = 0; i < 46; i++) { + assign(s, IRExpr_ITE(binop(Iop_And32, mkU32(i), mkU32(0x08)), + mkU32(shift), mkU32(shiftx))); + assign(s, IRExpr_ITE(binop(Iop_And32, mkU32(stripe), + binop(Iop_CmpNE32, mkU32(0x0), + binop(Iop_And32, + mkU32(i), mkU32(0x04)))), + unop(Iop_Not32, mkU32(s)), mkexpr(s))); + assign(tmp, binop(Iop_Or64, binop(Iop_And64, + binop(Iop_Shr64, mkexpr(t0), + mkU8(0x10)), + binop(Iop_Shl64, mkU64(0x01), + mkU8(i))), + binop(Iop_And64, mkexpr(t1), + unop(Iop_Not64, + binop(Iop_Shl64, mkU64(0x01), + mkU8(i)))))); + assign(t1, IRExpr_ITE(binop(Iop_And32, mkexpr(s), mkU32(0x10)), + mkexpr(tmp), + mkexpr(t1))); + + } + + assign(t2, mkexpr(t1)); + + for (i = 0; i < 38; i++) { + assign(s, IRExpr_ITE(binop(Iop_And32, mkU32(i), mkU32(0x04)), + mkU32(shift), mkU32(shiftx))); + assign(tmp, binop(Iop_Or64, + binop(Iop_And64, + binop(Iop_Shr64, mkexpr(t1), mkU8(0x08)), + binop(Iop_Shl64, mkU64(0x01), mkU8(i))), + binop(Iop_And64, mkexpr(t2), + unop(Iop_Not64, binop(Iop_Shl64, + mkU64(0x01), + mkU8(i)))))); + assign(t2, IRExpr_ITE(binop(Iop_And32, mkexpr(s), mkU32(0x08)), + mkexpr(tmp), + mkexpr(t2))); + + } + + assign(t3, mkexpr(t2)); + + for (i = 0; i < 34; i++) { + assign(s, IRExpr_ITE(binop(Iop_And32, mkU32(i), mkU32(0x02)), + mkU32(shift), mkU32(shiftx))); + assign(tmp, binop(Iop_Or64, + binop(Iop_And64, + binop(Iop_Shr64, mkexpr(t2), mkU8(0x04)), + binop(Iop_Shl64, mkU64(0x01), mkU8(i))), + binop(Iop_And64, mkexpr(t3), + unop(Iop_Not64, binop(Iop_Shl64, + mkU64(0x01), + mkU8(i)))))); + assign(t3, IRExpr_ITE(binop(Iop_And32, mkexpr(s), mkU32(0x04)), + mkexpr(tmp), + mkexpr(t3))); + + } + + assign(t4, mkexpr(t3)); + + for (i = 0; i < 32; i++) { + assign(s, IRExpr_ITE(binop(Iop_And32, mkU32(i), mkU32(0x01)), + mkU32(shift), mkU32(shiftx))); + assign(tmp, binop(Iop_Or64, + binop(Iop_And64, + binop(Iop_Shr64, mkexpr(t3), mkU8(0x02)), + binop(Iop_Shl64, mkU64(0x01), mkU8(i))), + binop(Iop_And64, mkexpr(t4), + unop(Iop_Not64, binop(Iop_Shl64, + mkU64(0x01), + mkU8(i)))))); + assign(t4, IRExpr_ITE(binop(Iop_And32, mkexpr(s), mkU32(0x02)), + mkexpr(tmp), + mkexpr(t4))); + + } + + assign(t5, mkexpr(t4)); + + for (i = 0; i < 32; i++) { + assign(tmp, binop(Iop_Or64, + binop(Iop_And64, + binop(Iop_Shr64, mkexpr(t4), mkU8(0x01)), + binop(Iop_Shl64, mkU64(0x01), mkU8(i))), + binop(Iop_And64, mkexpr(t5), + unop(Iop_Not64, binop(Iop_Shl64, + mkU64(0x01), + mkU8(i)))))); + assign(t4, IRExpr_ITE(binop(Iop_And32, mkexpr(shift), mkU32(0x02)), + mkexpr(tmp), + mkexpr(t5))); + + } + + putIReg(rt, mkexpr(t5)); + break; + } + + default: + vassert(0); + break; + } + +} + +static void nano_pins(UInt cins) +{ + UChar rt = (cins >> 21) & 0x1F; + UChar rs = (cins >> 16) & 0x1F; + UChar lsb = cins & 0x1F; + UChar msbd = (cins >> 6) & 0x1F; + + switch ((cins >> 5) & 0x41) { + case 0x00: { /* ins */ + UChar size = 1 + msbd - lsb; + DIP("ins r%u, r%u, %u, %u", rt, rs, lsb, size); + UInt mask = ((1 << size) - 1) << lsb; + putIReg(rt, binop(Iop_Or32, binop(Iop_And32, getIReg(rt), + mkU32(~mask)), + binop(Iop_And32, + binop(Iop_Shl32, + ... [truncated message content] |
|
From: Petar J. <pe...@so...> - 2019-08-21 17:09:50
|
https://sourceware.org/git/gitweb.cgi?p=valgrind.git;h=cb366f2680a7e2a30fcd5a06a73e59c34b68722d commit cb366f2680a7e2a30fcd5a06a73e59c34b68722d Author: Petar Jovanovic <mip...@gm...> Date: Wed Aug 21 12:47:11 2019 +0000 mips32: hook up vmsplice syscall Hook up vmsplice syscall for mips32. This fixes vmsplice01 failure in the LTP test suite. Diff: --- coregrind/m_syswrap/syswrap-mips32-linux.c | 1 + 1 file changed, 1 insertion(+) diff --git a/coregrind/m_syswrap/syswrap-mips32-linux.c b/coregrind/m_syswrap/syswrap-mips32-linux.c index 9512510..ace3c1e 100644 --- a/coregrind/m_syswrap/syswrap-mips32-linux.c +++ b/coregrind/m_syswrap/syswrap-mips32-linux.c @@ -1063,6 +1063,7 @@ static SyscallTableEntry syscall_main_table[] = { LINX_ (__NR_splice, sys_splice), // 304 PLAX_ (__NR_sync_file_range, sys_sync_file_range), // 305 LINX_ (__NR_tee, sys_tee), // 306 + LINXY (__NR_vmsplice, sys_vmsplice), // 307 //.. LINX_ (__NR_set_robust_list, sys_set_robust_list), // 309 LINXY (__NR_get_robust_list, sys_get_robust_list), // 310 |