bug caused by this instruction:
fmove.l fp0,d0
problem was caused by a conflict between the fpu emulator (softfloat) and the compiler.
the emulator implemented this as a purely arithmetic move & conversion,
but the compiler assumed that the result could be interpreted as a logical (ie unsigned) conversion.
rightly or wrongly.
for example, if fp0 contained the value 2576980377.0 which is unsigned integer -1717987328
the emulator would treat this as an integer overflow and move 0x7fffffff (INT_MAX) into d0.
The complier on the other hand would assume that d0 contained 2576980377 (the unsigned value).
I don't know which is correct, but this is my fix for the time being.
problem was implementation of fint & fintrz floating point ops in m68kfpu.c
Both these ops truncated the integer to 32 bits instead of leaving it as an extended precision floating point number
Changed the implementation to use 64 bit ints instead of 32 bit ints.
latest version of musashi engine
includes floating point emulation
(plus a few patches to add in missing opcodes needed by ack - see tags JFF & TBB)
added a few missing linux syscalls in sim.c
pascal now runs pretty well
quick test with modula2 passes
c gets the floating point numbers wrong, so more work needed here
other languages untested
plat/linux68k/emu/build.lua is probably not quite right - the softfloat directory is compiled in the wrong place
Add rules for 8-byte integers to m68020 ncg. Add 8-byte long long to
ACK C on linux68k. Enable long-long tests for linux68k. The tests
pass in our emulator using musahi; I don't have a real 68k processor
and haven't tried other emulators.
Still missing are conversions between 8-byte integers and any size of
floats. The long-long tests don't cover these conversions, and our
emulator can't do floating-point.
Our build always enables TBL68020 and uses word size 4. Without
TBL68020, 8-byte multiply and divide are missing. With word size 2,
some conversions between 2-byte and 8-byte integers are missing.
Fix .cii in libem, which didn't work when converting from 1-byte or
2-byte integers. Now .cii and .cuu work, but also add some rules to
skip .cii and .cuu when converting 8-byte integers. The new rule for
loc 4 loc 8 cii `with test_set4` exposes a bug: the table may believe
that the condition codes test a 4-byte register when they only test a
word or byte, and this incorrect test may describe an unsigned word or
byte as negative. Another rule `with exact test_set1+test_set2` works
around the bug by ignoring the negative flag, because a zero-extended
word or byte is never negative.
The old rules for comparison and logic do work with 8-byte integers
and bitsets, but add some specific 8-byte rules to skip libem calls or
loops. There were no rules for 8-byte arithmetic, shift, or rotate;
so add some. There is a register shortage, because the table requires
preserving d3 to d7, leaving only 3 data registers (d0, d1, d2) for
8-byte operations. Because of the shortage, the code may move data to
an address register, or read a memory location more than once.
The multiplication and division code are translations of the i386
code. They pass the tests, but might not give the best performance on
a real 68k processor.
Skip the long-long test set on other platforms, because they don't
have long long. Each platform would need to implement 8-byte
operations like `adi 8` in its code generator, and set long long to
8 bytes in its descr file.
The first test is for negation, addition, and subtraction. It also
requires comparison for equality.
From my request at https://github.com/kstenerud/Musashi/pull/31
There was a conflict between Musahi's uint and OpenBSD's uint:
$ cc -o m68kmake m68kmake.c
$ ./m68kmake
$ cc -DM68K_COMPILE_FOR_MAME=0 -c m68kcpu.c
In file included from m68kcpu.c:565:
In file included from /usr/include/stdio.h:46:
/usr/include/sys/types.h:58:22: error: cannot combine with previous 'int'
declaration specifier
typedef unsigned int uint; /* Sys V compatibility */
^
./m68kcpu.h:75:25: note: expanded from macro 'uint'
#define uint unsigned int
^
1 error generated.
Rename plat/linux/libsys/errno.s to plat/linux386/libsys/trapno.s and
stop building it for linux68k and linuxppc. It defines symbols for
mach/i386/libem.
In syscalls.h, the numbers after 165 are only for i386, so hide them
from 68k, ppc. These numbers are unused, because the system calls now
in libsys use the lower numbers.
Also teach the build system that libsys depends on the internal
headers in plat/linux/libsys/*.h
Linux passes the arguments in registers, but our compiler expects
arguments on the stack. Signal handlers got garbage instead of the
signal number. Some handlers, like the one in lang/m2/libm2/sigtrp.c,
need the correct signal number.
I write a "bridge" in PowerPC assembly that moves the arguments to the
stack. I put the bridge in sigaction(), so I provide a signal() that
calls sigaction(). I remove the *.c glob or wildcard from build.lua,
so linuxppc only compiles its own signal.c, not the other signal.c for
linux386 and linux68k.
My bridge uses sigprocmask(), so I also add sigprocmask(). Because
linux386 and linux68k use globs, they also get sigprocmask(). I sync
the header files so all three Linux platforms declare execve(),
sigprocmask(), and unlink(), but not remove(), because we have
remove() in <stdio.h>.
I am using sigaction.s to test some features that we recently added to
our PowerPC assembler. These are the "hi16[...]" and "lo16[...]"
syntax, and also the extended names like "beq", "cmpwi", "li", "subi".
This needed lots of refactoring to ego --- not all platforms have ego descr
files, and ego will just crash if you invoke it without one. I think originally
it was never intended that these platforms would be used at -O2 or above.
Plats now only specify the ego descr file if they have one.
directories --- wrangling descr files was too hard. C programs can be built
for cpm, pc86, linux386, linux68k!
--HG--
branch : dtrg-buildsystem
rename : util/ack/build.mk => util/led/build.mk
rename : util/LLgen/build.mk => util/topgen/build.mk