davidgiven / ack

The Amsterdam Compiler Kit
http://tack.sf.net
Other
420 stars 59 forks source link

8-byte long long in ACK C for i386, m68020 #208

Closed kernigh closed 4 years ago

kernigh commented 4 years ago

This branch adds the type long long to ACK C, which is an 8-byte integer on i386 and m68020, and causes an error on other machines. A new test set in tests/plat/long-long operates on 8-byte integers on i386 and m68020. Beware that not everything works:

ACK languages had no 64-bit integers until now. My mail to tack-devel gave a few reasons to want 8-byte integers. Parts of the ACK assume that integers are never wider than 4 bytes, so I work around this assumption.

EM compact assembly can't encode an 8-byte constant for ldc (because the implementation of sp_cst8 is missing), so I modified the C compiler to avoid ldc with constants wider than 4 bytes. This diverts 8-byte constants to rom (where EM encodes them as strings) and causes slower code. For example, the C code

long long x;
long long f(void) { return x | 0x100LL; }

becomes the i386 code

I_1:
.data8  256
...
mov edx,(_x)
mov ecx,(_x+4)
or edx,(I_1)
or ecx,(I_1+4)

instead of the simpler

mov edx,(_x)
mov ecx,(_x+4)
or edx,256 ! may become orb dh,1

To implement sp_cst8 and enable ldc, one would need to widen the type arith from long to int64_t. This is difficult, because parts of the ACK assume that arith is always long. This branch keeps arith as long.

To convert between long long and floating-point types, one would need to change the interface to our mach/proto/fp software floating-point, which now assumes that integers have at most 4 bytes. This also affects i386, because its 8087 library has the same interface. For m68020, I use the ack's emulator, which is missing floating-point (but a newer version of musahi might have floating-point).

davidgiven commented 4 years ago

Thank you very much for this! I left a couple of small comments but I didn't spot any obvious issues.

My only concern is that there's a lot of scope for subtle, hard-to-find breakage in cemcom.ansi due to e.g. erroneously casting a writh to an arith and losing the top 32 bits, but this kind of problem isn't new and we should go ahead anyway. I've filed #209 because we really, really should have a proper test suite for this.

kernigh commented 4 years ago

After reading your comments, I added 2 more commits to change assembler's valu_t to int64_t and add back _EM_LSIZE == 8 to .

In my commit message for a434749, I mentioned startrek_c.linuxppc by mistake. It should be startrek_c.linuxmips. I'm too lazy to edit the message.

davidgiven commented 4 years ago

LGTM. Thank you very much!