[comp.misc] 32bit = 16bit x 16bit

cik@l.cc.purdue.edu (Herman Rubin) (10/24/87)

In article <146MAXHAM@RICE>, MAXHAM@RICE.BITNET (Mark Maxham) writes:
> But the 68000 MULS and MULU commands multiply two sixteen bit words
> into a 32 bit longword.  Thus they are defined.  Is the question
> how C translates from multiplicitive expressions into actual machine
> instructions?
>      
> Mark Maxham      maxham@icsa.rice.edu
>      

A general problem with HLL's is that they do not have the necessary
flexibility to handle situations like this.  I do not know of any language
which has in its operation list an operation to multiply two 16 bit object
and get a 32 bit object. (Note:  I am using the term "object" because what is
called a word, longword, etc., differs from machine to machine.)  On many
machines, this would have to be done by the portable method of converting
the 16 bit objects to 32 bits, but the possessor of a machine which can do
the operation directly should not have to go to such lengths to achieve the
results.  How about the related problem of multiplying two 32 bit objects and
getting a 64 bit object?  Other than inserting assembler instructions, which
may involve such problems as not knowing where the (expletive deleted) compiler
has decided to locate the objects, I see no way to do this in any HLL.  I know
of no way to tell the compiler that here is an operation with a given syntax,
and the compiler should put it in its set of operations.  If the syntax is
different from other syntaxes for that operator, the compiler should perform
the overloading.  It is clear that the languages need more flexibility
and that the gurus who claim that they have the solutions are wrong.
-- 
Herman Rubin, Dept. of Statistics, Purdue Univ., West Lafayette IN47907
Phone: (317)494-6054
hrubin@l.cc.purdue.edu (ARPA or UUCP) or hrubin@purccvm.bitnet

firth@sei.cmu.edu (Robert Firth) (10/27/87)

In article <593@l.cc.purdue.edu> cik@l.cc.purdue.edu (Herman Rubin) writes:
[discussion of 16*16=>32]
>A general problem with HLL's is that they do not have the necessary
>flexibility to handle situations like this.  I do not know of any language
>which has in its operation list an operation to multiply two 16 bit object
>and get a 32 bit object.

The language RTL/2 has exactly this feature; it has versions of "*" that
can multiply integers to give long ints or fractions to give long fracs.

A more modern language that recognises this problem is Ada, which has
explicit features for fixed-point multiplication with double-length
result (hidden in RM 3.5.9,3.5.10), and indeed for "rule-of-three"
operations (multiply to double length; divide back to single length).
These are defined in fairly general terms, and so can be mapped onto
a variety of multiple-length machine types, not just 16 and 32.

The systems language BCPL has an extension that provides the rule-of-three
primitive (called MULDIV), but for integers only.

mac3n@babbage.UUCP (10/27/87)

In article <593@l.cc.purdue.edu>, cik@l.cc.purdue.edu (Herman Rubin) writes:
> A general problem with HLL's is that they do not have the necessary
> flexibility to handle situations like this.  I do not know of any language
> which has in its operation list an operation to multiply two 16 bit object
> and get a 32 bit object.

In, e.g., Ada the overloading operators allow one to extend "*" for use
with two "16 bit" objects when the context calls for a "32 bit" object.
Ada is fairly unusual in allowing overload resolution based on context,
a feature that adds considerable complexity to the compiler.

> I know
> of no way to tell the compiler that here is an operation with a given syntax,
> and the compiler should put it in its set of operations.

The usual way to extend the set of operations in a language is with procedures.
Many languages are compatible with machine-language procedures.
Some languages allow inline procedues.  Some even allow inline assembler.

If you really want that much control over the code generated, perhaps you
should write your own compiler.  There are several systems which construct
code generators from a set of instructions and their semantics.  Automatic
code generation generation is still pretty new.

> It is clear that the languages need more flexibility
> and that the gurus who claim that they have the solutions are wrong.

Few Gurus claim that they have the perfect solutions.  Merely adequate.

bpendlet@esunix.UUCP (10/28/87)

in article <593@l.cc.purdue.edu>, cik@l.cc.purdue.edu (Herman Rubin) says:
> Xref: esunix comp.lang.c:4825 comp.misc:1454
> 
> In article <146MAXHAM@RICE>, MAXHAM@RICE.BITNET (Mark Maxham) writes:
>> But the 68000 MULS and MULU commands multiply two sixteen bit words
>> into a 32 bit longword.  Thus they are defined.  Is the question
>> how C translates from multiplicitive expressions into actual machine
>> instructions?
>>      
>> Mark Maxham      maxham@icsa.rice.edu
>>      
> 
> A general problem with HLL's is that they do not have the necessary
> flexibility to handle situations like this.  I do not know of any language
> which has in its operation list an operation to multiply two 16 bit object
> and get a 32 bit object. 

Whether or not you consider forth to be a high level language is a matter of
taste. But, in the last version of the forth standard that I read ( quite old
actually ) there was an operator named */ that multiplies two 16 bit ints
giving a 32 bit int and then divides by a 16 bit int to give a 16 bit result.
not quite what you asked for, but very close.

> I know
> of no way to tell the compiler that here is an operation with a given syntax,
                                                                        ^^^^^^
I think the term you are looking for here is "signature", the name of the
operator, plus the number of arguments, the type of the arguments, the order
of the arguments and type of the result.

> and the compiler should put it in its set of operations.  If the syntax is
> different from other syntaxes for that operator, the compiler should perform
> the overloading.  It is clear that the languages need more flexibility
> and that the gurus who claim that they have the solutions are wrong.

Operator overloading has been implemented in many compilers. It is pretty
trivial to implement. I know, I've implemented it. If this is meant as a
criticism of C, well there is a lot to criticise about C. But, one of the 
hallmarks of C is its lack of features, especially syntactic features.
C is rather elegant in its syntactic simplicity.

If you are looking for a modern language with a lot of syntactic features
and a lot of flexibility, try reading a good book on ADA. If you want
flexibility with a minimum of syntose, look a LISP.

Programming language syntax is a cancer. The bigger it is, the harder it
is to live with.

			Bob P.
-- 
Bob Pendleton @ Evans & Sutherland
UUCP Address:  {decvax,ucbvax,ihnp4,allegra}!decwrl!esunix!bpendlet
Alternate:     {ihnp4,seismo}!utah-cs!utah-gr!uplherc!esunix!bpendlet
        I am solely responsible for what I say.

henry@utzoo.UUCP (Henry Spencer) (10/28/87)

> ... I do not know of any language
> which has in its operation list an operation to multiply two 16 bit object
> and get a 32 bit object...

As has been said before, in C on a machine where shorts are 16 bits and longs
32, "(long)shortvar * (long)shortvar" does *exactly* this, assuming that the
compiler is smart enough to notice that it can do the casts as part of the
multiplication.  With the bonus that it works, although more slowly, even
if the compiler doesn't notice.

> ... How about the related problem of multiplying two 32 bit objects and
> getting a 64 bit object? ...

Given suitable data types (some 32-bit-machine C compilers have a "long long"
type for 64-bit integers), the same comment applies.
-- 
PS/2: Yesterday's hardware today.    |  Henry Spencer @ U of Toronto Zoology
OS/2: Yesterday's software tomorrow. | {allegra,ihnp4,decvax,utai}!utzoo!henry

toma@tekgvs.TEK.COM (Tom Almy) (10/28/87)

(I don't have the original article)

In article <593@l.cc.purdue.edu> cik@l.cc.purdue.edu (Herman Rubin) writes:

>A general problem with HLL's is that they do not have the necessary
>flexibility to handle situations like this.  I do not know of any language
>which has in its operation list an operation to multiply two 16 bit object
>and get a 32 bit object.

Forth does.  It also provides a 32 bit by 16 bit divide operation, 
a multiply divide function (a*b/c) combining these two for scaled integer
arithmetic, and a divide function returning both quotient and remainder.

Tom Almy
Tektronix, Inc.
toma@tekgvs.TEK.COM

boykin@custom.UUCP (10/28/87)

> In article <146MAXHAM@RICE>, MAXHAM@RICE.BITNET (Mark Maxham) writes:
> > But the 68000 MULS and MULU commands multiply two sixteen bit words
> > into a 32 bit longword.  Thus they are defined.  Is the question
> > how C translates from multiplicitive expressions into actual machine
> > instructions?
> 
> A general problem with HLL's is that they do not have the necessary
> flexibility to handle situations like this.  I do not know of any language
> which has in its operation list an operation to multiply two 16 bit object
> and get a 32 bit object.

I don't believe this is a problem with the language, but with
the compiler.  The compiler should be able to optimize to use
the instructions available to it.  On most C compilers I've
seen the following will use instructions like the 68000's MULS
rather than a subroutine call:

	long	x;		/* 32-bit value	*/
	short	y, z;		/* 16-bit value	*/

	x = y * z;

While this is implementation dependent, it has worked on most
C compilers I've seen.  Don't blame the language when the
compiler (optimizer) is at fault.
-- 

Joe Boykin
...necntc!custom!boykin

ark@alice.UUCP (10/30/87)

In article <776@custom.UUCP>, boykin@custom.UUCP writes:
> I don't believe this is a problem with the language, but with
> the compiler.  The compiler should be able to optimize to use
> the instructions available to it.  On most C compilers I've
> seen the following will use instructions like the 68000's MULS
> rather than a subroutine call:
  
> 	long	x;		/* 32-bit value	*/
> 	short	y, z;		/* 16-bit value	*/
  
> 	x = y * z;
  
> While this is implementation dependent, it has worked on most
> C compilers I've seen.  Don't blame the language when the
> compiler (optimizer) is at fault.


On a machine with a 16-bit multiply that gives a 16-bit product,
the compiler is completely justified in using that multiply
and then sign-extending the result to 32 bits.  If you have any
thoughts about portability, you should be writing:

	x = (long)y * (long)z;

And yes, I have seen compilers that will translate that to
a single 16x16=32 multiply.

barmar@think.COM (Barry Margolin) (10/30/87)

In article <120@babbage.acc.virginia.edu> mac3n@babbage.acc.virginia.edu (Alex Colvin) writes:
>In article <593@l.cc.purdue.edu>, cik@l.cc.purdue.edu (Herman Rubin) writes:
>> A general problem with HLL's is that they do not have the necessary
>> flexibility to handle situations like this.  I do not know of any language
>> which has in its operation list an operation to multiply two 16 bit object
>> and get a 32 bit object.

PL/I's default is to do just this!  And if you multiply "fixed bin
(12,5)" (12 bits with 5 after the binary point) by "fixed bin (16,3)"
the default result is "fixed bin (28,8)".  Imagine -- a language that
follows the rules for arithmetic that we learned in grade school!  For
cases where you know that the result will not be the default (usually
when one of the operands is a literal, and the automatically-generated
data type isn't appropriate), there is a version of the multiplication
operator that lets you specify the size of the result:

	result = multiply (var, 3, 16, 3);

which means "multiply var by 3 giving a sixteen-bit result with three
bits after the binary point)."

---
Barry Margolin
Thinking Machines Corp.

barmar@think.com
seismo!think!barmar