Path: utzoo!attcan!uunet!seismo!sundc!pitstop!sun!amdcad!ames!mailrus!tut.cis.ohio-state.edu!cs.utexas.edu!sm.unisys.com!sdcsmb!check!pmontgom From: pmontgom@sm.unisys.com (Peter Montgomery) Newsgroups: comp.lang.misc Subject: Re: Many people's opinions on computer languages Message-ID: Date: 13 Sep 88 04:17:14 GMT References: <3938@enea.se> <923@l.cc.purdue.edu> <382@quintus.UUCP> Reply-To: pmontgom@sm.unisys.com (Peter Montgomery) Organization: Unisys Santa Monica Lines: 59 In article <382@quintus.UUCP> ok@quintus.UUCP (Richard A. O'Keefe) writes: >In article <923@l.cc.purdue.edu> cik@l.cc.purdue.edu (Herman Rubin) writes: >> >>Programming time is therefore not necessarily faster in HLLs. Frequently, >>I see how to use a machine instruction or instructions to accomplish something >>which I consider simple and obvious. Why should I even have to try to find a >>way to do in in some HLL? The HLL gurus have left out too much. > >Please tell us about some of these instructions. Herman Rubin previously mentioned my most important need: support of long long multiplication and division (multiply two 32-bit numbers to get a 64-bit product; divide a 64-bit number by a 32-bit number to get quotient and remainder). Another need is the truncated base 2 logarithm of an unsigned integer n. For example, LOG2(13) = 3. Conventionally LOG2(0) = -1. I want to be able to write code resembling (in practice, the "switch" would probably be several #ifdefs). inline int LOG2(unsigned long n) /* Return truncated base 2 log of n */ { switch(target machine) { default: Use a loop which searches n one bit at a time CDC CYBER: if ((signed long)n < 0) return 59; else if ((n >> 48) == 0) return 47 - (B register output when normalizing n); else return 95 - (B register output when normalizing n >> 48); CRAY: return 63 - (leading zero count of n) SUN 3: return 31 - (output of BFFFO (find first) applied to n); VAX: { const double d = (double)((signed long)n); (CVTLD) if (d == 0.0) return -1; if (d < 0.0) return 31; extract lower 5 bits of exponent of d, return 1 less; } } } Although all these architectures allow the function to be computed directly (without a loop), the CRAY CFT compiler is the only C or FORTRAN compiler I know which lets the programmer express this algorithm and get inline code. [The SUN 3 "inline" utility may work, but its manual page states "Only opdefs and addressing modes generated by Sun compilers are guaranteed to work"; I want to access an instruction NOT generated by these compilers.] I use LOG2 when initializing the left-to-right binary method of exponentiation and when normalizing a divisor for multiple precision division. The exponent of the highest power of 2 dividing a positive number p (needed by the binary method for greatest common divisors) is LOG2(p & ~(p-1)). In practice I write assembly code for each target machine, but these procedure calls inhibit normal optimization (the compiler doesn't know what other variables my procedure may reference or modify) and prevent peephole optimizations which a good compiler would make, such as replacing 30 - LOG2(n) by (output of BFFFO) - 1 on a SUN 3.