mike@quench.lbl.gov (Michael Helm) (10/29/88)
I'm trying to revive a dinosaur code that used to run on our CDC 6600/7600 years ago. In so doing, I've come across some odd code fragments that compilers on our newer machines don't like much. Most of these I can fix, but now I've come across one I'm not sure of, & my CDC-ish FORTRAN manuals are long gone. In particular, suppose one has this code: . . . LOGICAL IRON . . . IF(IRON)4,9 4 A=B . . 9 A=C . . . END What logical state will IRON be in for #4 to be executed, & for #9 to be executed? How were(are) logical values represented on old(current) CDC hardware or in CDC FORTRAN programs? Thanks for your help, Michael Helm (Internet M_Helm@lbl.gov)
ags@s.cc.purdue.edu (Dave Seaman) (10/31/88)
In article <1196@helios.ee.lbl.gov> mike@quench.lbl.gov (Michael Helm) writes: [Re: Ancient CDC Fortran and the two-branch logical IF] [This is my corrected posting. I have cancelled an incorrect earlier posting. If you see another posting from me on this subject, ignore it.] > LOGICAL IRON > . > . > . > IF(IRON)4,9 > >What logical state will IRON be in for #4 to be executed, & for #9 >to be executed? The Fortran 77 equivalent of this CDC-ism is: IF (IRON) THEN GO TO 4 ELSE GO TO 9 ENDIF CDC compilers also recognized a two-branch arithmetic IF of the form, IF (aexp) 10,20 where "aexp" is an arithmetic expression. The Fortran 77 equivalent is: IF (aexp .NE. 0) THEN GO TO 10 ELSE GO TO 20 ENDIF >How were(are) logical values represented on old(current) >CDC hardware or in CDC FORTRAN programs? The representation of logical values is a software concept, not a hardware concept. I can't imagine why you would need to know the representation chosen by a particular Fortran compiler, but if I remember correctly, the usual convention was to represent .TRUE. as -1 and .FALSE. as zero. Some of the very old CDC compilers used a different convention. -- Dave Seaman ags@j.cc.purdue.edu
daniel@uxe.cso.uiuc.edu (11/01/88)
Re: IF(IRON)4,9 This is not a logical IF statement. It is a variant on the arithmetic IF. It's meaning is as follows: Jump to the first label if the value of the expression is non-zero and to the second label if it is zero. (Actually, it can be used as a two branch logical IF also: Branch to the first label if the logical expression is true; branch to the second label if it is false.) These commands exist only in the CDC Fortran Version 4 compiler which compiled the FORTRAN 66 language. -- Daniel Pommert Computing Services Office University of Illinois 1304 W. Springfield, Rm. 150 Urbana, IL 61801-2987 (217)333-8629 daniel@uxh.cso.uiuc.edu (Internet) DANIEL@UIUCVMD (Bitnet)
cccm001@ut-emx.UUCP (Tom Linsley) (11/01/88)
Some further trivia relating to the CDC two-branch IF and 6600 logic: The values .TRUE. and .FALSE., when assigned to a variable, are represented as a (60-bit) word with all bits set (-0) and all bits clear (+0), respectively. Later CDC compilers (FTN, MNF) checked the sign bit (2**59), and .TRUE. was high, .FALSE. low. The venerable RUN compiler used a different convention, whereby a word with no bits set (+0) was .FALSE., and _any_other_value_ was .TRUE. This convention made possible some peculiarly illogical logical behaviors, in that both "X" and ".NOT. X" could be true simultaneously, if "X" had been given some nonzero (or "non-logical") value (i.e., neither +0 nor -0). Remember that this compiler dates from a time when "strong typing" meant pounding hard on the keypunch. As an aside, negative zero was assigned to a variable read from a blank field (rather than a field containing a zero), and the test for the blank (often used for missing data) was IF ( .NOT. X ) T,F where the "false" branch indicated a negative zero (arithmetic blank) value. IF ( X .AND. (X .EQ. 0) ) <blank field processing statement> was also sometimes used for this check. -- Tom Linsley University of Texas Computation Center cccm001@emx.cc.utexas.edu
dik@cwi.nl (Dik T. Winter) (11/01/88)
In article <3616@s.cc.purdue.edu> ags@s.cc.purdue.edu.UUCP (Dave Seaman) writes: > In article <1196@helios.ee.lbl.gov> mike@quench.lbl.gov (Michael Helm) writes: > [Re: Ancient CDC Fortran and the two-branch logical IF] > > but if I remember correctly, the > usual convention was to represent .TRUE. as -1 and .FALSE. as zero. Some > of the very old CDC compilers used a different convention. > -- Beware, .FALSE. is +0; truth values returned by expressions could have any arithmetic value with negative for .TRUE. and positive for .FALSE.. So -0 is .TRUE. (yes, it is a 1-s complement machine). -- dik t. winter, cwi, amsterdam, nederland INTERNET : dik@cwi.nl BITNET/EARN: dik@mcvax
ags@s.cc.purdue.edu (Dave Seaman) (11/01/88)
In article <7523@ut-emx.UUCP> cccm001@ut-emx.UUCP (Tom Linsley) writes: > >Some further trivia relating to the CDC two-branch IF and 6600 logic: > >The values .TRUE. and .FALSE., when assigned to a variable, are represented >as a (60-bit) word with all bits set (-0) and all bits clear (+0), respectively. > >Later CDC compilers (FTN, MNF) checked the sign bit (2**59), and .TRUE. was >high, .FALSE. low. I agree that there was more than one convention, but I believe most of the later compilers used -1 (59 one bits out of 60 on a ones-complement machine) for .TRUE. and zero for .FALSE. I used to know exactly what each of our dozen-or-so Fortran compilers did on the old CDC machines, but I have forgotten most of the details. >The venerable RUN compiler used a different convention, whereby a word with no >bits set (+0) was .FALSE., and _any_other_value_ was .TRUE. This convention >made possible some peculiarly illogical logical behaviors, in that both "X" and >".NOT. X" could be true simultaneously, if "X" had been given some nonzero (or >"non-logical") value (i.e., neither +0 nor -0). Remember that this compiler >dates from a time when "strong typing" meant pounding hard on the keypunch. I remember that there was some strangeness about logicals with the RUN compiler, and this may have been it, but I think the later compilers used a slightly different test: zero for .FALSE. and nonzero for .TRUE. The ones-complement value -0 (all bits set) is considered "zero" as far as this hardware test is concerned, so that the problem you described does not arise. This is also why .TRUE. was represented as not-quite-all-ones. -- Dave Seaman ags@j.cc.purdue.edu
ags@s.cc.purdue.edu (Dave Seaman) (11/02/88)
In article <7691@boring.cwi.nl> dik@cwi.nl (Dik T. Winter) writes: >Beware, .FALSE. is +0; truth values returned by expressions could have any >arithmetic value with negative for .TRUE. and positive for .FALSE.. >So -0 is .TRUE. (yes, it is a 1-s complement machine). I still have access to a CDC 6500. Just a few minutes ago I ran the following program: print 10, .true., .false. 10 format(2(1x,o20)) end for which the output was: 77777777777777777776 00000000000000000000 which shows that .true. is -1 and .false. is 0, just as I said. The older compilers (such as RUN) used a different convention, something like -0 for .true. and +0 for .false. -- Dave Seaman ags@j.cc.purdue.edu
cccm001@ut-emx.UUCP (Tom Linsley) (11/02/88)
By golly, Dave's right, the "logical truth" is even curiouser than I had thought. I ran a little "assign and print" program this afternoon using five of the Fortran compilers on our Dual Cyber 170/750; herewith the results: RUN TRUE 77777777777777777777 (-0) FALSE 00000000000000000000 (+0) MNF 4.6 TRUE 77777777777777777776 (-1) FALSE 00000000000000000001 (+1) MNF 5.4 TRUE 77777777777777777776 (-1) FALSE 00000000000000000000 (+0) FTN 4.8 TRUE 77777777777777777776 (-1) FALSE 00000000000000000000 (+0) FTN 5.1 TRUE 77777777777777777776 (-1) FALSE 00000000000000000000 (+0) I sure hope none of Mike Helms' old CDC code relies on anything but just plain "true" or "false". - TL -- Tom Linsley University of Texas Computation Center cccm001@emx.cc.utexas.edu
dik@cwi.nl (Dik T. Winter) (11/02/88)
In article <3622@s.cc.purdue.edu> ags@s.cc.purdue.edu.UUCP (Dave Seaman) writes: > I agree that there was more than one convention, but I believe most of the > later compilers used -1 (59 one bits out of 60 on a ones-complement > machine) for .TRUE. and zero for .FALSE. Still true for FTN4 and FTN5. > In article <7523@ut-emx.UUCP> cccm001@ut-emx.UUCP (Tom Linsley) writes: >The venerable RUN compiler used a different convention, whereby a word with no >bits set (+0) was .FALSE., and _any_other_value_ was .TRUE. This convention >made possible some peculiarly illogical logical behaviors, in that both "X" and >".NOT. X" could be true simultaneously, if "X" had been given some nonzero (or >"non-logical") value (i.e., neither +0 nor -0). Remember that this compiler >dates from a time when "strong typing" meant pounding hard on the keypunch. > I doubt this. On the Cybers it is very difficult to distinguish +0 from the rest. The hardware compare for zero gets both +0 and -0. (Testing L you have to write: OR(NOT(L)+0,L).GE.0 to distinguish +0). So I do not think any compiler has used this scheme. (Was RUN FORTRAN 2 or FORTRAN 3? I do not remember anymore.) The illogical thing is of course that you could have tests like (I.LT.0.AND.I.EQ.0) return .TRUE. or (P.GE.Q.OR.Q.GE.P) return .FALSE.. In article <3622@s.cc.purdue.edu> ags@s.cc.purdue.edu.UUCP (Dave Seaman) writes: > I remember that there was some strangeness about logicals with the RUN > compiler, and this may have been it, but I think the later compilers used a > slightly different test: zero for .FALSE. and nonzero for .TRUE. The > ones-complement value -0 (all bits set) is considered "zero" as far as this > hardware test is concerned, so that the problem you described does not > arise. No, both FTN4 and FTN5 use negative for TRUE and positive for FALSE. The following function: LOGICAL COMPARE(X, Y) COMPARE = X .LT. Y RETURN END would compile to the equivalent of: return(x-y) without postnormalisation step. If X and Y are not both -0 the subtraction does not return -0. Of course the equivalent for integers fails due to possible overflow, but well, so it is with any comparison on integers. The best I have found for a fail proof integer compare (<) was: OR(AND(XOR(I,J),J),AND(EQV(I,J),I-J)). There is a very slick method to translate L = A.NE.B: L = OR(A-B,B-A). To summarise, I like ones complement machines, and I liked the Cybers. -- dik t. winter, cwi, amsterdam, nederland INTERNET : dik@cwi.nl BITNET/EARN: dik@mcvax
dik@cwi.nl (Dik T. Winter) (11/02/88)
In article <3624@s.cc.purdue.edu> ags@s.cc.purdue.edu.UUCP (Dave Seaman) writes: > In article <7691@boring.cwi.nl> dik@cwi.nl (Dik T. Winter) writes: > >Beware, .FALSE. is +0; truth values returned by expressions could have any > >arithmetic value with negative for .TRUE. and positive for .FALSE.. > >So -0 is .TRUE. (yes, it is a 1-s complement machine). > > print 10, .true., .false. > 10 format(2(1x,o20)) > end > > for which the output was: > > 77777777777777777776 00000000000000000000 You missed something: I wrote: the constant .TRUE. is -1 indeed, but a logical expression could very well return -0 for .TRUE.. Try: logical function equal(i,j) equal = i.eq.j return end print 10, equal(1,1) 10 format(1x,o20) end the output is: 77777777777777777777 (yes, -0). (It might depend on the level of optimisation.) -- dik t. winter, cwi, amsterdam, nederland INTERNET : dik@cwi.nl BITNET/EARN: dik@mcvax
ags@s.cc.purdue.edu (Dave Seaman) (11/03/88)
>In article <7523@ut-emx.UUCP> cccm001@ut-emx.UUCP (Tom Linsley) writes: >>The venerable RUN compiler used a different convention, whereby a word with no >>bits set (+0) was .FALSE., and _any_other_value_ was .TRUE. In article <7693@boring.cwi.nl> dik@cwi.nl (Dik T. Winter) writes: >I doubt this. On the Cybers it is very difficult to distinguish +0 from the >rest. The hardware compare for zero gets both +0 and -0. The RUN compiler did indeed use this scheme. It is true that the hardware compare for zero gets both +0 and -0, but all this proves is that the RUN compiler did not use the hardware compare for zero when testing logicals. >(Testing L you have >to write: OR(NOT(L)+0,L).GE.0 to distinguish +0). >So I do not think any compiler has used this scheme. No, you just write .NOT. L, assuming L is typed LOGICAL. The compiler does the rest. >The illogical thing is of course >that you could have tests like (I.LT.0.AND.I.EQ.0) return .TRUE. or >(P.GE.Q.OR.Q.GE.P) return .FALSE.. I don't see how. I tried evaluating your first expression with I equal to minus zero, and it still gave me .FALSE. I tried the second expression with P and Q both equal to minus zero, and it gave me .TRUE. Did you have some other values in mind? It seems to me you are making unwarranted assumptions about how compilers generate code. [Concerning my claim that the later compilers use nonzero for TRUE and zero for FALSE]: >No, both FTN4 and FTN5 use negative for TRUE and positive for FALSE. You're right. I got the compilers confused on this point. It was the RUN compiler that behaved as I described. -- Dave Seaman ags@j.cc.purdue.edu
forags@violet.berkeley.edu (11/03/88)
In article <3627@s.cc.purdue.edu> ags@s.cc.purdue.edu.UUCP (Dave Seaman) writes: > >The RUN compiler did indeed use this scheme. It is true that the hardware >compare for zero gets both +0 and -0, but all this proves is that the RUN >compiler did not use the hardware compare for zero when testing logicals. > Right! The RUN compiler used a CXi Xk instruction (count all one-bits in Xi and store the result in Xk, so anything but 60 zero bits was true). (On a 6000-series machine this took an obscene number of minor cycles (68 on a 6400), which made logical variables rather slow to evaluate...) Al Stangenberger Dept. of Forestry & Resource Mgt. forags@violet.berkeley.edu 145 Mulford Hall - Univ. of Calif. uucp: ucbvax!ucbviolet!forags Berkeley, CA 94720 BITNET: FORAGS AT UCBVIOLE (415) 642-4424
rchrd@well.UUCP (Richard Friedman) (11/04/88)
I believe the old RUN compiler would generate code to test the number of 1 bits in a register. If this was 60, the result was true. (The 6600 hardware had a CXi Xj instruction to count the number of 1 bits in Xj and leave that number in Xi). -- ...Richard Friedman [rchrd] uucp: {ucbvax,lll-lcc,ptsfa,hplabs}!well!rchrd - or - rchrd@well.uucp
kurtk@tekcae.CAX.TEK.COM (Kurt Krueger) (11/04/88)
Something that may be confusing the issue is that CDC in the FTN and FTN5 compilers always inserted code to make sure that -0 would 'disappear'. In logical statements, this would at times amount to adding a +0 to the logical expression so SOME mathematics would always get done BEFORE a sign test was done. The hardware is such that -0 can NEVER get calculated but is a perfectly legitimate operand. -- I too like the Cybers. Even the new NOS/VE ones - a REAL computer.
khb%chiba@Sun.COM (Keith Bierman - Sun Tactical Engineering) (11/05/88)
In article <2183@tekcae.CAX.TEK.COM> kurtk@tekcae.CAX.TEK.COM (Kurt Krueger) writes: >Something that may be confusing the issue is that CDC in the FTN and FTN5 >compilers always inserted code to make sure that -0 would 'disappear'. >In logical statements, this would at times amount to adding a +0 to the >logical expression so SOME mathematics would always get done BEFORE a sign >test was done. The hardware is such that -0 can NEVER get calculated >but is a perfectly legitimate operand. -0 DID get computed. This proved to be a problem during my student days on a Cyber 17x with using the ETH Pascal compiler in conjuction with one of the fortran compilers (I forget which) Pascal couldn't cope with -0's which were being generated by the fortran compiler. Keith H. Bierman It's Not My Fault ---- I Voted for Bill & Opus
dik@cwi.nl (Dik T. Winter) (11/06/88)
In article <16427@agate.BERKELEY.EDU> forags@violet.berkeley.edu writes: > Right! The RUN compiler used a CXi Xk instruction (count all one-bits in Xi > and store the result in Xk, so anything but 60 zero bits was true). (On a > 6000-series machine this took an obscene number of minor cycles (68 on a > 6400), which made logical variables rather slow to evaluate...) > This explains it. I would never have thought that a compiler writer would use that instruction for logicals. Interestingly, on many Cybers the sequence I gave (OR(NOT(L)+0,L).GE.0) is faster than CXi Xk followed by a PL, and does the same! And if you follow comp.arch you know why this instruction was there. -- dik t. winter, cwi, amsterdam, nederland INTERNET : dik@cwi.nl BITNET/EARN: dik@mcvax
rchrd@well.UUCP (Richard Friedman) (11/08/88)
The comment was made that CDC hardware prevented -0 from being generated. This was/is true, but there were times the FTN4 and FTN5 math library routines would (for specific arguments) return -0. This was a hard error to find, but eventually it got corrected. -- ...Richard Friedman [rchrd] uucp: {ucbvax,lll-lcc,ptsfa,hplabs}!well!rchrd - or - rchrd@well.uucp
dik@cwi.nl (Dik T. Winter) (11/09/88)
In article <7588@well.UUCP> rchrd@well.UUCP (Richard Friedman) writes: > The comment was made that CDC hardware prevented -0 from being > generated. This was/is true, but there were times the FTN4 and > FTN5 math library routines would (for specific arguments) return -0. > This was a hard error to find, but eventually it got corrected. > Not exactly true; floating-point and integer arithmetic do not generate -0, if the input operands do not contain -0. But otherwise they can be generated. E.g. truncating a negative floating point value to integer (if between -1.0 and 0.0). Also overflowing integer multiply (which is really a special case of floating-point multiply) can return -0. Most compilers compensate for this by adding +0 to the result, which turns -0 to +0. -- dik t. winter, cwi, amsterdam, nederland INTERNET : dik@cwi.nl BITNET/EARN: dik@mcvax
rchrd@well.UUCP (Richard Friedman) (11/11/88)
In article <7709@boring.cwi.nl> dik@cwi.nl (Dik T. Winter) writes: > floating-point and integer arithmetic do not generate -0, >if the input operands do not contain -0. But otherwise they can be generated. >E.g. truncating a negative floating point value to integer (if between -1.0 >and 0.0). Also overflowing integer multiply (which is really a special case >of floating-point multiply) can return -0. Most compilers compensate >for this by adding +0 to the result, which turns -0 to +0. >-- >dik t. winter, cwi, amsterdam, nederland Yes, but the math library was written in COMPASS and early versions were not very careful about propagating -0 thru sign extension under special cases, usually resulting from scaling exponents. In general the code compiled by FTN did a good job avoiding -0 but the library could not be trusted. -- ...Richard Friedman [rchrd] Berkeley, CA. rchrd@well.uucp -or- {ucbvax,lll-lcc,pacbell,hplabs}!well!rchrd