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.
Also change UINT32_MAX in <stdint.h> from 4294967295 to 4294967295U.
The U suffix avoids a promotion to long or unsigned long if it would
fit in unsigned int.
Define _EM_LLSIZE but not EM_LLSIZE. The leading underscore is a
convention for such macros. If code always uses _EM_LLSIZE, we will
never need to add EM_LLSIZE. The flag -D_EM_LLSIZE={q} is in
plat/linux386/descr, not lib/descr/fe, so platforms without long long
don't define _EM_LLSIZE.
<stdint.h> doesn't keep the old code for _EM_LSIZE == 8, because I
change it to _EM_LLSIZE == 8. No platform had _EM_LSIZE == 8, and the
old limits like INT64_MAX were wrong.
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.
Add long long type, but without literals; you can't say '123LL' yet.
You can try constant operations, like `(long long)123 + 1`, but the
compiler's `arith` type might not be wide enough. Conversions,
shifts, and some other operations don't work in i386 ncg; I am using a
union instead of conversions:
union q {
long long ll;
unsigned long long ull;
int i[2];
};
Hack plat/linux386/descr to enable long long (size 8, alignment 4)
only for this platform. The default for other platforms is to disable
long long (size -1).
In lang/cem/cemcom.ansi,
- BigPars, SmallPars: Add default size, alignment of long long.
- align.h: Add lnglng_align.
- arith.c: Convert arithmetic operands to long long or unsigned long
long when necessary; avoid conversion from long long to long.
Allow long long as an arithmetic, integral, or logical operand.
- ch3.c: Handle long long like int and long when erroneously applying
a selector, like `long long ll; ll.member` or `ll->member`. Add
long long to integral and arithmetic types.
- code.c: Add long long to type stabs for debugging.
- conversion.c: Add long long to integral conversions.
- cstoper.c: Write masks up to full_mask[8]. Add FIXME comment.
- declar.g: Parse `long long` in code.
- decspecs.c: Understand long long in type declarations.
- eval.c: Add long long to operations, to generate code like `adi 8`.
Don't use `ldc` with constant over 4 bytes.
- ival.g: Allow long long in initializations.
- main.c: Set lnglng_type and related values.
- options.c: Add option like `-Vq8.4` to set long long to size 8,
alignment 4. I chose 'q', because Perl's pack and Ruby's
Array#pack use 'q' for 64-bit or long long values; it might be a
reference to BSD's old quad_t alias for long long.
- sizes.h: Add lnglng_size.
- stab.c: Allow long long when writing the type stab for debugging.
Switch from calculating the ranges to hardcoding them in strings;
add 8-byte ranges as a special case. This also hardcodes the
unsigned 4-byte range as "0;-1". Before it was either "0;-1" or
"0;4294967295", depending on sizeof(long) in the compiler.
- struct.c: Try long long bitfield, but it will probably give the
error, "bit field type long long does not fit in a word".
- switch.c: Update comment.
- tokenname.c: Define LNGLNG (long long) like LNGDBL (long double).
- type.c, type.str: Add lnglng_type and ulnglng_type. Add function
no_long_long() to check if long long is disabled.
This causes clang to give fewer warnings of implicit declarations of
functions.
In mach/pdp/cv/cv.c, rename wr_int2() to cv_int2() because it
conflicts with wr_int2() in <object.h>.
In util/ack, rename F_OK to F_TRANSFORM because it conflicts with F_OK
for access() in <unistd.h>.
In OpenBSD, _XOPEN_SOURCE 500 forces _POSIX_C_SOURCE down to 199506,
which hides the declarations of openat() and fdopendir() and causes
compiler warnings.
Don't set _POSIX_C_SOURCE, because _XOPEN_SOURCE may set
_POSIX_C_SOURCE to a different value.
The existing code allocated 2 bytes (char*), but gtty() needs 6 bytes
(struct sgttyb), so isatty() smashed the stack and corrupted its
return address, probably causing SIGBUS or SIGSEGV.
Fix by switching to TIOCGETD, which needs 2 bytes. TIOCGETD isn't in
the manual for tty(4), but does appear in
https://minnie.tuhs.org//cgi-bin/utree.pl?file=V7/usr/sys/dev/tty.c
This fixes hilo_c.pdpv7 and hilo_mod.pdpv7 in simh-pdp11.
Change the alignment in C structs (wa, pa, sa, and so on) from 1 to 2
bytes. This prevents the SIGBUS when PDP-11 Unix V7 catches the
misalignment. This fixes hilo_p.pdpv7 in simh-pdp11.
Change ALIGN to document that sections have 2-byte alignment. This
change should have no effect, because the sections only contain 2-byte
values.
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.
The code included <X11/Xfuncproto.h> only for _X_ATTRIBUTE_PRINTF,
which tells some compilers to check the printf format string. Remove
so ACK doesn't need any X11 headers.
Some machines don't have the X11 headers, or they need a flag like
-I/usr/X11R[67]/include to find them.
em libmon vanished decades ago (or never existed), and also ass appears to have
a different idea of what the em opcodes are to everything else and gets
confused.