reeder@ut-emx.UUCP (William P. Reeder) (07/15/89)
Boy, this one makes my head hurt. I have tried reading the "Series 32000 Programmer's Reference Manual" from Prentice-Hall to find the answer to this question: When I reference a word in a register, is it the least significant word, or the most significant word? Here is why I ask: I have a FORTRAN program in which 1000 is greater than 3. I look at the assembly instructions generated by the Encore f77 compiler and don't understand why things are busted. Here is the subroutine which produces the problem. SUBROUTINE SUB ( PTR ) INTEGER*2 PTR, LKEY, THOU LKEY = 2 PTR = 1 PTR = PTR + 1 IF ( 1000 .LT. PTR+LKEY-1 ) THEN PRINT *, '1000 is less than 3' ELSE PRINT *, '1000 is greater than 3' ENDIF RETURN END Here is the relevant assembler code (produced with f77 -S): _sub_: enter [],$24 movd 8(fp),r1 # R1 contains address of ptr movqw $2,r2 # R2 contains word value 2 (lkey) movqw $1,0(r1) # store 1 in word addressed in R1 (ptr=1) movxwd 0(r1),r0 # bring ptr into R0 as double addqd $1,r0 # add (as doubles) 1 to contents of R0 (ptr+=1) movw r0,0(r1) # store low word back in memory movxwd 0(r1),r0 # bring it back addd r2,r0 # add R2 to R0 as doubles (ptr+lkey) addqd $-1,r0 # subtract 1 from R0 as doubles (ptr+lkey-1) cmpd r0,$1000 # compare double in R0 with 1000 (clear N?) ble .L15 # branch if N flag clear I added the comments and deleted the code which followed the conditional branch. Now, when we get to the cmpd instruction, R0 *should* contain the value 3. The binary in R0, most significant bit on the left, should be 000000000000000000000000000000011 while 1000 as a double (the manual says it is sign extended to the size of the compare) is 000000000000000000000001111101000 Clearly, 1000 is greater than 3, so "cmpd ro,$1000" should clear the N flag in PSR, and the ble instruction should cause a jump to .L15 -- but it doesn't. The really sick part is that if I edit the .s file produced by f77 -S and change the cmpd to cmpw, but change NOTHING else, then run as and ld, the "proper" behavior is observed. Can anyone explain what is going on with the this assembler? And can anyone from Encore tell me why f77 is generating this apparently incorrect code? I will be submitting a bug report to Encore about this soon. For those who care, I have an Encore Multimax 320 with APC's, running Umax 4.2 Release 3.2.1, and with f77 release 2.0.r051. -- William "Wills" Reeder, The University of Texas at Austin, Computation Center reeder@emx.utexas.edu, uunet!cs.utexas.edu!ut-emx!reeder, (512)471-3241 DISCLAIMER: Opinions expressed above are those of the author and do not necessarily reflect the opinions of The University of Texas at Austin, or those of the manufacturer of the wires which carried this message.
simpson@xenna.UUCP (Rich Simpson,Look for the plant on the pole.,x2609,5082636474) (07/17/89)
From article <15266@ut-emx.UUCP>, by reeder@ut-emx.UUCP (William P. Reeder): -- -- Here is why I ask: I have a FORTRAN program in which 1000 is greater -- than 3. I look at the assembly instructions generated by the Encore -- f77 compiler and don't understand why things are busted. -- Here is the relevant assembler code (produced with f77 -S): -- movd 8(fp),r1 # R1 contains address of ptr -- movqw $2,r2 # R2 contains word value 2 (lkey) -- movqw $1,0(r1) # store 1 in word addressed in R1 (ptr=1) -- movxwd 0(r1),r0 # bring ptr into R0 as double -- addqd $1,r0 # add (as doubles) 1 to contents of R0 (ptr+=1) -- movw r0,0(r1) # store low word back in memory -- movxwd 0(r1),r0 # bring it back -- addd r2,r0 # add R2 to R0 as doubles (ptr+lkey) The problem is here. The value in r2 is a word and the value in r0 is a double. Either the compiler should have not done the movxwd into r0, done an addw and then widened the result, or it should have widened the value in r2 to double before the addd. The net effect is that the addd picks up noise from the top half of r2 which throws the cmpd off. -- addqd $-1,r0 # subtract 1 from R0 as doubles (ptr+lkey-1) -- cmpd r0,$1000 # compare double in R0 with 1000 (clear N?) -- ble .L15 # branch if N flag clear -- Can anyone explain what is going on with the this assembler? And -- can anyone from Encore tell me why f77 is generating this apparently -- incorrect code? I will be submitting a bug report to Encore about -- this soon. For those who care, I have an Encore Multimax 320 with -- APC's, running Umax 4.2 Release 3.2.1, and with f77 release 2.0.r051. -- -- -- William "Wills" Reeder, The University of Texas at Austin, Computation Center -- reeder@emx.utexas.edu, uunet!cs.utexas.edu!ut-emx!reeder, (512)471-3241 This problem is fixed in the 2.1 version of f77 which is currently in final release testing and should be available within a month. There were a variety of problems with handling INTEGER*2 expressions which have been fixed in this release. Rich Simpson Encore Computer