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
(17) |
2
(8) |
3
(23) |
4
(16) |
5
(13) |
6
(13) |
|
7
|
8
|
9
|
10
(2) |
11
(4) |
12
(2) |
13
(14) |
|
14
(13) |
15
(7) |
16
(13) |
17
(20) |
18
(15) |
19
(15) |
20
(13) |
|
21
(15) |
22
(13) |
23
(13) |
24
(2) |
25
(5) |
26
(12) |
27
|
|
28
(3) |
29
(13) |
30
(13) |
31
(14) |
|
|
|
|
From: <sv...@va...> - 2013-07-25 22:37:14
|
philippe 2013-07-25 23:37:02 +0100 (Thu, 25 Jul 2013)
New Revision: 13472
Log:
Bypass GDB bug which asks to read packet slightly too big
GDB sometimes asks slightly too big read packets
(no taking into account the packet overhead).
Bypass the problem by allocating slightly more than needed
if GDB would only ask the correct maximum size.
Modified files:
trunk/coregrind/m_gdbserver/remote-utils.c
trunk/coregrind/m_gdbserver/server.c
Modified: trunk/coregrind/m_gdbserver/remote-utils.c (+2 -1)
===================================================================
--- trunk/coregrind/m_gdbserver/remote-utils.c 2013-07-25 21:40:17 +01:00 (rev 13471)
+++ trunk/coregrind/m_gdbserver/remote-utils.c 2013-07-25 23:37:02 +01:00 (rev 13472)
@@ -695,7 +695,8 @@
char *p;
int cc;
- buf2 = malloc (PBUFSIZ);
+ buf2 = malloc (PBUFSIZ+POVERHSIZ);
+ // should malloc PBUFSIZ, but bypass GDB bug (see gdbserver_init in server.c)
/* Copy the packet into buffer BUF2, encapsulating it
and giving it a checksum. */
Modified: trunk/coregrind/m_gdbserver/server.c (+7 -2)
===================================================================
--- trunk/coregrind/m_gdbserver/server.c 2013-07-25 21:40:17 +01:00 (rev 13471)
+++ trunk/coregrind/m_gdbserver/server.c 2013-07-25 23:37:02 +01:00 (rev 13472)
@@ -799,9 +799,14 @@
// After a fork, gdbserver_init can be called again.
// We do not have to re-malloc the buffers in such a case.
if (own_buf == NULL)
- own_buf = malloc (PBUFSIZ);
+ own_buf = malloc (PBUFSIZ+POVERHSIZ);
if (mem_buf == NULL)
- mem_buf = malloc (PBUFSIZ);
+ mem_buf = malloc (PBUFSIZ+POVERHSIZ);
+ // Note: normally, we should only malloc PBUFSIZ. However,
+ // GDB has a bug, and in some cases, sends e.g. 'm' packets
+ // asking for slightly more than the PacketSize given at
+ // connection initialisation. So, we bypass the GDB bug
+ // by allocating slightly more.
}
void gdbserver_terminate (void)
|
|
From: <sv...@va...> - 2013-07-25 20:40:25
|
philippe 2013-07-25 21:40:17 +0100 (Thu, 25 Jul 2013)
New Revision: 13471
Log:
do not include linux/ptrace.h in vgdb.c
Include of linux/ptrace.h was added in revision r11740,
to avoid compilation error on s390x (fedora and suse).
The compilation error was retrieved thanks to archeological research
done by Christian Borntraeger: without this include, the following was given:
error: 'PT_ENDREGS' undeclared
There was also some errors on ppc64 around the same time:
error: 'PTRACE_GETREGS' undeclared
Currently, the inclusion of linux/ptrace.h gives a problem on amd64/fedora20:
/usr/include/linux/ptrace.h:58:8: error: redefinition of ‘struct ptrace_peeksiginfo_args’
/usr/include/sys/ptrace.h:191:8: note: originally defined here
According to man ptrace, it is good enough to include sys/ptrace.h
(which should avoid the problem on amd64/f20).
The linux/ptrace.h is deemed not necessary anymore as:
1. Christian has tested on sles11sp2 on s390x.
2. since linux/ptrace.h was added in vgdb.c, #ifdef PT_ENDREGS and
#ifdef PTRACE_GETREGS were added
=> remove the linux/ptrace.h
(tested on x86/f12, ppc64/f18, amd64/deb6, sles11sp2/s390x)
Thanks to Christian for the investigations
Modified files:
trunk/coregrind/vgdb.c
Modified: trunk/coregrind/vgdb.c (+0 -3)
===================================================================
--- trunk/coregrind/vgdb.c 2013-07-25 09:22:08 +01:00 (rev 13470)
+++ trunk/coregrind/vgdb.c 2013-07-25 21:40:17 +01:00 (rev 13471)
@@ -100,10 +100,7 @@
#if defined(PTRACEINVOKER)
#include <sys/user.h>
-#if defined(VGO_linux)
-# include <linux/ptrace.h>
#endif
-#endif
// Outputs information for the user about ptrace not working.
|
|
From: Emilio C. <er...@gm...> - 2013-07-25 14:11:53
|
Hi Josef, Thanks for your feedback! As I understand, your tool makes it possible to predict the runtime > of function calls. I wonder if this could be used for scheduling > decisions, e.g. if a function call is the body of an OpenMP for loop, > to get better dynamic scheduling decisions for improved load balancing. > This is an interesting idea. One critical point in getting an actual runtime prediction using our profiles is that a scheduler would need to guess the size of the input given to a task in advance. A possible approach may be to allow programmers to provide hints to the scheduler by specifying the expected input size of a task, but there may be more clever ways of speculating about workloads. Definitely worth investigating. Emilio |
|
From: <sv...@va...> - 2013-07-25 09:08:15
|
dejanj 2013-07-25 10:08:03 +0100 (Thu, 25 Jul 2013)
New Revision: 2732
Log:
mips32: Add support for mips32 DSP instruction set.
Add support for mips32 DSP and DSP revision 2 ASE.
More details about the mips32 DSP(r2) ASE:
http://www.mips.com/media/files/MD00566-2B-MIPSDSP-QRC-01.00.pdf
Applied patch provided by Maja Gagic <maj...@rt...>
Modified files:
trunk/priv/guest_mips_helpers.c
trunk/priv/guest_mips_toIR.c
trunk/priv/host_mips_defs.c
trunk/priv/host_mips_defs.h
trunk/priv/host_mips_isel.c
trunk/priv/main_main.c
trunk/pub/libvex.h
trunk/pub/libvex_guest_mips32.h
Modified: trunk/pub/libvex_guest_mips32.h (+10 -0)
===================================================================
--- trunk/pub/libvex_guest_mips32.h 2013-07-04 21:35:42 +01:00 (rev 2731)
+++ trunk/pub/libvex_guest_mips32.h 2013-07-25 10:08:03 +01:00 (rev 2732)
@@ -139,6 +139,16 @@
UInt host_EvC_FAILADDR; /* 308 */
UInt host_EvC_COUNTER; /* 312 */
UInt guest_COND; /* 316 */
+
+ UInt padding1;
+ /* MIPS32 DSP ASE(r2) specific registers. */
+ UInt guest_DSPControl; /* 324 */
+ ULong guest_ac0; /* 328 */
+ ULong guest_ac1; /* 336 */
+ ULong guest_ac2; /* 344 */
+ ULong guest_ac3; /* 352 */
+
+ UInt padding[6];
} VexGuestMIPS32State;
/*---------------------------------------------------------------*/
/*--- Utility functions for MIPS32 guest stuff. ---*/
Modified: trunk/pub/libvex.h (+4 -0)
===================================================================
--- trunk/pub/libvex.h 2013-07-04 21:35:42 +01:00 (rev 2731)
+++ trunk/pub/libvex.h 2013-07-25 10:08:03 +01:00 (rev 2732)
@@ -185,6 +185,10 @@
#define VEX_PRID_COMP_BROADCOM 0x00020000
#define VEX_PRID_COMP_NETLOGIC 0x000c0000
+/* MIPS additional capabilities */
+#define VEX_MIPS_ASE_DSP 0x00000010 /* Signal Processing ASE */
+#define VEX_MIPS_ASE_DSP2P 0x00000040 /* Signal Processing ASE Rev 2 */
+
/* These return statically allocated strings. */
extern const HChar* LibVEX_ppVexArch ( VexArch );
Modified: trunk/priv/guest_mips_toIR.c (+9713 -162)
===================================================================
--- trunk/priv/guest_mips_toIR.c 2013-07-04 21:35:42 +01:00 (rev 2731)
+++ trunk/priv/guest_mips_toIR.c 2013-07-25 10:08:03 +01:00 (rev 2732)
@@ -395,8 +395,31 @@
return ret;
}
-/* Do a endian load of a 32-bit word, regardless of the
- endianness of the underlying host. */
+/* ---------------- MIPS32 DSP ASE(r2) accumulators ---------------- */
+
+static UInt accumulatorGuestRegOffset(UInt acNo)
+{
+ vassert(!mode64);
+ vassert(acNo <= 3);
+ UInt ret;
+ switch (acNo) {
+ case 0:
+ ret = offsetof(VexGuestMIPS32State, guest_ac0); break;
+ case 1:
+ ret = offsetof(VexGuestMIPS32State, guest_ac1); break;
+ case 2:
+ ret = offsetof(VexGuestMIPS32State, guest_ac2); break;
+ case 3:
+ ret = offsetof(VexGuestMIPS32State, guest_ac3); break;
+ default:
+ vassert(0);
+ break;
+ }
+ return ret;
+}
+
+/* Do a endian load of a 32-bit word, regardless of the endianness of the
+ underlying host. */
static inline UInt getUInt(UChar * p)
{
UInt w = 0;
@@ -449,7 +472,7 @@
t4 = newTemp(Ity_I32); \
assign(t4, mkNarrowTo32( ty, binop(Iop_And64, \
mkexpr(t1), mkU64(0x3))));
-
+
#define LWX_SWX_PATTERN64_1 \
t2 = newTemp(Ity_I64); \
assign(t2, binop(Iop_And64, mkexpr(t1), mkU64(0xFFFFFFFFFFFFFFF8ULL))); \
@@ -641,6 +664,43 @@
return (0x00000007 & mipsins);
}
+/* Get acc number for all MIPS32 DSP ASE(r2) instructions that use them,
+ except for MFHI and MFLO. */
+static UInt get_acNo(UInt mipsins)
+{
+ return (0x00001800 & mipsins) >> 11;
+}
+
+/* Get accumulator number for MIPS32 DSP ASEr2 MFHI and MFLO instructions. */
+static UInt get_acNo_mfhilo(UInt mipsins)
+{
+ return (0x00600000 & mipsins) >> 21;
+}
+
+/* Get mask field (helper function for wrdsp instruction). */
+static UInt get_wrdspMask(UInt mipsins)
+{
+ return (0x001ff800 & mipsins) >> 11;
+}
+
+/* Get mask field (helper function for rddsp instruction). */
+static UInt get_rddspMask(UInt mipsins)
+{
+ return (0x03ff0000 & mipsins) >> 16;
+}
+
+/* Get shift field (helper function for DSP ASE instructions). */
+static UInt get_shift(UInt mipsins)
+{
+ return (0x03f00000 & mipsins) >> 20;
+}
+
+/* Get immediate field for DSP ASE instructions. */
+static UInt get_dspImm(UInt mipsins)
+{
+ return (0x03ff0000 & mipsins) >> 16;
+}
+
static Bool branch_or_jump(UChar * addr)
{
UInt fmt;
@@ -651,7 +711,7 @@
UInt function = get_function(cins);
/* bgtz, blez, bne, beq, jal */
- if (opcode == 0x07 || opcode == 0x06 || opcode == 0x05 || opcode == 0x04
+ if (opcode == 0x07 || opcode == 0x06 || opcode == 0x05 || opcode == 0x04
|| opcode == 0x03 || opcode == 0x02) {
return True;
}
@@ -694,6 +754,11 @@
}
}
+ /* bposge32 */
+ if (opcode == 0x01 && rt == 0x1c) {
+ return True;
+ }
+
return False;
}
@@ -767,13 +832,19 @@
return IRExpr_Const(IRConst_U8((UChar) i));
}
-/* Create an expression node for a 32-bit integer constant */
+/* Create an expression node for a 16-bit integer constant. */
+static IRExpr *mkU16(UInt i)
+{
+ return IRExpr_Const(IRConst_U16(i));
+}
+
+/* Create an expression node for a 32-bit integer constant. */
static IRExpr *mkU32(UInt i)
{
return IRExpr_Const(IRConst_U32(i));
}
-/* Create an expression node for a 64-bit integer constant */
+/* Create an expression node for a 64-bit integer constant. */
static IRExpr *mkU64(ULong i)
{
return IRExpr_Const(IRConst_U64(i));
@@ -864,6 +935,11 @@
binop(Iop_Shr32, src, mkexpr(t0)));
}
+static UShort extend_s_10to16(UInt x)
+{
+ return (UShort) ((((Int) x) << 22) >> 22);
+}
+
static UInt extend_s_16to32(UInt x)
{
return (UInt) ((((Int) x) << 16) >> 16);
@@ -911,6 +987,34 @@
stmt(IRStmt_Put(OFFB_PC, mkU64(d64)));
}
+/* Get value from accumulator (helper function for MIPS32 DSP ASE instructions).
+ This function should be called before any other operation if widening
+ multiplications are used. */
+static IRExpr *getAcc(UInt acNo)
+{
+ vassert(!mode64);
+ vassert(acNo <= 3);
+ return IRExpr_Get(accumulatorGuestRegOffset(acNo), Ity_I64);
+}
+
+/* Get value from DSPControl register (helper function for MIPS32 DSP ASE
+ instructions). */
+static IRExpr *getDSPControl(void)
+{
+ vassert(!mode64);
+ return IRExpr_Get(offsetof(VexGuestMIPS32State, guest_DSPControl), Ity_I32);
+}
+
+/* Put value to DSPControl register. Expression e is written to DSPControl as
+ is. If only certain bits of DSPControl need to be changed, it should be done
+ before calling putDSPControl(). It could be done by reading DSPControl and
+ ORing it with appropriate mask. */
+static void putDSPControl(IRExpr * e)
+{
+ vassert(!mode64);
+ stmt(IRStmt_Put(offsetof(VexGuestMIPS32State, guest_DSPControl), e));
+}
+
/* Fetch a byte from the guest insn stream. */
static UChar getIByte(Int delta)
{
@@ -993,20 +1097,55 @@
static void putLO(IRExpr * e)
{
- if (mode64)
+ if (mode64) {
stmt(IRStmt_Put(offsetof(VexGuestMIPS64State, guest_LO), e));
- else
+ } else {
stmt(IRStmt_Put(offsetof(VexGuestMIPS32State, guest_LO), e));
+ /* Add value to lower 32 bits of ac0 to maintain compatibility between
+ regular MIPS32 instruction set and MIPS DSP ASE. Keep higher 32bits
+ unchanged. */
+ IRTemp t_lo = newTemp(Ity_I32);
+ IRTemp t_hi = newTemp(Ity_I32);
+ assign(t_lo, e);
+ assign(t_hi, unop(Iop_64HIto32, getAcc(0)));
+ stmt(IRStmt_Put(accumulatorGuestRegOffset(0),
+ binop(Iop_32HLto64, mkexpr(t_hi), mkexpr(t_lo))));
+ }
}
static void putHI(IRExpr * e)
{
- if (mode64)
+ if (mode64) {
stmt(IRStmt_Put(offsetof(VexGuestMIPS64State, guest_HI), e));
- else
+ } else {
stmt(IRStmt_Put(offsetof(VexGuestMIPS32State, guest_HI), e));
+ /* Add value to higher 32 bits of ac0 to maintain compatibility between
+ regular MIPS32 instruction set and MIPS DSP ASE. Keep lower 32bits
+ unchanged. */
+ IRTemp t_lo = newTemp(Ity_I32);
+ IRTemp t_hi = newTemp(Ity_I32);
+ assign(t_hi, e);
+ assign(t_lo, unop(Iop_64to32, getAcc(0)));
+ stmt(IRStmt_Put(accumulatorGuestRegOffset(0),
+ binop(Iop_32HLto64, mkexpr(t_hi), mkexpr(t_lo))));
+ }
}
+/* Put value to accumulator(helper function for MIPS32 DSP ASE instructions). */
+static void putAcc(UInt acNo, IRExpr * e)
+{
+ vassert(!mode64);
+ vassert(acNo <= 3);
+ vassert(typeOfIRExpr(irsb->tyenv, e) == Ity_I64);
+ stmt(IRStmt_Put(accumulatorGuestRegOffset(acNo), e));
+/* If acNo = 0, split value to HI and LO regs in order to maintain compatibility
+ between MIPS32 and MIPS DSP ASE insn sets. */
+ if (0 == acNo) {
+ putLO(unop(Iop_64to32, e));
+ putHI(unop(Iop_64HIto32, e));
+ }
+}
+
static IRExpr *mkNarrowTo8 ( IRType ty, IRExpr * src )
{
vassert(ty == Ity_I32 || ty == Ity_I64);
@@ -1088,9 +1227,9 @@
IRTemp t0;
/* PC = PC + (SignExtend(signed_immed_24) << 2)
- An 18-bit signed offset (the 16-bit offset field shifted left 2 bits)
+ An 18-bit signed offset (the 16-bit offset field shifted left 2 bits)
is added to the address of the instruction following
- the branch (not the branch itself), in the branch delay slot, to form
+ the branch (not the branch itself), in the branch delay slot, to form
a PC-relative effective target address. */
if (mode64)
branch_offset = extend_s_18to64(imm << 2);
@@ -1104,7 +1243,7 @@
stmt(IRStmt_Exit(mkexpr(t0), Ijk_Boring,
IRConst_U64(guest_PC_curr_instr + 8), OFFB_PC));
else
- stmt(IRStmt_Exit(mkexpr(t0), Ijk_Boring,
+ stmt(IRStmt_Exit(mkexpr(t0), Ijk_Boring,
IRConst_U32(guest_PC_curr_instr + 8), OFFB_PC));
irsb->jumpkind = Ijk_Boring;
@@ -1128,9 +1267,9 @@
}
/* PC = PC + (SignExtend(signed_immed_24) << 2)
- An 18-bit signed offset (the 16-bit offset field shifted left 2 bits)
+ An 18-bit signed offset (the 16-bit offset field shifted left 2 bits)
is added to the address of the instruction following
- the branch (not the branch itself), in the branch delay slot, to form
+ the branch (not the branch itself), in the branch delay slot, to form
a PC-relative effective target address. */
if (mode64)
@@ -1221,7 +1360,7 @@
putFCSR(binop(Iop_And32, getFCSR(), mkU32(0xFF7FFFFF)));
putFCSR(binop(Iop_Or32, getFCSR(), binop(Iop_Shl32, e, mkU8(23))));
} else {
- putFCSR(binop(Iop_And32, getFCSR(), unop(Iop_Not32,
+ putFCSR(binop(Iop_And32, getFCSR(), unop(Iop_Not32,
binop(Iop_Shl32, mkU32(0x01000000), mkU8(cc)))));
putFCSR(binop(Iop_Or32, getFCSR(), binop(Iop_Shl32, e, mkU8(24 + cc))));
}
@@ -1229,7 +1368,7 @@
static IRExpr* get_IR_roundingmode ( void )
{
-/*
+/*
rounding mode | MIPS | IR
------------------------
to nearest | 00 | 00
@@ -1270,7 +1409,7 @@
static Addr64 mkSzAddr ( IRType ty, Addr64 addr )
{
vassert(ty == Ity_I32 || ty == Ity_I64);
- return (ty == Ity_I64 ? (Addr64) addr :
+ return (ty == Ity_I64 ? (Addr64) addr :
(Addr64) extend_s_32to64(toUInt(addr)));
}
@@ -1515,11 +1654,11 @@
*/
/* ccMIPS = Shl(1, (~(ccIR>>5) & 2) | ((ccIR ^ (ccIR>>6)) & 1) */
- assign(ccMIPS, binop(Iop_Shl32, mkU32(1), unop(Iop_32to8,
+ assign(ccMIPS, binop(Iop_Shl32, mkU32(1), unop(Iop_32to8,
binop(Iop_Or32, binop(Iop_And32, unop(Iop_Not32,
binop(Iop_Shr32, mkexpr(ccIR),mkU8(5))),mkU32(2)),
binop(Iop_And32, binop(Iop_Xor32, mkexpr(ccIR),
- binop(Iop_Shr32, mkexpr(ccIR), mkU8(6))),
+ binop(Iop_Shr32, mkexpr(ccIR), mkU8(6))),
mkU32(1))))));
putLO(mkWidenFrom32(Ity_I64, mkexpr(ccMIPS), True));
@@ -1589,7 +1728,7 @@
case 0xF:
setFPUCondCode(mkexpr(t2), fpc_cc);
break;
-
+
default:
return False;
}
@@ -1612,12 +1751,12 @@
*/
/* ccMIPS = Shl(1, (~(ccIR>>5) & 2) | ((ccIR ^ (ccIR>>6)) & 1) */
- assign(ccMIPS, binop(Iop_Shl32, mkU32(1), unop(Iop_32to8,
+ assign(ccMIPS, binop(Iop_Shl32, mkU32(1), unop(Iop_32to8,
binop(Iop_Or32, binop(Iop_And32, unop(Iop_Not32,
binop(Iop_Shr32, mkexpr(ccIR), mkU8(5))),
mkU32(2)), binop(Iop_And32,
binop(Iop_Xor32, mkexpr(ccIR),
- binop(Iop_Shr32, mkexpr(ccIR), mkU8(6))),
+ binop(Iop_Shr32, mkexpr(ccIR), mkU8(6))),
mkU32(1))))));
/* UN */
assign(t0, binop(Iop_And32, mkexpr(ccMIPS), mkU32(0x1)));
@@ -1686,7 +1825,7 @@
case 0xF:
setFPUCondCode(mkexpr(t2), fpc_cc);
break;
-
+
default:
return False;
}
@@ -1717,7 +1856,7 @@
binop(Iop_And32, binop(Iop_Xor32, mkexpr(ccIR),
binop(Iop_Shr32, mkexpr(ccIR), mkU8(6))),
mkU32(1))))));
-
+
/* UN */
assign(t0, binop(Iop_And32, mkexpr(ccMIPS), mkU32(0x1)));
/* EQ */
@@ -1915,6 +2054,9071 @@
}
/*------------------------------------------------------------*/
+/*--- Disassemble a single DSP ASE instruction ---*/
+/*------------------------------------------------------------*/
+
+static UInt disDSPInstr_MIPS_WRK ( UInt cins )
+{
+ IRTemp t0, t1 = 0, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11, t12, t13, t14,
+ t15, t16, t17, t18;
+ UInt opcode, rs, rt, rd, sa, function, ac, ac_mfhilo, rddsp_mask,
+ wrdsp_mask, dsp_imm, shift;
+
+ opcode = get_opcode(cins);
+ rs = get_rs(cins);
+ rt = get_rt(cins);
+ rd = get_rd(cins);
+ sa = get_sa(cins);
+ function = get_function(cins);
+ ac = get_acNo(cins);
+ ac_mfhilo = get_acNo_mfhilo(cins);
+ rddsp_mask = get_rddspMask(cins);
+ wrdsp_mask = get_wrdspMask(cins);
+ dsp_imm = get_dspImm(cins);
+ shift = get_shift(cins);
+
+ switch (opcode) {
+ case 0x00: { /* Special */
+ switch (function) {
+ case 0x10: { /* MFHI */
+ DIP("mfhi ac%d r%d", ac_mfhilo, rd);
+ putIReg(rd, unop(Iop_64HIto32, getAcc(ac_mfhilo)));
+ break;
+ }
+
+ case 0x11: { /* MTHI */
+ DIP("mthi ac%d r%d", ac, rs);
+ t1 = newTemp(Ity_I32);
+ assign(t1, unop(Iop_64to32, getAcc(ac)));
+ putAcc(ac, binop(Iop_32HLto64, getIReg(rs), mkexpr(t1)));
+ break;
+ }
+
+ case 0x12: { /* MFLO */
+ DIP("mflo ac%d r%d", ac_mfhilo, rd);
+ putIReg(rd, unop(Iop_64to32, getAcc(ac_mfhilo)));
+ break;
+ }
+
+ case 0x13: { /* MTLO */
+ DIP("mtlo ac%d r%d", ac, rs);
+ t1 = newTemp(Ity_I32);
+ assign(t1, unop(Iop_64HIto32, getAcc(ac)));
+ putAcc(ac, binop(Iop_32HLto64, mkexpr(t1), getIReg(rs)));
+ break;
+ }
+
+ case 0x18: { /* MULT */
+ DIP("mult ac%d r%d, r%d", ac, rs, rt);
+ t1 = newTemp(Ity_I64);
+ assign(t1, binop(Iop_MullS32, mkNarrowTo32(Ity_I32, getIReg(rs)),
+ mkNarrowTo32(Ity_I32, getIReg(rt))));
+ putAcc(ac, mkexpr(t1));
+ break;
+ }
+
+ case 0x19: { /* MULTU */
+ DIP("multu ac%d r%d, r%d", ac, rs, rt);
+ t1 = newTemp(Ity_I64);
+ assign(t1, binop(Iop_MullU32, mkNarrowTo32(Ity_I32, getIReg(rs)),
+ mkNarrowTo32(Ity_I32,
+ getIReg(rt))));
+ putAcc(ac, mkexpr(t1));
+ break;
+ }
+ }
+ break;
+ }
+ case 0x1C: { /* Special2 */
+ switch (function) {
+ case 0x00: { /* MADD */
+ DIP("madd ac%d, r%d, r%d", ac, rs, rt);
+ t1 = newTemp(Ity_I64);
+ t2 = newTemp(Ity_I64);
+ t3 = newTemp(Ity_I64);
+
+ assign(t1, getAcc(ac));
+ assign(t2, binop(Iop_MullS32, getIReg(rs), getIReg(rt)));
+ assign(t3, binop(Iop_Add64, mkexpr(t1), mkexpr(t2)));
+
+ putAcc(ac, mkexpr(t3));
+ break;
+ }
+ case 0x01: { /* MADDU */
+ DIP("maddu ac%d r%d, r%d", ac, rs, rt);
+ t1 = newTemp(Ity_I64);
+ t2 = newTemp(Ity_I64);
+ t3 = newTemp(Ity_I64);
+
+ assign(t1, getAcc(ac));
+ assign(t2, binop(Iop_MullU32, getIReg(rs), getIReg(rt)));
+ assign(t3, binop(Iop_Add64, mkexpr(t2), mkexpr(t1)));
+
+ putAcc(ac, mkexpr(t3));
+ break;
+ }
+ case 0x04: { /* MSUB */
+ DIP("msub ac%d r%d, r%d", ac, rs, rt);
+ t1 = newTemp(Ity_I64);
+ t2 = newTemp(Ity_I64);
+ t3 = newTemp(Ity_I64);
+
+ assign(t1, getAcc(ac));
+ assign(t2, binop(Iop_MullS32, getIReg(rs), getIReg(rt)));
+ assign(t3, binop(Iop_Sub64, mkexpr(t1), mkexpr(t2)));
+
+ putAcc(ac, mkexpr(t3));
+ break;
+ }
+ case 0x05: { /* MSUBU */
+ DIP("msubu ac%d r%d, r%d", ac, rs, rt);
+ t1 = newTemp(Ity_I64);
+ t2 = newTemp(Ity_I64);
+ t3 = newTemp(Ity_I64);
+
+ assign(t1, getAcc(ac));
+ assign(t2, binop(Iop_MullU32, getIReg(rs), getIReg(rt)));
+ assign(t3, binop(Iop_Sub64, mkexpr(t1), mkexpr(t2)));
+
+ putAcc(ac, mkexpr(t3));
+ break;
+ }
+ }
+ break;
+ }
+ case 0x1F: { /* Special3 */
+ switch (function) {
+ case 0x12: { /* ABSQ_S.PH */
+ switch (sa) {
+ case 0x1: { /* ABSQ_S.QB */
+ DIP("absq_s.qb r%d, r%d", rd, rt);
+ vassert(!mode64);
+ t0 = newTemp(Ity_I8);
+ t1 = newTemp(Ity_I1);
+ t2 = newTemp(Ity_I1);
+ t3 = newTemp(Ity_I8);
+ t4 = newTemp(Ity_I8);
+ t5 = newTemp(Ity_I1);
+ t6 = newTemp(Ity_I1);
+ t7 = newTemp(Ity_I8);
+ t8 = newTemp(Ity_I8);
+ t9 = newTemp(Ity_I1);
+ t10 = newTemp(Ity_I1);
+ t11 = newTemp(Ity_I8);
+ t12 = newTemp(Ity_I8);
+ t13 = newTemp(Ity_I1);
+ t14 = newTemp(Ity_I1);
+ t15 = newTemp(Ity_I8);
+ t16 = newTemp(Ity_I32);
+ t17 = newTemp(Ity_I32);
+
+ /* Absolute value of the rightmost byte (bits 7-0). */
+ /* t0 - rightmost byte. */
+ assign(t0, unop(Iop_16to8, unop(Iop_32to16, getIReg(rt))));
+ /* t1 holds 1 if t0 is equal to 0x80, or 0 otherwise. */
+ assign(t1, binop(Iop_CmpEQ32,
+ unop(Iop_8Uto32, mkexpr(t0)),
+ mkU32(0x00000080)));
+ /* t2 holds 1 if value in t0 is negative, 0 otherwise. */
+ assign(t2, unop(Iop_32to1,
+ binop(Iop_Shr32,
+ binop(Iop_And32,
+ getIReg(rt),
+ mkU32(0x00000080)),
+ mkU8(0x7))));
+ /* t3 holds abs(t0). */
+ assign(t3, IRExpr_ITE(mkexpr(t1),
+ mkU8(0x7F),
+ IRExpr_ITE(mkexpr(t2),
+ binop(Iop_Add8,
+ unop(Iop_Not8,
+ mkexpr(t0)),
+ mkU8(0x1)),
+ mkexpr(t0))));
+
+ /* Absolute value of bits 15-8. */
+ /* t4 - input byte. */
+ assign(t4,
+ unop(Iop_16HIto8, unop(Iop_32to16, getIReg(rt))));
+ /* t5 holds 1 if t4 is equal to 0x80, or 0 otherwise. */
+ assign(t5, binop(Iop_CmpEQ32,
+ unop(Iop_8Uto32, mkexpr(t4)),
+ mkU32(0x00000080)));
+ /* t6 holds 1 if value in t4 is negative, 0 otherwise. */
+ assign(t6, unop(Iop_32to1,
+ binop(Iop_Shr32,
+ binop(Iop_And32,
+ getIReg(rt),
+ mkU32(0x00008000)),
+ mkU8(15))));
+ /* t3 holds abs(t4). */
+ assign(t7, IRExpr_ITE(mkexpr(t5),
+ mkU8(0x7F),
+ IRExpr_ITE(mkexpr(t6),
+ binop(Iop_Add8,
+ unop(Iop_Not8,
+ mkexpr(t4)),
+ mkU8(0x1)),
+ mkexpr(t4))));
+
+ /* Absolute value of bits 23-15. */
+ /* t8 - input byte. */
+ assign(t8,
+ unop(Iop_16to8, unop(Iop_32HIto16, getIReg(rt))));
+ /* t9 holds 1 if t8 is equal to 0x80, or 0 otherwise. */
+ assign(t9, binop(Iop_CmpEQ32,
+ unop(Iop_8Uto32, mkexpr(t8)),
+ mkU32(0x00000080)));
+ /* t6 holds 1 if value in t8 is negative, 0 otherwise. */
+ assign(t10, unop(Iop_32to1,
+ binop(Iop_Shr32,
+ binop(Iop_And32,
+ getIReg(rt),
+ mkU32(0x00800000)),
+ mkU8(23))));
+ /* t3 holds abs(t8). */
+ assign(t11, IRExpr_ITE(mkexpr(t9),
+ mkU8(0x7F),
+ IRExpr_ITE(mkexpr(t10),
+ binop(Iop_Add8,
+ unop(Iop_Not8,
+ mkexpr(t8)),
+ mkU8(0x1)),
+ mkexpr(t8))));
+
+ /* Absolute value of bits 31-24. */
+ /* t12 - input byte. */
+ assign(t12,
+ unop(Iop_16HIto8, unop(Iop_32HIto16, getIReg(rt))));
+ /* t13 holds 1 if t12 is equal to 0x80, or 0 otherwise. */
+ assign(t13, binop(Iop_CmpEQ32,
+ unop(Iop_8Uto32, mkexpr(t12)),
+ mkU32(0x00000080)));
+ /* t14 holds 1 if value in t12 is negative, 0 otherwise. */
+ assign(t14, unop(Iop_32to1,
+ binop(Iop_Shr32,
+ binop(Iop_And32,
+ getIReg(rt),
+ mkU32(0x80000000)),
+ mkU8(31))));
+ /* t15 holds abs(t12). */
+ assign(t15, IRExpr_ITE(mkexpr(t13),
+ mkU8(0x7F),
+ IRExpr_ITE(mkexpr(t14),
+ binop(Iop_Add8,
+ unop(Iop_Not8,
+ mkexpr(t12)),
+ mkU8(0x1)),
+ mkexpr(t12))));
+
+ /* t16 holds !0 if any of input bytes is 0x80 or 0
+ otherwise. */
+ assign(t16,
+ binop(Iop_Or32,
+ binop(Iop_Or32,
+ binop(Iop_Or32,
+ unop(Iop_1Sto32, mkexpr(t13)),
+ unop(Iop_1Sto32, mkexpr(t9))),
+ unop(Iop_1Sto32, mkexpr(t5))),
+ unop(Iop_1Sto32, mkexpr(t1))));
+
+ putDSPControl(IRExpr_ITE(binop(Iop_CmpEQ32,
+ mkexpr(t16),
+ mkU32(0x0)),
+ getDSPControl(),
+ binop(Iop_Or32,
+ getDSPControl(),
+ mkU32(0x00100000))));
+
+ /* t17 = t15|t11|t7|t3 */
+ assign(t17,
+ binop(Iop_16HLto32,
+ binop(Iop_8HLto16, mkexpr(t15), mkexpr(t11)),
+ binop(Iop_8HLto16, mkexpr(t7), mkexpr(t3))));
+
+ putIReg(rd, mkexpr(t17));
+ break;
+ }
+ case 0x2: { /* REPL.QB */
+ DIP("repl.qb r%d, %d", rd, dsp_imm);
+ vassert(!mode64);
+
+ putIReg(rd, mkU32((dsp_imm << 24) | (dsp_imm << 16) |
+ (dsp_imm << 8) | (dsp_imm)));
+ break;
+ }
+ case 0x3: { /* REPLV.QB */
+ DIP("replv.qb r%d, r%d", rd, rt);
+ vassert(!mode64);
+ t0 = newTemp(Ity_I8);
+
+ assign(t0, unop(Iop_32to8,
+ binop(Iop_And32, getIReg(rt), mkU32(0xff))));
+ putIReg(rd,
+ binop(Iop_16HLto32,
+ binop(Iop_8HLto16, mkexpr(t0), mkexpr(t0)),
+ binop(Iop_8HLto16, mkexpr(t0), mkexpr(t0))));
+ break;
+ }
+ case 0x4: { /* PRECEQU.PH.QBL */
+ DIP("precequ.ph.qbl r%d, r%d", rd, rt);
+ vassert(!mode64);
+
+ putIReg(rd, binop(Iop_Or32,
+ binop(Iop_Shr32,
+ binop(Iop_And32,
+ getIReg(rt),
+ mkU32(0xff000000)),
+ mkU8(1)),
+ binop(Iop_Shr32,
+ binop(Iop_And32,
+ getIReg(rt),
+ mkU32(0x00ff0000)),
+ mkU8(9))));
+ break;
+ }
+ case 0x5: { /* PRECEQU.PH.QBR */
+ DIP("precequ.ph.qbr r%d, r%d", rd, rt);
+ vassert(!mode64);
+
+ putIReg(rd, binop(Iop_Or32,
+ binop(Iop_Shl32,
+ binop(Iop_And32,
+ getIReg(rt),
+ mkU32(0x0000ff00)),
+ mkU8(15)),
+ binop(Iop_Shl32,
+ binop(Iop_And32,
+ getIReg(rt),
+ mkU32(0x000000ff)),
+ mkU8(7))));
+ break;
+ }
+ case 0x6: { /* PRECEQU.PH.QBLA */
+ DIP("precequ.ph.qbla r%d, r%d", rd, rt);
+ vassert(!mode64);
+
+ putIReg(rd, binop(Iop_Or32,
+ binop(Iop_Shr32,
+ binop(Iop_And32,
+ getIReg(rt),
+ mkU32(0xff000000)),
+ mkU8(1)),
+ binop(Iop_Shr32,
+ binop(Iop_And32,
+ getIReg(rt),
+ mkU32(0x0000ff00)),
+ mkU8(1))));
+ break;
+ }
+ case 0x7: { /* PRECEQU.PH.QBRA */
+ DIP("precequ.ph.qbra r%d, r%d", rd, rt);
+ vassert(!mode64);
+
+ putIReg(rd, binop(Iop_Or32,
+ binop(Iop_Shl32,
+ binop(Iop_And32,
+ getIReg(rt),
+ mkU32(0x00ff0000)),
+ mkU8(7)),
+ binop(Iop_Shl32,
+ binop(Iop_And32,
+ getIReg(rt),
+ mkU32(0x000000ff)),
+ mkU8(7))));
+ break;
+ }
+ case 0x9: { /* ABSQ_S.PH */
+ DIP("absq_s.ph r%d, r%d", rd, rt);
+ vassert(!mode64);
+ t0 = newTemp(Ity_I16);
+ t1 = newTemp(Ity_I1);
+ t2 = newTemp(Ity_I1);
+ t3 = newTemp(Ity_I16);
+ t4 = newTemp(Ity_I16);
+ t5 = newTemp(Ity_I1);
+ t6 = newTemp(Ity_I1);
+ t7 = newTemp(Ity_I16);
+ t8 = newTemp(Ity_I32);
+ t9 = newTemp(Ity_I32);
+
+ /* t0 holds lower 16 bits of value in rt. */
+ assign(t0, unop(Iop_32to16, getIReg(rt)));
+ /* t1 holds 1 if t0 is equal to 0x8000. */
+ assign(t1, binop(Iop_CmpEQ32,
+ unop(Iop_16Uto32, mkexpr(t0)),
+ mkU32(0x00008000)));
+ /* t2 holds 1 if value in t0 is negative, 0 otherwise. */
+ assign(t2, unop(Iop_32to1,
+ binop(Iop_Shr32,
+ binop(Iop_And32,
+ getIReg(rt),
+ mkU32(0x00008000)),
+ mkU8(15))));
+ /* t3 holds abs(t0). */
+ assign(t3, IRExpr_ITE(mkexpr(t1),
+ mkU16(0x7FFF),
+ IRExpr_ITE(mkexpr(t2),
+ binop(Iop_Add16,
+ unop(Iop_Not16,
+ mkexpr(t0)),
+ mkU16(0x1)),
+ mkexpr(t0))));
+
+ /* t4 holds lower 16 bits of value in rt. */
+ assign(t4, unop(Iop_32HIto16, getIReg(rt)));
+ /* t5 holds 1 if t4 is equal to 0x8000. */
+ assign(t5, binop(Iop_CmpEQ32,
+ unop(Iop_16Uto32, mkexpr(t4)),
+ mkU32(0x00008000)));
+ /* t6 holds 1 if value in t4 is negative, 0 otherwise. */
+ assign(t6, unop(Iop_32to1,
+ binop(Iop_Shr32,
+ binop(Iop_And32,
+ getIReg(rt),
+ mkU32(0x80000000)),
+ mkU8(31))));
+ /* t7 holds abs(t4). */
+ assign(t7, IRExpr_ITE(mkexpr(t5),
+ mkU16(0x7FFF),
+ IRExpr_ITE(mkexpr(t6),
+ binop(Iop_Add16,
+ unop(Iop_Not16,
+ mkexpr(t4)),
+ mkU16(0x1)),
+ mkexpr(t4))));
+ /* If any of the two input halfwords is equal 0x8000,
+ set bit 20 in DSPControl register. */
+ assign(t8, binop(Iop_Or32,
+ unop(Iop_1Sto32, mkexpr(t5)),
+ unop(Iop_1Sto32, mkexpr(t1))));
+
+ putDSPControl(IRExpr_ITE(binop(Iop_CmpEQ32,
+ mkexpr(t8),
+ mkU32(0x0)),
+ getDSPControl(),
+ binop(Iop_Or32,
+ getDSPControl(),
+ mkU32(0x00100000))));
+
+ /* t9 = t7|t3 */
+ assign(t9, binop(Iop_16HLto32, mkexpr(t7), mkexpr(t3)));
+
+ putIReg(rd, mkexpr(t9));
+ break;
+ }
+ case 0xA: { /* REPL.PH */
+ DIP("repl.ph r%d, %d", rd, dsp_imm);
+ vassert(!mode64);
+ UShort immediate = extend_s_10to16(dsp_imm);
+
+ putIReg(rd, mkU32(immediate << 16 | immediate));
+ break;
+ }
+ case 0xB: { /* REPLV.PH */
+ DIP("replv.ph r%d, r%d", rd, rt);
+ vassert(!mode64);
+
+ putIReg(rd, binop(Iop_16HLto32,
+ unop(Iop_32to16, getIReg(rt)),
+ unop(Iop_32to16, getIReg(rt))));
+ break;
+ }
+ case 0xC: { /* PRECEQ.W.PHL */
+ DIP("preceq.w.phl r%d, r%d", rd, rt);
+ vassert(!mode64);
+ putIReg(rd, binop(Iop_And32,
+ getIReg(rt),
+ mkU32(0xffff0000)));
+ break;
+ }
+ case 0xD: { /* PRECEQ.W.PHR */
+ DIP("preceq.w.phr r%d, r%d", rd, rt);
+ vassert(!mode64);
+ putIReg(rd, binop(Iop_16HLto32,
+ unop(Iop_32to16, getIReg(rt)),
+ mkU16(0x0)));
+ break;
+ }
+ case 0x11: { /* ABSQ_S.W */
+ DIP("absq_s.w r%d, r%d", rd, rt);
+ vassert(!mode64);
+ t0 = newTemp(Ity_I1);
+ t1 = newTemp(Ity_I1);
+ t2 = newTemp(Ity_I32);
+
+ assign(t0,
+ binop(Iop_CmpEQ32, getIReg(rt), mkU32(0x80000000)));
+
+ putDSPControl(IRExpr_ITE(mkexpr(t0),
+ binop(Iop_Or32,
+ getDSPControl(),
+ mkU32(0x00100000)),
+ getDSPControl()));
+
+ assign(t1, binop(Iop_CmpLT32S, getIReg(rt), mkU32(0x0)));
+
+ assign(t2, IRExpr_ITE(mkexpr(t0),
+ mkU32(0x7FFFFFFF),
+ IRExpr_ITE(mkexpr(t1),
+ binop(Iop_Add32,
+ unop(Iop_Not32,
+ getIReg(rt)),
+ mkU32(0x1)),
+ getIReg(rt))));
+ putIReg(rd, mkexpr(t2));
+ break;
+ }
+ case 0x1B: { /* BITREV */
+ DIP("bitrev r%d, r%d", rd, rt);
+ vassert(!mode64);
+ /* 32bit reversal as seen on Bit Twiddling Hacks site
+ http://graphics.stanford.edu/~seander/bithacks.html
+ section ReverseParallel */
+ t1 = newTemp(Ity_I32);
+ t2 = newTemp(Ity_I32);
+ t3 = newTemp(Ity_I32);
+ t4 = newTemp(Ity_I32);
+ t5 = newTemp(Ity_I32);
+
+ assign(t1, binop(Iop_Or32,
+ binop(Iop_Shr32,
+ binop(Iop_And32,
+ getIReg(rt),
+ mkU32(0xaaaaaaaa)),
+ mkU8(0x1)),
+ binop(Iop_Shl32,
+ binop(Iop_And32,
+ getIReg(rt),
+ mkU32(0x55555555)),
+ mkU8(0x1))));
+ assign(t2, binop(Iop_Or32,
+ binop(Iop_Shr32,
+ binop(Iop_And32,
+ mkexpr(t1),
+ mkU32(0xcccccccc)),
+ mkU8(0x2)),
+ binop(Iop_Shl32,
+ binop(Iop_And32,
+ mkexpr(t1),
+ mkU32(0x33333333)),
+ mkU8(0x2))));
+ assign(t3, binop(Iop_Or32,
+ binop(Iop_Shr32,
+ binop(Iop_And32,
+ mkexpr(t2),
+ mkU32(0xf0f0f0f0)),
+ mkU8(0x4)),
+ binop(Iop_Shl32,
+ binop(Iop_And32,
+ mkexpr(t2),
+ mkU32(0x0f0f0f0f)),
+ mkU8(0x4))));
+ assign(t4, binop(Iop_Or32,
+ binop(Iop_Shr32,
+ binop(Iop_And32,
+ mkexpr(t3),
+ mkU32(0xff00ff00)),
+ mkU8(0x8)),
+ binop(Iop_Shl32,
+ binop(Iop_And32,
+ mkexpr(t3),
+ mkU32(0x00ff00ff)),
+ mkU8(0x8))));
+ assign(t5, binop(Iop_Or32,
+ binop(Iop_Shr32,
+ mkexpr(t4),
+ mkU8(0x10)),
+ binop(Iop_Shl32,
+ mkexpr(t4),
+ mkU8(0x10))));
+ putIReg(rd, binop(Iop_Shr32,
+ mkexpr(t5),
+ mkU8(16)));
+ break;
+ }
+ case 0x1C: { /* PRECEU.PH.QBL */
+ DIP("preceu.ph.qbl r%d, r%d", rd, rt);
+ vassert(!mode64);
+
+ putIReg(rd, binop(Iop_Or32,
+ binop(Iop_Shr32,
+ binop(Iop_And32,
+ getIReg(rt),
+ mkU32(0xff000000)),
+ mkU8(8)),
+ binop(Iop_Shr32,
+ binop(Iop_And32,
+ getIReg(rt),
+ mkU32(0x00ff0000)),
+ mkU8(16))));
+ break;
+ }
+ case 0x1E: { /* PRECEU.PH.QBLA */
+ DIP("preceu.ph.qbla r%d, r%d", rd, rt);
+ vassert(!mode64);
+
+ putIReg(rd, binop(Iop_Or32,
+ binop(Iop_Shr32,
+ binop(Iop_And32,
+ getIReg(rt),
+ mkU32(0xff000000)),
+ mkU8(8)),
+ binop(Iop_Shr32,
+ binop(Iop_And32,
+ getIReg(rt),
+ mkU32(0x0000ff00)),
+ mkU8(8))));
+ break;
+ }
+ case 0x1D: { /* PRECEU.PH.QBR */
+ DIP("preceu.ph.qbr r%d, r%d", rd, rt);
+ vassert(!mode64);
+
+ putIReg(rd, binop(Iop_Or32,
+ binop(Iop_Shl32,
+ binop(Iop_And32,
+ getIReg(rt),
+ mkU32(0x0000ff00)),
+ mkU8(8)),
+ binop(Iop_And32,
+ getIReg(rt),
+ mkU32(0x000000ff))));
+ break;
+ }
+ case 0x1F: { /* PRECEU.PH.QBRA */
+ DIP("preceu.ph.qbra r%d, r%d", rd, rt);
+ vassert(!mode64);
+
+ putIReg(rd, binop(Iop_Or32,
+ binop(Iop_And32,
+ getIReg(rt),
+ mkU32(0x00ff0000)),
+ binop(Iop_And32,
+ getIReg(rt),
+ mkU32(0x000000ff))));
+ break;
+ }
+ default:
+ return -1;
+ }
+ break; /* end of ABSQ_S.PH */
+ }
+ case 0x38: { /* EXTR.W */
+ switch(sa) {
+ case 0x0: { /* EXTR.W */
+ DIP("extr.w r%d, ac%d, %d", rt, ac, rs);
+ vassert(!mode64);
+ t0 = newTemp(Ity_I64);
+ t1 = newTemp(Ity_I64);
+ t2 = newTemp(Ity_I32);
+ t3 = newTemp(Ity_I32);
+ t4 = newTemp(Ity_I32);
+
+ assign(t0, getAcc(ac));
+ assign(t1, binop(Iop_Sar64, mkexpr(t0), mkU8(rs)));
+ putIReg(rt, unop(Iop_64to32, mkexpr(t1)));
+
+ assign(t2, binop(Iop_Or32,
+ getDSPControl(), mkU32(0x00800000)));
+
+ /* Check if signOut == signIn */
+ assign(t3, IRExpr_ITE(binop(Iop_CmpEQ32,
+ binop(Iop_And32,
+ unop(Iop_64HIto32,
+ mkexpr(t0)),
+ mkU32(0x80000000)),
+ binop(Iop_And32,
+ getIReg(rt),
+ mkU32(0x80000000))),
+ getDSPControl(),
+ mkexpr(t2)));
+
+ assign(t4, IRExpr_ITE(binop(Iop_CmpNE32,
+ unop(Iop_64HIto32,
+ mkexpr(t1)),
+ mkU32(0x0)),
+ IRExpr_ITE(binop(Iop_CmpNE32,
+ unop(Iop_64HIto32,
+ mkexpr(t1)),
+ mkU32(0xffffffff)),
+ mkexpr(t2),
+ mkexpr(t3)),
+ mkexpr(t3)));
+ putDSPControl(mkexpr(t4));
+ break;
+ }
+ case 0x1: { /* EXTRV.W */
+ DIP("extrv.w r%d, ac%d, r%d", rt, ac, rs);
+ vassert(!mode64);
+ t0 = newTemp(Ity_I64);
+ t1 = newTemp(Ity_I64);
+ t2 = newTemp(Ity_I32);
+ t3 = newTemp(Ity_I32);
+ t4 = newTemp(Ity_I1);
+
+ assign(t0, getAcc(ac));
+ assign(t1, binop(Iop_Sar64,
+ mkexpr(t0),
+ unop(Iop_32to8,
+ binop(Iop_And32,
+ getIReg(rs),
+ mkU32(0x1f)))));
+ putIReg(rt, unop(Iop_64to32, mkexpr(t1)));
+
+ assign(t2, binop(Iop_Or32,
+ getDSPControl(), mkU32(0x00800000)));
+
+ /* Check if signOut == signIn */
+ assign(t3, IRExpr_ITE(binop(Iop_CmpEQ32,
+ binop(Iop_And32,
+ unop(Iop_64HIto32,
+ mkexpr(t0)),
+ mkU32(0x80000000)),
+ binop(Iop_And32,
+ getIReg(rt),
+ mkU32(0x80000000))),
+ getDSPControl(),
+ mkexpr(t2)));
+ assign(t4, binop(Iop_CmpNE32,
+ unop(Iop_64HIto32, mkexpr(t1)),
+ mkU32(0xffffffff)));
+ putDSPControl(IRExpr_ITE(binop(Iop_CmpNE32,
+ unop(Iop_64HIto32,
+ mkexpr(t1)),
+ mkU32(0x0)),
+ IRExpr_ITE(mkexpr(t4),
+ mkexpr(t2),
+ mkexpr(t3)),
+ mkexpr(t3)));
+ break;
+ }
+ case 0x2: { /* EXTP */
+ DIP("extp r%d, ac%d, %d", rt, ac, rs);
+ vassert(!mode64);
+ t0 = newTemp(Ity_I64);
+ t1 = newTemp(Ity_I32);
+ t2 = newTemp(Ity_I1);
+ t3 = newTemp(Ity_I1);
+ t4 = newTemp(Ity_I8);
+ t5 = newTemp(Ity_I64);
+ t6 = newTemp(Ity_I64);
+ t7 = newTemp(Ity_I32);
+
+ assign(t0, getAcc(ac));
+ /* Extract pos field of DSPControl register. */
+ assign(t1, binop(Iop_And32, getDSPControl(), mkU32(0x3f)));
+
+ /* Check if (pos - size) >= 0 [size <= pos]
+ if (pos < size)
+ put 1 to EFI field of DSPControl register
+ else
+ extract bits from acc and put 0 to EFI field of
+ DSPCtrl */
+ assign(t2, binop(Iop_CmpLT32U, mkexpr(t1), mkU32(rs)));
+
+ putDSPControl(IRExpr_ITE(mkexpr(t2),
+ binop(Iop_Or32,
+ binop(Iop_And32,
+ getDSPControl(),
+ mkU32(0xffffbfff)),
+ mkU32(0x4000)),
+ binop(Iop_And32,
+ getDSPControl(),
+ mkU32(0xffffbfff))));
+
+ /* If pos <= 31, shift right the value from the acc
+ (pos-size) times and take (size+1) bits from the least
+ significant positions. Otherwise, shift left the value
+ (63-pos) times, take (size+1) bits from the most
+ significant positions and shift right (31-size) times.*/
+ assign(t3, binop(Iop_CmpLE32U, mkexpr(t1), mkU32(31)));
+
+ assign(t4,
+ IRExpr_ITE(mkexpr(t3),
+ unop(Iop_32to8,
+ binop(Iop_Sub32,
+ mkexpr(t1), mkU32(rs))),
+ unop(Iop_32to8,
+ binop(Iop_Sub32,
+ mkU32(63), mkexpr(t1)))));
+
+ assign(t5, IRExpr_ITE(mkexpr(t3),
+ binop(Iop_Shr64,
+ mkexpr(t0), mkexpr(t4)),
+ binop(Iop_Shl64,
+ mkexpr(t0), mkexpr(t4))));
+
+ /* t6 holds a mask for bit extraction */
+ assign(t6,
+ IRExpr_ITE(mkexpr(t3),
+ unop(Iop_Not64,
+ binop(Iop_Shl64,
+ mkU64(0xffffffffffffffffULL),
+ mkU8(rs+1))),
+ unop(Iop_Not64,
+ binop(Iop_Shr64,
+ mkU64(0xffffffffffffffffULL),
+ mkU8(rs+1)))));
+
+ assign(t7, IRExpr_ITE(mkexpr(t3),
+ unop(Iop_64to32,
+ binop(Iop_And64,
+ mkexpr(t5),
+ mkexpr(t6))),
+ binop(Iop_Shr32,
+ unop(Iop_64HIto32,
+ binop(Iop_And64,
+ mkexpr(t5),
+ mkexpr(t6))),
+ mkU8(31-rs))));
+
+ putIReg(rt, mkexpr(t7));
+ break;
+ }
+ case 0x3: { /* EXTPV */
+ DIP("extpv r%d, ac%d, r%d", rt, ac, rs);
+ vassert(!mode64);
+ t0 = newTemp(Ity_I64);
+ t1 = newTemp(Ity_I32);
+ t2 = newTemp(Ity_I1);
+ t3 = newTemp(Ity_I1);
+ t4 = newTemp(Ity_I8);
+ t5 = newTemp(Ity_I64);
+ t6 = newTemp(Ity_I64);
+ t7 = newTemp(Ity_I32);
+ t8 = newTemp(Ity_I32);
+
+ assign(t8, binop(Iop_And32, getIReg(rs), mkU32(0x1f)));
+ assign(t0, getAcc(ac));
+ /* Extract pos field of DSPControl register. */
+ assign(t1, binop(Iop_And32, getDSPControl(), mkU32(0x3f)));
+
+ /* Check if (pos - size) >= 0 [size <= pos]
+ if (pos < size)
+ put 1 to EFI field of DSPControl register
+ else
+ extract bits from acc and put 0 to EFI field of
+ DSPCtrl */
+ assign(t2, binop(Iop_CmpLT32U, mkexpr(t1), mkexpr(t8)));
+
+ putDSPControl(IRExpr_ITE(mkexpr(t2),
+ binop(Iop_Or32,
+ binop(Iop_And32,
+ getDSPControl(),
+ mkU32(0xffffbfff)),
+ mkU32(0x4000)),
+ binop(Iop_And32,
+ getDSPControl(),
+ mkU32(0xffffbfff))));
+
+ /* If pos <= 31, shift right the value from the acc
+ (pos-size) times and take (size+1) bits from the least
+ significant positions. Otherwise, shift left the value
+ (63-pos) times, take (size+1) bits from the most
+ significant positions and shift right (31-size)
+ times. */
+ assign(t3, binop(Iop_CmpLE32U, mkexpr(t1), mkU32(31)));
+
+ assign(t4,
+ IRExpr_ITE(mkexpr(t3),
+ unop(Iop_32to8,
+ binop(Iop_Sub32,
+ mkexpr(t1), mkexpr(t8))),
+ unop(Iop_32to8,
+ binop(Iop_Sub32,
+ mkU32(63), mkexpr(t1)))));
+
+ assign(t5, IRExpr_ITE(mkexpr(t3),
+ binop(Iop_Shr64,
+ mkexpr(t0), mkexpr(t4)),
+ binop(Iop_Shl64,
+ mkexpr(t0), mkexpr(t4))));
+
+ /* t6 holds a mask for bit extraction. */
+ assign(t6,
+ IRExpr_ITE(mkexpr(t3),
+ unop(Iop_Not64,
+ binop(Iop_Shl64,
+ mkU64(0xffffffffffffffffULL),
+ unop(Iop_32to8,
+ binop(Iop_Add32,
+ mkexpr(t8),
+ mkU32(1))))),
+ unop(Iop_Not64,
+ binop(Iop_Shr64,
+ mkU64(0xffffffffffffffffULL),
+ unop(Iop_32to8,
+ binop(Iop_Add32,
+ mkexpr(t8),
+ mkU32(1)))))));
+
+ assign(t7, IRExpr_ITE(mkexpr(t3),
+ unop(Iop_64to32,
+ binop(Iop_And64,
+ mkexpr(t5),
+ mkexpr(t6))),
+ binop(Iop_Shr32,
+ unop(Iop_64HIto32,
+ binop(Iop_And64,
+ ...
[truncated message content] |
|
From: <sv...@va...> - 2013-07-25 08:22:23
|
dejanj 2013-07-25 09:22:08 +0100 (Thu, 25 Jul 2013)
New Revision: 13470
Log:
mips32: Add support for mips32 DSP instruction set.
Add support for mips32 DSP and DSP revision 2 ASE.
More details about the mips32 DSP(r2) ASE:
http://www.mips.com/media/files/MD00566-2B-MIPSDSP-QRC-01.00.pdf
Applied patch provided by Maja Gagic <maj...@rt...>
Modified files:
trunk/coregrind/m_libcsetjmp.c
trunk/coregrind/m_machine.c
trunk/include/pub_tool_libcsetjmp.h
trunk/memcheck/mc_machine.c
Modified: trunk/coregrind/m_libcsetjmp.c (+52 -0)
===================================================================
--- trunk/coregrind/m_libcsetjmp.c 2013-07-22 23:00:13 +01:00 (rev 13469)
+++ trunk/coregrind/m_libcsetjmp.c 2013-07-25 09:22:08 +01:00 (rev 13470)
@@ -444,6 +444,58 @@
#endif /* VGP_x86_linux || VGP_x86_darwin */
+#if defined(VGP_mips32_linux)
+
+__asm__(
+".text \n\t"
+".globl VG_MINIMAL_SETJMP; \n\t"
+".align 2; \n\t"
+"VG_MINIMAL_SETJMP: \n\t" /* a0 = jmp_buf */
+" sw $s0, 0($a0) \n\t" /* Save registers s0-s7. */
+" sw $s1, 4($a0) \n\t"
+" sw $s2, 8($a0) \n\t"
+" sw $s3, 12($a0) \n\t"
+" sw $s4, 16($a0) \n\t"
+" sw $s5, 20($a0) \n\t"
+" sw $s6, 24($a0) \n\t"
+" sw $s7, 28($a0) \n\t"
+" sw $s8, 32($a0) \n\t" /* Frame pointer. */
+" sw $ra, 36($a0) \n\t" /* Return address. */
+" sw $gp, 40($a0) \n\t" /* Global data pointer. */
+" sw $sp, 44($a0) \n\t" /* Stack pointer. */
+
+" move $v0, $zero \n\t" /* Return zero. */
+" j $ra \n\t"
+" nop \n\t"
+".end VG_MINIMAL_SETJMP; \n\t"
+" \n\t"
+".globl VG_MINIMAL_LONGJMP; \n\t"
+".align 2; \n\t"
+"VG_MINIMAL_LONGJMP: \n\t" /* a0 = jmp_buf */
+" lw $s0, 0($a0) \n\t" /* Restore registers s0-s7. */
+" lw $s1, 4($a0) \n\t"
+" lw $s2, 8($a0) \n\t"
+" lw $s3, 12($a0) \n\t"
+" lw $s4, 16($a0) \n\t"
+" lw $s5, 20($a0) \n\t"
+" lw $s6, 24($a0) \n\t"
+" lw $s7, 28($a0) \n\t"
+" lw $s8, 32($a0) \n\t" /* Frame pointer. */
+" lw $ra, 36($a0) \n\t" /* Return address. */
+" lw $gp, 40($a0) \n\t" /* Global data pointer. */
+" lw $sp, 44($a0) \n\t" /* Stack pointer. */
+
+/* Checking whether second argument is zero. */
+" bnez $a1, 1f \n\t"
+" nop \n\t"
+" addi $a1, $a1, 1 \n\t" /* We must return 1 if val=0. */
+"1: \n\t"
+" move $v0, $a1 \n\t" /* Return value of second argument. */
+" j $ra \n\t"
+".end VG_MINIMAL_SETJMP; \n\t"
+);
+#endif /* VGP_mips32_linux */
+
/*--------------------------------------------------------------------*/
/*--- end ---*/
/*--------------------------------------------------------------------*/
Modified: trunk/coregrind/m_machine.c (+54 -2)
===================================================================
--- trunk/coregrind/m_machine.c 2013-07-22 23:00:13 +01:00 (rev 13469)
+++ trunk/coregrind/m_machine.c 2013-07-25 09:22:08 +01:00 (rev 13470)
@@ -444,7 +444,7 @@
/* For hwcaps detection on ppc32/64, s390x, and arm we'll need to do SIGILL
testing, so we need a VG_MINIMAL_JMP_BUF. */
#if defined(VGA_ppc32) || defined(VGA_ppc64) \
- || defined(VGA_arm) || defined(VGA_s390x)
+ || defined(VGA_arm) || defined(VGA_s390x) || defined(VGA_mips32)
#include "pub_tool_libcsetjmp.h"
static VG_MINIMAL_JMP_BUF(env_unsup_insn);
static void handler_unsup_insn ( Int x ) {
@@ -1400,11 +1400,63 @@
{
va = VexArchMIPS32;
UInt model = VG_(get_machine_model)();
- if (model== -1)
+ if (model == -1)
return False;
vai.hwcaps = model;
+ /* Same instruction set detection algorithm as for ppc32/arm... */
+ vki_sigset_t saved_set, tmp_set;
+ vki_sigaction_fromK_t saved_sigill_act;
+ vki_sigaction_toK_t tmp_sigill_act;
+
+ volatile Bool have_DSP, have_DSPr2;
+ Int r;
+
+ vg_assert(sizeof(vki_sigaction_fromK_t) == sizeof(vki_sigaction_toK_t));
+
+ VG_(sigemptyset)(&tmp_set);
+ VG_(sigaddset)(&tmp_set, VKI_SIGILL);
+
+ r = VG_(sigprocmask)(VKI_SIG_UNBLOCK, &tmp_set, &saved_set);
+ vg_assert(r == 0);
+
+ r = VG_(sigaction)(VKI_SIGILL, NULL, &saved_sigill_act);
+ vg_assert(r == 0);
+ tmp_sigill_act = saved_sigill_act;
+
+ /* NODEFER: signal handler does not return (from the kernel's point of
+ view), hence if it is to successfully catch a signal more than once,
+ we need the NODEFER flag. */
+ tmp_sigill_act.sa_flags &= ~VKI_SA_RESETHAND;
+ tmp_sigill_act.sa_flags &= ~VKI_SA_SIGINFO;
+ tmp_sigill_act.sa_flags |= VKI_SA_NODEFER;
+ tmp_sigill_act.ksa_handler = handler_unsup_insn;
+ VG_(sigaction)(VKI_SIGILL, &tmp_sigill_act, NULL);
+
+ /* DSP instructions. */
+ have_DSP = True;
+ if (VG_MINIMAL_SETJMP(env_unsup_insn)) {
+ have_DSP = False;
+ } else {
+ __asm__ __volatile__(".word 0x7c3f44b8"); /* rddsp t0, 0x3f */
+ }
+
+ /* DSPr2 instructions. */
+ have_DSPr2 = True;
+ if (VG_MINIMAL_SETJMP(env_unsup_insn)) {
+ have_DSPr2 = False;
+ } else {
+ __asm__ __volatile__(".word 0x7d095351"); /* precr.qb.ph t2, t0, t1 */
+ }
+
+ VG_(convert_sigaction_fromK_to_toK)(&saved_sigill_act, &tmp_sigill_act);
+ VG_(sigaction)(VKI_SIGILL, &tmp_sigill_act, NULL);
+ VG_(sigprocmask)(VKI_SIG_SETMASK, &saved_set, NULL);
+
+ if (have_DSP) vai.hwcaps |= VEX_MIPS_ASE_DSP;
+ if (have_DSPr2) vai.hwcaps |= VEX_MIPS_ASE_DSP2P;
+ VG_(debugLog)(1, "machine", "hwcaps = 0x%x\n", vai.hwcaps);
VG_(machine_get_cache_info)(&vai);
return True;
Modified: trunk/include/pub_tool_libcsetjmp.h (+7 -0)
===================================================================
--- trunk/include/pub_tool_libcsetjmp.h 2013-07-22 23:00:13 +01:00 (rev 13469)
+++ trunk/include/pub_tool_libcsetjmp.h 2013-07-25 09:22:08 +01:00 (rev 13470)
@@ -108,7 +108,14 @@
__attribute__((regparm(1))) // ditto
void VG_MINIMAL_LONGJMP(VG_MINIMAL_JMP_BUF(_env));
+#elif defined(VGP_mips32_linux)
+#define VG_MINIMAL_JMP_BUF(_name) UInt _name [8+1+1+1+1]
+__attribute__((returns_twice))
+UWord VG_MINIMAL_SETJMP(VG_MINIMAL_JMP_BUF(_env));
+__attribute__((noreturn))
+void VG_MINIMAL_LONGJMP(VG_MINIMAL_JMP_BUF(_env));
+
#else
/* The default implementation. */
Modified: trunk/memcheck/mc_machine.c (+9 -1)
===================================================================
--- trunk/memcheck/mc_machine.c 2013-07-22 23:00:13 +01:00 (rev 13469)
+++ trunk/memcheck/mc_machine.c 2013-07-25 09:22:08 +01:00 (rev 13470)
@@ -1060,8 +1060,16 @@
if (o >= GOF(f30) && o+sz <= GOF(f30)+SZB(f30)) return GOF(f30);
if (o >= GOF(f31) && o+sz <= GOF(f31)+SZB(f31)) return GOF(f31);
- if ((o > GOF(NRADDR)) && (o <= GOF(NRADDR) +12 )) return -1; /*padding registers*/
+ /* Slot unused. */
+ if ((o > GOF(NRADDR)) && (o <= GOF(NRADDR) +12 )) return -1;
+ /* MIPS32 DSP ASE(r2) specific registers. */
+ if (o == GOF(DSPControl) && sz == 4) return o;
+ if (o == GOF(ac0) && sz == 8) return o;
+ if (o == GOF(ac1) && sz == 8) return o;
+ if (o == GOF(ac2) && sz == 8) return o;
+ if (o == GOF(ac3) && sz == 8) return o;
+
VG_(printf)("MC_(get_otrack_shadow_offset)(mips)(off=%d,sz=%d)\n",
offset,szB);
tl_assert(0);
|