Le 03/11/2016 à 20:47, Richard Henderson a écrit : > On 11/02/2016 03:15 PM, Laurent Vivier wrote: >> + if ((insn & 7) + 8 == i && >> + m68k_feature(s->env, M68K_FEATURE_EXT_FULL)) { >> + /* M68020+: if the addressing register is the >> + * register moved to memory, the value written >> + * is the initial value decremented by the >> size of >> + * the operation >> + * M68000/M68010: the value is the initial value >> + */ >> + TCGv tmp = tcg_temp_new(); >> + tcg_gen_sub_i32(tmp, mreg(i), incr); >> + gen_store(s, opsize, addr, tmp); >> + tcg_temp_free(tmp); > > This doesn't look right. Is the value stored the intermediate value of > the decremented register, or the final value? What you're storing is > reg-4, which is neither of these things. > > I could see, maybe, that reg-4 might well turn out to be the right value > for > > movem {a0-a7}, (sp)- > > since sp == a7, and therefore stored first. But I question that's the > correct result for > > movem {a0-a7}, (a1)- > > If it's the incremental value, then you can just store "addr" and you > don't need a temp. If it's the final value, then you can compute > > tcg_gen_subi_i32(tmp, AREG(insn, 0), ctpop32(mask) * 4); >
As it was not clear for me, I have written a test to see what was the good value. my test program is: top: .space 64,0 stack: .text .globl _start _start: lea stack,%a4 lea 1,%a0 lea 2,%a1 lea 3,%a2 lea 4,%a3 lea 5,%a5 lea 6,%a6 moveq.l #8, %d0 moveq.l #9, %d1 moveq.l #10, %d2 moveq.l #11, %d3 moveq.l #12, %d4 moveq.l #13, %d5 moveq.l #14, %d6 moveq.l #15, %d7 movem.l %a0-%a7/%d0-%d7,-(%a4) on a real 68040: initial value of A4 is 0x800020ec final value of A4 is 0x800020ac (gdb) x/15x 0x800020ac 0x800020ac: 0x00000008 0x00000009 0x0000000a 0x0000000b 0x800020bc: 0x0000000c 0x0000000d 0x0000000e 0x0000000f 0x800020cc: 0x00000001 0x00000002 0x00000003 0x00000004 0x800020dc: 0x800020e8 0x00000005 0x00000006 Stored value is thus 0x800020e8 so this is initial value - 4. [I have tried the same test with a1, for the same result] Laurent