From: Aleksandar Rikalo Date: Tue, 14 Jan 2020 12:09:18 +0000 (+0000) Subject: mips: Fix UASWM and UALWM instructions for nanoMIPS X-Git-Tag: VALGRIND_3_16_0~143 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=8b7a3a2107c4e4465b256c61ae69bcf0421816bd;p=thirdparty%2Fvalgrind.git mips: Fix UASWM and UALWM instructions for nanoMIPS UASWM and UALWM have not been implemented correctly. Code used to implement SWM and LWM has been reused without making all of the required adjustments. This fixes memcpy() and memset() libc functions. --- diff --git a/VEX/priv/guest_nanomips_toIR.c b/VEX/priv/guest_nanomips_toIR.c index 373ba5f9a0..7233a73691 100755 --- a/VEX/priv/guest_nanomips_toIR.c +++ b/VEX/priv/guest_nanomips_toIR.c @@ -2086,19 +2086,27 @@ static void nano_plsuawm(DisResult *dres, UInt cins) UChar count3 = (cins >> 12) & 0x07; UChar count = count3 ? count3 : 8; UChar counter = 0; - UInt offset = extend_sign(s, 9); + UInt offset = s; UChar rt_tmp, offset_tmp; - if ((cins >> 11) & 0x01) { /* swm */ - while (counter++ != count) { + if ((cins >> 11) & 0x01) { /* uaswm */ + + DIP("uaswm r%u, %d(r%u), %u", rt, (int)offset, rs, count); + + while (counter != count) { rt_tmp = rt ? (rt & 0x10) | ((rt + counter) & 0x1F) : 0; offset_tmp = offset + (counter << 2); store(binop(Iop_Add32, getIReg(rs), mkU32(offset_tmp)), getIReg(rt_tmp)); + counter+=1; } - } else { /* lwm */ - while (counter++ != count) { - rt_tmp = (rt & 0x10) | (rt + counter); + + } else { /* ualwm */ + + DIP("ualwm r%u, %d(r%u), %u", rt, (int)offset, rs, count); + + while (counter != count) { + rt_tmp = (rt & 0x10) | ((rt + counter) & 0x1F); offset_tmp = offset + (counter << 2); putIReg(rt_tmp, load(Ity_I32, binop(Iop_Add32, getIReg(rs), mkU32(offset_tmp)))); @@ -2107,6 +2115,7 @@ static void nano_plsuawm(DisResult *dres, UInt cins) vassert(0); // raise UNPREDICTABLE() } + counter+=1; } }