public inbox for linux-m68k@lists.linux-m68k.org
 help / color / mirror / Atom feed
* FPU emulation incorrect for 68LC040?
@ 2010-07-21 20:22 Mattias Engdegård
  2010-07-21 20:32 ` Geert Uytterhoeven
  0 siblings, 1 reply; 9+ messages in thread
From: Mattias Engdegård @ 2010-07-21 20:22 UTC (permalink / raw)
  To: linux-m68k, zippel, geert

Does anyone know whether a 68LC040 alters the address register in  
postincrement/predecrement modes when it calculates the effective  
address for an FP instruction? The FPU emulation in the kernel seems  
to assume that it doesn't, but that doesn't really make sense.

If the 'LC040 does increment a0 in fadd.d (a0)+,fp0, say, then the  
Linux FPU emulation is quite broken, at least in 2.6.34. If not, then  
I have misunderstood how the hardware works.

I'm writing a 68040/68LC040 simulator and unfortunately do not have a  
real 'LC040 to do experiments on. If someone with actual hardware  
could help me, I'd be most grateful.

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: FPU emulation incorrect for 68LC040?
  2010-07-21 20:22 FPU emulation incorrect for 68LC040? Mattias Engdegård
@ 2010-07-21 20:32 ` Geert Uytterhoeven
  2010-07-21 20:53   ` Mattias Engdegård
  0 siblings, 1 reply; 9+ messages in thread
From: Geert Uytterhoeven @ 2010-07-21 20:32 UTC (permalink / raw)
  To: Mattias Engdegård; +Cc: linux-m68k, zippel

On Wed, Jul 21, 2010 at 22:22, Mattias Engdegård <mattiase@bredband.net> wrote:
> Does anyone know whether a 68LC040 alters the address register in
> postincrement/predecrement modes when it calculates the effective address
> for an FP instruction? The FPU emulation in the kernel seems to assume that
> it doesn't, but that doesn't really make sense.
>
> If the 'LC040 does increment a0 in fadd.d (a0)+,fp0, say, then the Linux FPU
> emulation is quite broken, at least in 2.6.34. If not, then I have
> misunderstood how the hardware works.

As the 'LC040 doesn't implement FPU instructions, I'd expect it to
just generate an
exception when the "fadd.d (a0)+,fp0" is encountered. I.e. not do anything else,
like postincrementing a0.

> I'm writing a 68040/68LC040 simulator and unfortunately do not have a real
> 'LC040 to do experiments on. If someone with actual hardware could help me,
> I'd be most grateful.

Sorry, only a full '040 here.

Gr{oetje,eeting}s,

                        Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
                                -- Linus Torvalds

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: FPU emulation incorrect for 68LC040?
  2010-07-21 20:32 ` Geert Uytterhoeven
@ 2010-07-21 20:53   ` Mattias Engdegård
  2010-07-22  1:05     ` Finn Thain
  0 siblings, 1 reply; 9+ messages in thread
From: Mattias Engdegård @ 2010-07-21 20:53 UTC (permalink / raw)
  To: Geert Uytterhoeven; +Cc: linux-m68k, zippel

21 jul 2010 kl. 22.32 skrev Geert Uytterhoeven:

> As the 'LC040 doesn't implement FPU instructions, I'd expect it to
> just generate an
> exception when the "fadd.d (a0)+,fp0" is encountered. I.e. not do  
> anything else,
> like postincrementing a0.

According to the manual, it generates a special 8-word exception frame  
that contains the decoded effective address, as a help to the  
emulator. It only makes sense if the user can just use that EA right  
away (after having established that it is a memory operand). I suppose  
the only way to find out is to find someone with a genuine 'LC040 (a  
non-buggy one).

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: FPU emulation incorrect for 68LC040?
  2010-07-21 20:53   ` Mattias Engdegård
@ 2010-07-22  1:05     ` Finn Thain
  2010-07-22 19:55       ` Mattias Engdegård
  0 siblings, 1 reply; 9+ messages in thread
From: Finn Thain @ 2010-07-22  1:05 UTC (permalink / raw)
  To: Mattias Engdegård; +Cc: Geert Uytterhoeven, linux-m68k, zippel

[-- Attachment #1: Type: TEXT/PLAIN, Size: 966 bytes --]


On Wed, 21 Jul 2010, Mattias Engdegård wrote:

> 21 jul 2010 kl. 22.32 skrev Geert Uytterhoeven:
> 
> > As the 'LC040 doesn't implement FPU instructions, I'd expect it to 
> > just generate an exception when the "fadd.d (a0)+,fp0" is encountered. 
> > I.e. not do anything else, like postincrementing a0.
> 
> According to the manual, it generates a special 8-word exception frame 
> that contains the decoded effective address, as a help to the emulator. 
> It only makes sense if the user can just use that EA right away (after 
> having established that it is a memory operand). I suppose the only way 
> to find out is to find someone with a genuine 'LC040 (a non-buggy one).

I have both kinds, buggy and non-buggy. Unfortunately, these machines 
(PowerBooks) don't have working SCSI and the one with IDE has no Linux 
filesystem.

But if you send me some inline asm, I'll patch it into busybox and test a 
2.6.34 initramfs for you.

Finn

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: FPU emulation incorrect for 68LC040?
  2010-07-22  1:05     ` Finn Thain
@ 2010-07-22 19:55       ` Mattias Engdegård
  2010-07-23  4:12         ` Finn Thain
  0 siblings, 1 reply; 9+ messages in thread
From: Mattias Engdegård @ 2010-07-22 19:55 UTC (permalink / raw)
  To: Finn Thain; +Cc: Geert Uytterhoeven, linux-m68k, zippel

22 jul 2010 kl. 03.05 skrev Finn Thain:

> But if you send me some inline asm, I'll patch it into busybox and  
> test a
> 2.6.34 initramfs for you.

Thanks! Try this:

void test_postinc(void)
{
         double x = 0.0;
         double a[2] = {3.5, 0.0};
         double *p = a;
         __asm__ volatile  ("fneg.d (%0)+,%1" : "+a"(p), "+f"(x));
         printf("postinc: result %f (expected %f), address %p  
(expected %p)\n",
                x, -3.5, p, a + 1);
}

void test_predec(void)
{
         double x = 0.0;
         double a[2] = {-1.75, 0.0};
         double *p = a + 1;
         __asm__ volatile  ("fneg.d -(%0),%1" : "+a"(p), "+f"(x));
         printf("predec: result %f (expected %f), address %p (expected  
%p)\n",
                x, 1.75, p, a);
}

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: FPU emulation incorrect for 68LC040?
  2010-07-22 19:55       ` Mattias Engdegård
@ 2010-07-23  4:12         ` Finn Thain
  2010-07-23  8:39           ` Mattias Engdegård
  0 siblings, 1 reply; 9+ messages in thread
From: Finn Thain @ 2010-07-23  4:12 UTC (permalink / raw)
  To: Mattias Engdegård; +Cc: Geert Uytterhoeven, linux-m68k, zippel

[-- Attachment #1: Type: TEXT/PLAIN, Size: 3385 bytes --]


On Thu, 22 Jul 2010, Mattias Engdegård wrote:

> 22 jul 2010 kl. 03.05 skrev Finn Thain:
> 
> > But if you send me some inline asm, I'll patch it into busybox and test a
> > 2.6.34 initramfs for you.
> 
> Thanks! Try this:
> 
> void test_postinc(void)
> {
>        double x = 0.0;
>        double a[2] = {3.5, 0.0};
>        double *p = a;
>        __asm__ volatile  ("fneg.d (%0)+,%1" : "+a"(p), "+f"(x));
>        printf("postinc: result %f (expected %f), address %p (expected %p)\n",
>               x, -3.5, p, a + 1);
> }
> 
> void test_predec(void)
> {
>        double x = 0.0;
>        double a[2] = {-1.75, 0.0};
>        double *p = a + 1;
>        __asm__ volatile  ("fneg.d -(%0),%1" : "+a"(p), "+f"(x));
>        printf("predec: result %f (expected %f), address %p (expected %p)\n",
>               x, 1.75, p, a);
> }
> 

I ran this on a PowerBook 190cs:

postinc: result -3.500000 (expected -3.500000), address 0xef8ddcf8 (expected 0xef8ddcf8)
predec: result 1.750000 (expected 1.750000), address 0xef8ddcf0 (expected 0xef8ddcf0)

It is probably not relevant, but I believe that this CPU is free from the 
68LC040 erratum that affects page faults and FPU ops as I've tested for 
that before.

# cat /proc/cpuinfo
CPU:            68040
MMU:            68040
FPU:            none
Clocking:       32.9MHz
BogoMips:       21.96
Calibration:    109824 loops
# cat /proc/version
Linux version 2.6.34-mac (fthain@nippy) (gcc version 4.4.4 (GCC) ) #5 Fri Jul 23 13:32:53 EST 2010

Here's the disassembly:

8007da96 <test_predec>:
8007da96:	4e56 fff0      	linkw %fp,#-16
8007da9a:	2d7c bffc 0000 	movel #-1074003968,%fp@(-16)
8007daa0:	fff0 
8007daa2:	42ae fff4      	clrl %fp@(-12)
8007daa6:	42ae fff8      	clrl %fp@(-8)
8007daaa:	42ae fffc      	clrl %fp@(-4)
8007daae:	41ee fff8      	lea %fp@(-8),%a0
8007dab2:	f200 5c0f      	fmovecrx #15,%fp0
8007dab6:	f220 541a      	fnegd %a0@-,%fp0
8007daba:	486e fff0      	pea %fp@(-16)
8007dabe:	2f08           	movel %a0,%sp@-
8007dac0:	42a7           	clrl %sp@-
8007dac2:	2f3c 3ffc 0000 	movel #1073479680,%sp@-
8007dac8:	f227 7400      	fmoved %fp0,%sp@-
8007dacc:	4879 8009 b25a 	pea 8009b25a <isoformats.7051+0x29>
8007dad2:	2f39 800a 8e04 	movel 800a8e04 <_IO_stderr>,%sp@-
8007dad8:	4eb9 8000 e564 	jsr 8000e564 <__fprintf>
8007dade:	4fef 0020      	lea %sp@(32),%sp
8007dae2:	4e5e           	unlk %fp
8007dae4:	4e75           	rts

8007dae6 <test_postinc>:
8007dae6:	4e56 fff0      	linkw %fp,#-16
8007daea:	2d7c 400c 0000 	movel #1074528256,%fp@(-16)
8007daf0:	fff0 
8007daf2:	42ae fff4      	clrl %fp@(-12)
8007daf6:	42ae fff8      	clrl %fp@(-8)
8007dafa:	42ae fffc      	clrl %fp@(-4)
8007dafe:	41ee fff0      	lea %fp@(-16),%a0
8007db02:	f200 5c0f      	fmovecrx #15,%fp0
8007db06:	f218 541a      	fnegd %a0@+,%fp0
8007db0a:	486e fff8      	pea %fp@(-8)
8007db0e:	2f08           	movel %a0,%sp@-
8007db10:	42a7           	clrl %sp@-
8007db12:	2f3c c00c 0000 	movel #-1072955392,%sp@-
8007db18:	f227 7400      	fmoved %fp0,%sp@-
8007db1c:	4879 8009 b295 	pea 8009b295 <isoformats.7051+0x64>
8007db22:	2f39 800a 8e04 	movel 800a8e04 <_IO_stderr>,%sp@-
8007db28:	4eb9 8000 e564 	jsr 8000e564 <__fprintf>
8007db2e:	4fef 0020      	lea %sp@(32),%sp
8007db32:	4e5e           	unlk %fp
8007db34:	4e75           	rts

HTH

Finn

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: FPU emulation incorrect for 68LC040?
  2010-07-23  4:12         ` Finn Thain
@ 2010-07-23  8:39           ` Mattias Engdegård
  2010-07-24  0:31             ` Michael Schmitz
  0 siblings, 1 reply; 9+ messages in thread
From: Mattias Engdegård @ 2010-07-23  8:39 UTC (permalink / raw)
  To: Finn Thain; +Cc: Geert Uytterhoeven, linux-m68k, zippel

23 jul 2010 kl. 06.12 skrev Finn Thain:

> I ran this on a PowerBook 190cs:
>
> postinc: result -3.500000 (expected -3.500000), address 0xef8ddcf8  
> (expected 0xef8ddcf8)
> predec: result 1.750000 (expected 1.750000), address 0xef8ddcf0  
> (expected 0xef8ddcf0)

Thank you! It indicates that the address generation does not alter any  
registers (because the FPU emulation will do so, and we didn't see a  
duplicated change). This is a bit surprising to me, but your evidence  
cannot be refuted. Anyway, it's good to have cast light on the matter.

(And Geert can say "told you so".)

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: FPU emulation incorrect for 68LC040?
  2010-07-23  8:39           ` Mattias Engdegård
@ 2010-07-24  0:31             ` Michael Schmitz
  2010-07-24 18:33               ` Mattias Engdegård
  0 siblings, 1 reply; 9+ messages in thread
From: Michael Schmitz @ 2010-07-24  0:31 UTC (permalink / raw)
  To: Mattias Engdegård; +Cc: Finn Thain, Geert Uytterhoeven, linux-m68k, zippel

Hi,

the way I understood post-increment to work was for this to happen
only after instruction execution. If the effective address had been
modified already, it would be more difficult for an emulator to
determine the correct address after the trap. Also, it seems more
efficient to first decode the instruction (and trap if needed) before
fully decoding the address.

  Michael (posting from gmail since my old mail account has gone down
in flames with a RAID5 crash at my old lab ...)

On Fri, Jul 23, 2010 at 8:39 PM, Mattias Engdegård
<mattiase@bredband.net> wrote:
> 23 jul 2010 kl. 06.12 skrev Finn Thain:
>
>> I ran this on a PowerBook 190cs:
>>
>> postinc: result -3.500000 (expected -3.500000), address 0xef8ddcf8
>> (expected 0xef8ddcf8)
>> predec: result 1.750000 (expected 1.750000), address 0xef8ddcf0 (expected
>> 0xef8ddcf0)
>
> Thank you! It indicates that the address generation does not alter any
> registers (because the FPU emulation will do so, and we didn't see a
> duplicated change). This is a bit surprising to me, but your evidence cannot
> be refuted. Anyway, it's good to have cast light on the matter.
>
> (And Geert can say "told you so".)
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-m68k" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
>

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: FPU emulation incorrect for 68LC040?
  2010-07-24  0:31             ` Michael Schmitz
@ 2010-07-24 18:33               ` Mattias Engdegård
  0 siblings, 0 replies; 9+ messages in thread
From: Mattias Engdegård @ 2010-07-24 18:33 UTC (permalink / raw)
  To: Michael Schmitz; +Cc: Finn Thain, Geert Uytterhoeven, linux-m68k, zippel

> the way I understood post-increment to work was for this to happen
> only after instruction execution. If the effective address had been
> modified already, it would be more difficult for an emulator to
> determine the correct address after the trap. Also, it seems more
> efficient to first decode the instruction (and trap if needed) before
> fully decoding the address.

The 68LC040 calculates the effective address of unimplemented FP  
instructions and puts it in the exception frame so that the emulator  
should not have to - after all, the CPU already has the hardware to do  
EA calculations the right way. On the other hand, an instruction that  
traps will not, in general, alter any register.

For example, move.l -(a0),-(a0) will decrement a0 twice, once before  
the load and once again before the store. But if the either the load  
or store traps, the exception handler will see an unchanged register.  
At least this is my understanding after various experiments - the  
official docs are not very explicit about it.

^ permalink raw reply	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2010-07-24 18:33 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2010-07-21 20:22 FPU emulation incorrect for 68LC040? Mattias Engdegård
2010-07-21 20:32 ` Geert Uytterhoeven
2010-07-21 20:53   ` Mattias Engdegård
2010-07-22  1:05     ` Finn Thain
2010-07-22 19:55       ` Mattias Engdegård
2010-07-23  4:12         ` Finn Thain
2010-07-23  8:39           ` Mattias Engdegård
2010-07-24  0:31             ` Michael Schmitz
2010-07-24 18:33               ` Mattias Engdegård

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox