Issue 4807 Fix movem PC instruction bug on 68000

The `movem` instruction's `(d16, PC)` addressing mode has an instruction
word, a mask word, and then an extension word. The addressing mode
uses the value of PC incremented to the extension word, in this case
`instr_start + 4`. The sleigh code incorrectly uses `instr_start + 2`.
The issue is present for both `movem.w` and `movem.l` variants. This
PR fixes the `PC` offset to `+4`.

See 68000 reference manual page 2-13 for PC indirect addressing mode,
and 4-128 for MOVEM documentation.

Partially addresses #4807.
This commit is contained in:
Phlosioneer 2022-12-09 12:53:06 -05:00 committed by ghidorahrex
parent 1fcaf3c9cd
commit 058fa90387

View File

@ -1643,7 +1643,7 @@ m2rfl0: { m2rfl1} is mvm15=0 & m2rfl1 { }
:movem.w (regan)+,m2rfw0 is opbig=0x4c & op67=2 & mode=3 & regan; m2rfw0 { movemptr = regan; build m2rfw0; regan = movemptr; }
:movem.w (d16,regan),m2rfw0 is opbig=0x4c & op67=2 & mode=5 & regan; m2rfw0; d16 { movemptr = regan+d16; build m2rfw0; }
:movem.w (extw),m2rfw0 is opbig=0x4c & op67=2 & mode=6 & regan; m2rfw0; extw [ pcmode=0; regtfan=regan; ] { build extw; movemptr = extw; build m2rfw0; }
:movem.w (d16,PC),m2rfw0 is opbig=0x4c & op67=2 & mode=7 & regan=2; m2rfw0; d16 & PC { movemptr = inst_start+2+d16; build m2rfw0; }
:movem.w (d16,PC),m2rfw0 is opbig=0x4c & op67=2 & mode=7 & regan=2; m2rfw0; d16 & PC { movemptr = inst_start+4+d16; build m2rfw0; }
:movem.w (extw),m2rfw0 is opbig=0x4c & op67=2 & mode=7 & regan=3; m2rfw0; extw [ pcmode=1; ] { build extw; movemptr = extw; build m2rfw0; }
:movem.w (d16)".w",m2rfw0 is opbig=0x4c & op67=2 & mode=7 & regan=0; m2rfw0; d16 { movemptr = d16; build m2rfw0; }
:movem.w (d32)".l",m2rfw0 is opbig=0x4c & op67=2 & mode=7 & regan=1; m2rfw0; d32 { movemptr = d32; build m2rfw0; }
@ -1651,7 +1651,7 @@ m2rfl0: { m2rfl1} is mvm15=0 & m2rfl1 { }
:movem.l (regan)+,m2rfl0 is opbig=0x4c & op67=3 & mode=3 & regan; m2rfl0 { movemptr = regan; build m2rfl0; regan = movemptr; }
:movem.l (d16,regan),m2rfl0 is opbig=0x4c & op67=3 & mode=5 & regan; m2rfl0; d16 { movemptr = regan+d16; build m2rfl0; }
:movem.l (extw),m2rfl0 is opbig=0x4c & op67=3 & mode=6 & regan; m2rfl0; extw [ pcmode=0; regtfan=regan; ] { build extw; movemptr = extw; build m2rfl0; }
:movem.l (d16,PC),m2rfl0 is opbig=0x4c & op67=3 & mode=7 & regan=2; m2rfl0; d16 & PC { movemptr = inst_start+2+d16; build m2rfl0; }
:movem.l (d16,PC),m2rfl0 is opbig=0x4c & op67=3 & mode=7 & regan=2; m2rfl0; d16 & PC { movemptr = inst_start+4+d16; build m2rfl0; }
:movem.l (extw),m2rfl0 is opbig=0x4c & op67=3 & mode=7 & regan=3; m2rfl0; extw [ pcmode=1; ] { build extw; movemptr = extw; build m2rfl0; }
:movem.l (d16)".w",m2rfl0 is opbig=0x4c & op67=3 & mode=7 & regan=0; m2rfl0; d16 { movemptr = d16; build m2rfl0; }
:movem.l (d32)".l",m2rfl0 is opbig=0x4c & op67=3 & mode=7 & regan=1; m2rfl0; d32 { movemptr = d32; build m2rfl0; }