From: S_JUFFA@iravcl.ira.uka.de (|S| Norbert Juffa)
Newsgroups: comp.arch
Subject: Re: how to advocate new software/hardware features (Re: Hard
Date: 16 Nov 1992 13:48:47 GMT
Organization: University of Karlsruhe (FRG) - Informatik Rechnerabt.
Distribution: world
NNTP-Posting-Host: irav1.ira.uka.de
X-News-Reader: VMS NEWS 1.23

In <1992Nov15.193356.1549@sal.wisc.edu> alan@sal.wisc.edu writes:

> In article <7899@charon.cwi.nl> dik@cwi.nl (Dik T. Winter) writes:
> >But wait.  SPARC version 7 does not have an integer multiply instruction,
> >it uses multiply step.  When you code the multiply in assembly you will
> >find that you get a 64 bit result, but in C it is not possible to
> >retrieve that result.  Doing it with inline assembly is not what you
> >want in general (>32 instructions inline assembly), so you do it
> >out-of-line.  Hence it is not sufficient to have good inliners, on
> >some platforms you need out of line assembly routines to do what you
> >want, and no, the compilers do not help.  (The same holds for HP-PA 1,
> >IBM PC-RT, AMD 29k and a few more.)  So the operation is available but
> >you do not get it.
> >
> >So let's see.  You promote the GCC interface with asm.  How do you
> >code the 32x32->64 multiply on the SPARC in GCC?
> 
> Include the following in every source file:
> 
> 	static inline long long mul32to64 (long i, long j)
> 	{
> 		whatever asm magic one requires
> 	}
> 
> This terribly inelegant; if you want elegance BUY a compiler for the
> machine which has 64 bit longs and use:
> 
> 	long i64;
> 	int i32, j32;
> 	i64 = (long) i32 * (long) j32;
> 
> If the compiler insists on promoting i32 and j32 to 64 bits before the
> multiplication, ask for your money back.
> 
> Solutions exists for many of the specific problems which have been
> discussed in this thread: most of the free ones are inelegant and most
> of the elegant ones are expensive.

I would think that most compilers with optimizers can generate a n-bit * n-bit
-> 2n-bit multiply instruction if it is available in HW. A while back, I tried
this with an 8086 (which has 16x16->32 multiply) and the lowly MS-FORTRAN 5.0 
optimizing compiler. What I wanted to do is multiply to INTEGER*4 numbers, the
result being an INTEGER*4 (32-bit integer), and I knew that the inputs fit into
16 bits each, so I didn't want the compiler to call the 32x32->32 bit mul
routine. So I tried:

INTEGER*4 I,J,K
INTEGER*2 TEMP1, TEMP2

TEMP1=I
TEMP2=J
K=TEMP1*TEMP2

I ran it thru the compiler with max. optimization and took a look at the 
assembly output. I was amazed that the compiler had produced exactly the result
I wanted:

MOV   AX, WORD PTR [I]      ; load least significant 16 bits of I
MOV   DX, WORD PTR [J]      ; load least significant 16 bits of J
MUL   DX                    ; multiply I*J (result in regs DX,AX)
MOV   WORD PTR [K], AX      ; store 32-bit
MOV   WORD PTR [K+2], DX    ;  result

I haven't checked the 32/16->16 bit divide, but I wouldn't be surprised if it
works as well. I'll admit though that there are instructions that are difficult
to generate from a HLL: adding loooong integers with ADD/ADC, or shifting them
using the 80386 double shift instructions SHLD, SHRD (these allow you to shift
crossing register boundaries, actually the asm-notation for the functionality
of a funnel-shifter), etc. The problem here is that the code to do the equi-
valent operations in a HLL does not map to these instructions in very obvious
ways (think about generating a HW bitcount instruction from the HLL code for a
bitcount!). A human can see what is really intended, but today's compilers can't
(I would be pleased to be proved wrong on this one).

Norbert
-------------------------------------------------------------------------------
Norbert Juffa        email: S_JUFFA@IRAVCL.IRA.UKA.DE        Live and let live!
Newsgroups: comp.arch