Newsgroups: comp.sys.transputer
From: ifunltd@xs4all.hacktic.nl (ifunltd)
Subject: Re: INT64s in C
Organization: Hack-Tic, networking for the masses
Date: 19 Jul 1994 08:50:15 GMT
Message-ID: <30g44r$6g9@news4all.hacktic.nl>


here's some info on INT64 types in transputer programming.

No, Inmos did not think the world of transputer programmers was up to 
64-bit yet. Not very nice, but there are plenty of ways around this 
problem:

First, the suggestion from AIKI to use a bit of Occam works fine, if 
you have the Occam Toolset available. You can mix languages at link 
level, but if you do not write Occam yet, it's a lot of overhead.

Second, you can use the also mentioned trick of disassembling some 
Occam library code. But if you do not have the Occam toolset, you 
have the same problem of availability, and also you would still need 
to produce a small program doing INT64 calculations. In fact only one 
of the INT64 routines (long divide) is coded in the libraries, as far 
as I know, since the others are too simple not to generate inline in 
the compiler.

So you could think about another C compiler for transputers (I 
believe the parallel C compiler which is part of the ACE Expert PDS 
for transputers supports 64-bit long integers), but my guess is you 
do not want to do this either (it is a good compiler and runtime, so 
think about it when you need an upgrade: you can call them at +31-
20-6646416 or send a mail to info@ace.nl).

Simplest but not very efficient: use a bit of C to implement longer 
integers. I give you the general idea by showing the simplest 
calculation on long ints: the ++ operation. The rest takes a little 
more time, but is not difficult (except the long divide, which I hope 
you do not need).

unsigned int   mylong[2];
if(!mylong[0]++)mylong[1]++;   /* increment */

Last but not least: write some simple assembler code (preferably in-
line, since the basic operations are extremely simple). I will give 
the example for adding two INT64 numbers below, including the data 
structure you need to define in C:

typedef struct { int hi, int lo } mylong;
mylong  first, second, third;

/* code for long addition -> third = first + second */
__asm{ ldc 0; ldl first.lo; ldl second.lo; ladd; stl third.lo;
       ldl first.hi; ldl second.hi; ladd; stl third.hi; }

/* code for long subtraction -> third = first - second */
__asm{ ldc 0; ldl first.lo; ldl second.lo; lsub; stl third.lo;
       ldl first.hi; ldl second.hi; lsub; stl third.hi; }

The "ladd" instruction adds the top 2 registers of the transputer 
stack and leaves the result on top, the carry below that. The "ldc 0" 
places a zero as initial 'carry' on the stack, to be used in the 
first "ladd" instruction. The carry from the first "ladd" is taken 
into the calculation when doing the second "ladd" on the high words. 
The same is true for the "borrow" in long subtraction. 

When using one 64-bit and one 32-bit integer, the code becomes a 
little simpler, of course, since the second part of the calculation 
merely adds the carry to the high word of the 64-bit integer, or 
subtracts the borrow from that high word. So you only need one "ladd" 
or "lsub". I give the example for the addition only:

/* code for (64-bit) third = (64-bit) first + (32-bit) second */
__asm{ ldc 0; ldl first.lo; ldl second; ladd; stl third.lo;
       ldl first.hi; add; stl third.hi; }

If you need a long multiply (fairly simple) and a long divide (quite 
complicated, and very inefficiently coded in Occam libraries), send 
me a mail and I will try to dig up the code from the long arithmetic 
I did for the mentioned parallel C compiler. I hope this mail has 
helped you in your project.

Good luck !

Jang, IF (UnLtd)



