Implement support for the MMX instruction set. The scheme used is
the same as that for FPU instructions. That is, regard the MMX state
(which is the same as the FPU state) opaquely, and every time we
need to do a MMX instruction, move the simulated MMX state into the
real CPU, do the instruction, and move it back. JeremyF's optimisation
to minimise FPU saves/restores applies automatically here.
So, this scheme is simple. It will cause memcheck to complain bitterly
if uninitialised data is copied through the MMX registers, in the same
way that memcheck complains if you move uninit data through the FPU
registers. Whether this turns out to be a problem remains to be seen.
Most instructions are done, and doing the rest is easy enough, I just
need people to send test cases so I can do them on demand.
(Core) UCode has been extended with 7 new uinstrs:
MMX1 MMX2 MMX3
-- 1/2/3 byte mmx insns, no references to
integer regs or memory, copy exactly to the output stream.
MMX_MemRd MMX_MemWr
-- 2 byte mmx insns which read/write memory and therefore need
to have an address register patched in at code generation
time. These are the analogues to FPU_R / FPU_W.
MMX_RegRd MMX_RegWr
-- These have no analogues in FPU land. They hold 2 byte insns
which move data to/from a normal integer register (%eax etc),
and so this has to be made explicit so that (1) a suitable
int reg can be patched in at codegen time, and (2) so that
memcheck can do suitable magic with the V bits going into/
out of the MMX regs.
Nulgrind (ok, this is a nop, but still ...) and AddrCheck's
instrumenters have been extended to cover these new UInstrs. All
others (cachesim, memcheck, lackey, helgrind, did I forget any)
abort when they see any of them. This may be overkill but at least
it ensures we don't forget to implement it in those skins.
[A bad thing would be that some skin silently passes along
MMX uinstrs because of a default: case, when it should actually
do something with them.]
If this works out well, I propose to backport this to 2_0_BRANCH.
git-svn-id: svn://svn.valgrind.org/valgrind/trunk@1483 a5019735-40e9-0310-863c-91ae7b9d1cf9
diff --git a/addrcheck/ac_main.c b/addrcheck/ac_main.c
index 1bd842e..8de3290 100644
--- a/addrcheck/ac_main.c
+++ b/addrcheck/ac_main.c
@@ -1094,6 +1094,18 @@
VG_(copy_UInstr)(cb, u_in);
break;
+ case MMX2_MemRd:
+ case MMX2_MemWr:
+ sk_assert(u_in->size == 8);
+ t_addr = u_in->val2;
+ t_size = newTemp(cb);
+ uInstr2(cb, MOV, 4, Literal, 0, TempReg, t_size);
+ uLiteral(cb, 8);
+ uInstr2(cb, CCALL, 0, TempReg, t_addr, TempReg, t_size);
+ uCCall(cb, (Addr) & ac_fpu_ACCESS_check, 2, 2, False );
+ VG_(copy_UInstr)(cb, u_in);
+ break;
+
default:
VG_(copy_UInstr)(cb, u_in);
break;