* 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