diff options
author | Richard Henderson <rth@twiddle.net> | 2013-09-04 08:51:07 -0700 |
---|---|---|
committer | Richard Henderson <rth@twiddle.net> | 2013-10-12 16:19:19 -0700 |
commit | b3e2bc500f5fe09763a107e2e28cb0e2d39ffb7c (patch) | |
tree | 46a6479cee93ddd3a821cb52af3f15420dac00bb | |
parent | 7352ee546ce0aba261d0e64595eae6e74e75e49d (diff) | |
download | qemu-b3e2bc500f5fe09763a107e2e28cb0e2d39ffb7c.zip |
tcg-i386: Remove "cb" output restriction from qemu_st8 for i386
Once we form a combined qemu_st_i32 opcode, we won't be able to
have separate constraints based on size. This one is fairly easy
to work around, since eax is available as a scratch register.
When storing variable data, this tends to merely exchange one mov
for another. E.g.
-: mov %esi,%ecx
...
-: mov %cl,(%edx)
+: mov %esi,%eax
+: mov %al,(%edx)
Where we do have a regression is when storing constant data, in which
we may load the constant into edi, when only ecx/ebx ought to be used.
The proper way to recover this regression is to allow constants as
arguments to qemu_st_i32, so that we never load the constant data into
a register at all, must less the wrong register. TBD.
Signed-off-by: Richard Henderson <rth@twiddle.net>
-rw-r--r-- | tcg/i386/tcg-target.c | 10 |
1 files changed, 8 insertions, 2 deletions
diff --git a/tcg/i386/tcg-target.c b/tcg/i386/tcg-target.c index a7ff8a3b4c..f4fdce51ce 100644 --- a/tcg/i386/tcg-target.c +++ b/tcg/i386/tcg-target.c @@ -1479,6 +1479,12 @@ static void tcg_out_qemu_st_direct(TCGContext *s, TCGReg datalo, TCGReg datahi, switch (memop & MO_SIZE) { case MO_8: + /* In 32-bit mode, 8-byte stores can only happen from [abcd]x. + Use the scratch register if necessary. */ + if (TCG_TARGET_REG_BITS == 32 && datalo >= 4) { + tcg_out_mov(s, TCG_TYPE_I32, scratch, datalo); + datalo = scratch; + } tcg_out_modrm_offset(s, OPC_MOVB_EvGv + P_REXB_R + seg, datalo, base, ofs); break; @@ -2084,7 +2090,7 @@ static const TCGTargetOpDef x86_op_defs[] = { { INDEX_op_qemu_ld32, { "r", "L" } }, { INDEX_op_qemu_ld64, { "r", "r", "L" } }, - { INDEX_op_qemu_st8, { "cb", "L" } }, + { INDEX_op_qemu_st8, { "L", "L" } }, { INDEX_op_qemu_st16, { "L", "L" } }, { INDEX_op_qemu_st32, { "L", "L" } }, { INDEX_op_qemu_st64, { "L", "L", "L" } }, @@ -2096,7 +2102,7 @@ static const TCGTargetOpDef x86_op_defs[] = { { INDEX_op_qemu_ld32, { "r", "L", "L" } }, { INDEX_op_qemu_ld64, { "r", "r", "L", "L" } }, - { INDEX_op_qemu_st8, { "cb", "L", "L" } }, + { INDEX_op_qemu_st8, { "L", "L", "L" } }, { INDEX_op_qemu_st16, { "L", "L", "L" } }, { INDEX_op_qemu_st32, { "L", "L", "L" } }, { INDEX_op_qemu_st64, { "L", "L", "L", "L" } }, |