From: Tom Hughes Date: Sun, 28 Mar 2004 11:26:29 +0000 (+0000) Subject: For FPU/MMX/SSE instructions which don't reference any memory, make memcheck X-Git-Tag: svn/VALGRIND_2_1_2~161 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=99e443c3f5e73bfbe238560b860bf7d06ba8e89f;p=thirdparty%2Fvalgrind.git For FPU/MMX/SSE instructions which don't reference any memory, make memcheck look at whether the eflags are read or written and generate UCode to validate and/or mark as valid the eflags when necessary. CCMAIL: 78514-done@bugs.kde.org git-svn-id: svn://svn.valgrind.org/valgrind/trunk@2344 --- diff --git a/memcheck/mc_translate.c b/memcheck/mc_translate.c index 7a2e05b2a1..301d9da568 100644 --- a/memcheck/mc_translate.c +++ b/memcheck/mc_translate.c @@ -1177,12 +1177,26 @@ static UCodeBlock* memcheck_instrument ( UCodeBlock* cb_in ) VG_(copy_UInstr)(cb, u_in); break; } - - /* For FPU, MMX and SSE insns not referencing memory, just - copy thru. */ + + /* For MMX and SSE insns not referencing memory, just + make sure the eflags are defined if the instruction + read them, and make them defined it it writes them. */ case SSE5: case SSE4: case SSE3: case MMX1: case MMX2: case MMX3: - case FPU: + case FPU: + if (u_in->flags_r != FlagsEmpty) { + qt = create_GETVF(cb, 0); + uInstr1(cb, TESTV, 0, TempReg, qt); + /* qt should never be referred to again. Nevertheless + ... */ + uInstr1(cb, SETV, 0, TempReg, qt); + } + if (u_in->flags_w != FlagsEmpty) { + qd = newTemp(cb); + uInstr2(cb, MOV, 4, Literal, 0, TempReg, qd); + uLiteral(cb, qd); + create_PUTVF(cb, 0, qd); + } VG_(copy_UInstr)(cb, u_in); break; diff --git a/memcheck/tests/.cvsignore b/memcheck/tests/.cvsignore index 42dfbb8526..9fc694b6c3 100644 --- a/memcheck/tests/.cvsignore +++ b/memcheck/tests/.cvsignore @@ -16,6 +16,7 @@ execve exitprog filter_leak_check_size filter_stderr +fpeflags fprw fwrite inits diff --git a/memcheck/tests/Makefile.am b/memcheck/tests/Makefile.am index 40ba819a4e..37a3dbae3a 100644 --- a/memcheck/tests/Makefile.am +++ b/memcheck/tests/Makefile.am @@ -27,6 +27,7 @@ EXTRA_DIST = $(noinst_SCRIPTS) \ errs1.stderr.exp errs1.vgtest \ exitprog.stderr.exp exitprog.vgtest \ execve.stderr.exp execve.vgtest \ + fpeflags.stderr.exp fpeflags.vgtest \ fprw.stderr.exp fprw.vgtest \ fwrite.stderr.exp fwrite.stdout.exp fwrite.vgtest \ inits.stderr.exp inits.vgtest \ @@ -75,7 +76,7 @@ check_PROGRAMS = \ badaddrvalue badfree badjump badloop badrw brk buflen_check \ clientperm custom_alloc \ doublefree error_counts errs1 exitprog execve \ - fprw fwrite inits inline \ + fpeflags fprw fwrite inits inline \ malloc1 malloc2 malloc3 manuel1 manuel2 manuel3 \ memalign_test memcmptest mmaptest nanoleak new_nothrow null_socket \ overlap pushfpopf \ @@ -102,6 +103,7 @@ error_counts_SOURCES = error_counts.c errs1_SOURCES = errs1.c execve_SOURCES = execve.c exitprog_SOURCES = exitprog.c +fpeflags_SOURCES = fpeflags.c fprw_SOURCES = fprw.c fwrite_SOURCES = fwrite.c inits_SOURCES = inits.c @@ -141,3 +143,5 @@ mismatches_SOURCES = mismatches.cpp new_nothrow_SOURCES = new_nothrow.cpp new_override_SOURCES = new_override.cpp +# must be built with these flags -- bug only occurred with them +fpeflags.o: CFLAGS += -march=i686 diff --git a/memcheck/tests/fpeflags.c b/memcheck/tests/fpeflags.c new file mode 100644 index 0000000000..27cd3e3e99 --- /dev/null +++ b/memcheck/tests/fpeflags.c @@ -0,0 +1,20 @@ +#include + +struct instance +{ + unsigned myVal:1; +}; + +static struct instance* myInstance; + +int main(int argc, char** argv) +{ + float g = 1.0f; + + myInstance = malloc(sizeof(struct instance)); + + myInstance->myVal = 1; + + if (g == 1.0f) + return 0; +} diff --git a/memcheck/tests/fpeflags.stderr.exp b/memcheck/tests/fpeflags.stderr.exp new file mode 100644 index 0000000000..e69de29bb2 diff --git a/memcheck/tests/fpeflags.vgtest b/memcheck/tests/fpeflags.vgtest new file mode 100644 index 0000000000..88ae11d59a --- /dev/null +++ b/memcheck/tests/fpeflags.vgtest @@ -0,0 +1,2 @@ +vgopts: -q +prog: fpeflags