[comp.lang.ada] Some VAX RTL 64 bit operations take only 32 bit operands.

stluka@software.ORG (Fred Stluka) (03/03/88)

Just a warning to Arny Engleson who (I think) is looking for operators
to act on 64 bit operands giving 64 bit results on the VAX...

     Some of the VAX RTL 64 bit operations recommended to you in earlier
     messages only take 32 bit operands, or return 32 bit results.

The VAX instruction set includes the primitives you need to do arbitrary
extended precision arithmetic.  In addition to ADD, SUB, MUL, and DIV,
there are ADWC (Add with carry) and SBWC (Subtract with carry) which can 
be chained together to do arbitrary length additions or subtractions 
32 bits at a time.  There are also EMUL and EDIV which, respectively, 
multiply 32 bits by 32 bits to produce a 64 bit result, and divide 64
bits by 32 bits to produce a 32 bit quotient and a 32 bit remainder.

Furthermore, as pointed out by Dave Seward, there are RTL routines to provide
convenient access to these without having to write any MACRO (VAX assembler)
code.  The VAX RTL routines LIB$ADDX and LIB$SUBX claim to do arbitrary length 
addition and subtraction (presumably using ADWC and SBWC).

However, the LIB$EMUL and LIB$EDIV routines do no more than the EDIV and 
EMUL instructions.  That is they do *not* operate on 64 bit operands 
returning 64 bit results.  To produce true 64 bit operators, you have 
to use break up the operation into smaller parts (as mentioned by Sam 
Harbaugh).  This is not as trivial as it seems but it can be done.

The biggest problem you encounter is in avoiding spurious integer overflows
caused by intermediate results exceeding 32 bits.  Many of the intermediate
results you generate will be 32 bit quantities which you would like to 
think of as unsigned because they are to become the low order part of a
signed 64 bit number.  However, there is no way to tell the VAX that 
a 32 bit quantity is unsigned.  It will insist on treating any change 
in the sign bit as an overflow.  Explicitly disabling the integer overflow
trap helps some, but must be done selectively (during certain steps of
the operation only) if you want to retain the ability to have a true
overflow trigger a VAX condition which can be mapped to an Ada exception to
be handled in your calling routine.

My suggestion is to do the multiply and divide routines directly in MACRO 
because you are going to have to do a reasonable amount of bit twiddling
and setting and clearing of interrupt flags.  However, the MACRO routine
can still be called from Ada as overloaded infix operators if you use the
pragma INTERFACE.

By the way, the reason that I know so many of the details of this is that I
wrote a specialized 64 bit UNSIGNED package a while back in VAX MACRO to be
called from Ada.  It took a while, but in the end it worked fine.  You are
welcome to the code, but it has some special restrictions, like the 
multipliers and divisors are only 31 bits while the multiplicands and 
dividends, as well as the products and quotients are 64 bits.

If your application wants signed 64 bit numbers (mine required them to 
unsigned) there are examples in the "VAX Architecture Handbook" (1981
edition) on pages 201 and 206 which claim to be exactly the code you 
need (written in MACRO) to do 64 bit multiplication and division.

--Fred Stluka
stluka@softare.org
    

djs@actnyc.UUCP (Dave Seward) (03/08/88)

In article <8803030021.AA12106@venera.isi.edu> stluka@software.ORG (Fred Stluka) writes:
>However, the LIB$EMUL and LIB$EDIV routines ... operate on 64 bit operands 
>returning 64 bit results.  To produce true 64 bit operators, you have 
>to use break up the operation into smaller parts ...
>The biggest problem you encounter is in avoiding spurious integer overflows
>caused by intermediate results exceeding 32 bits.  Many of the intermediate
>results you generate will be 32 bit quantities ...

I agree that the multiply and divide have to be broken up into constituent
operations, but I would expect to use 64 bit intermediate results that EMUL
and EDIV provide. Am I missing something?

    Dave Seward
    uucp!actnyc!djs