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