Re: [hatari-devel] DSP bug: need more explanations

[ Thread Index | Date Index | More lists.tuxfamily.org/hatari-devel Archives ]


Do any existing programs rely on the pipeline behavior for the AGU? I thought it was undefined behavior and therefore not reliable? Or is it mainly to ensure some bugs get emulated too?

I'll need to look at the manual again for this but IIRC it was stated as undefined behavior to read an AGU reg during an update operation.

Same applies to writing the same register twice in the same instruction.

D

On 24 December 2014 at 17:40, <laurent.sallafranque@xxxxxxx> wrote:
Hi all,

I know for Lua, it was a bug I fixed into hatari 3-4 years ago (thanks to the old badmood ;) .
I just try to fix the AGU EA registers pipeline effect now.

I think I've got the idea to do it now, but I'm not at home till next week.

Laurent



----- Mail original -----
De: "Douglas Little" <doug694@xxxxxxxxxxxxxx>
À: hatari-devel@xxxxxxxxxxxxxxxxxxx
Envoyé: Mercredi 24 Décembre 2014 17:48:43
Objet: Re: [hatari-devel] DSP bug: need more explanations






Be careful with lua - that instruction does not modify the source register, ever. It just loads an effective address into the destination, leaving the source untouched.

So...

lua (r0)+,r1

will load 'r0+1 -> r1'

But r0 remains unchanged because of the special behaviour of lua instruction.




This is different from using

OP x:(r0)+,a

...or..

OP (r0)+


...which do leave r0 changed.




"LUA
Operation:
ea. d
Load Updated Address LUA
Assembler Syntax:
LUA ea,D
Description: Load .the updated address into the destination address register D. The
source address register and the update mode used to compute the updated address
are specified by the effective address (ea). Note that the source address register
specified in the effective address is not updated. All update addressing modes may
be used."



D





On 21 December 2014 at 20:59, Laurent Sallafranque < laurent.sallafranque@xxxxxxx > wrote:


Hi all,

I'm currently working on a bug in the DSP emulation :

some registers need 2 pipeline cycles to be useable :
eg : lua (r0)+,r2

with this instruction, R2 is set to the value r0+1 at instruction +2 (ie at instruction +1, it's the old value of R2 that is available).

There are 7 instructions in this case :
movep, movem, move, parallal move (2 instructions), lua and tcc.


I've written a little program under the DSP that does the following :

test1: ; start the test
clr a
move #$1,r0
move a,r1
move a,r2
move a,r3
nop
nop
lua (r0)+,r1
lua (r1)+,r2
lua (r2)+,r3

wait_transmit
move r1,x:HTX

wait_transmit
move r2,x:HTX

wait_transmit
move r3,x:HTX



On the real falcon side, I get the following values for R1, R2 and R3:
2
1
1

In hatari, I get the wrong values:
2
3
4


The DSP emulation works so far, because when one's compile his DSP code, he's warned about this by the compiler (or the DSP code doesn't work on the real computer). So coder often add a nop inbetween the move and the use of the register (or they add an instruction that doesn't use the register).


So, I've added a fake pipeline code for the instruction lua : instead of changing the register's value, I save it into a little pipeline table in the dsp_core structure :

Uint32 reg_pipeline[2][2];

in the lua instruction, I write the reg number into dsp_core.reg_pipeline[1][0] and the reg value into dsp_core.reg_pipeline[1][1]

In the main DSP code, I test if dsp_core.reg_pipeline[0][0] != 0
If this is true, I change the value of the register itself with the value into dsp_core.reg_pipeline[0][1]

And then, I always copy the pipeline like this :

dsp_core.reg_pipeline[0][0] = dsp_core.reg_pipeline[1][0];
dsp_core.reg_pipeline[0][1] = dsp_core.reg_pipeline[1][1];
dsp_core.reg_pipeline[1][0] = 0;

Like this, if I write a value into dsp_core.reg_pipeline[1][0], it is moved into dsp_core.reg_pipeline[0][0] during the next instruction and then copied into the final register for the second one.

The result with my test is OK under hatari, I get
2
1
1
like on the real computer.


The problem is that all the DSP programs that run under hatari without this fix don't work anymore, wich means that this fix is probably more complex than what it looks like at first glance.
I thought the fix shouldn't interfer with the current working programs, as coders often add a nop or a single instruction inbetween the loading of the register and it's use.
So they use the register value at the 2nd instruction and my code should be OK.


Does anybody have an idea about what could be wrong ? (Doug maybe ?)
Are there different case to take into account ?

Regards

Laurent











Mail converted by MHonArc 2.6.19+ http://listengine.tuxfamily.org/