jbwaters@bsu-cs.UUCP (J. Brian Waters) (12/08/88)
I have been looking at the assembly output of a C compiler and am puzzled to find that it sometimes uses, for example, the instruction addq.w #8,sp. I know that this clears the arguments pushed on the stack for a subroutine call. What I do not understand is why it is not a addq.l #8,sp as I thought the sp was a 32 bit counter. Why does it use the addq.w form rather then the addq.l? -- Brian Waters <backbone>!{iuvax|pur-ee}!bsu-cs!jbwaters uunet!---/
ben@grace.UUCP (Ben Henwood) (12/09/88)
From postnews Thu Dec 8 08:48:24 1988 In article <5005@bsu-cs.UUCP>, jbwaters@bsu-cs.UUCP (J. Brian Waters) writes: > > I have been looking at the assembly output of a C compiler and am puzzled to > find that it sometimes uses, for example, the instruction addq.w #8,sp. > I know that this clears the arguments pushed on the stack for a subroutine > call. What I do not understand is why it is not a addq.l #8,sp as I thought > the sp was a 32 bit counter. Why does it use the addq.w form rather then > the addq.l? When an "addq" instruction affects an address register (A7 in this case), the entire destination address register is used, regardless of the operation size. So even though the assembler instruction specifies 16-bits, which would be a bug, the instruction will use 32-bits since it's dealing with the SP.
rbrown@svax.cs.cornell.edu (Russell Brown) (12/09/88)
In article <5005@bsu-cs.UUCP> jbwaters@bsu-cs.UUCP (J. Brian Waters) writes: > >What I do not understand is why it is not a addq.l #8,sp as I thought >the sp was a 32 bit counter. Why does it use the addq.w form rather then >the addq.l? According to the entry on ADDQ in the M68000 Programmer's reference manual, "When adding to address registers, the entire destination address register is used, regardless of the operation size." As to why the C compiler you're using chooses the .w form, I can't say. It might be a feature, or it might be that doing it that way made doing something else easier. Russell G. Brown Cornell Computer Science
ditto@cbmvax.UUCP (Michael "Ford" Ditto) (12/09/88)
In article <5005@bsu-cs.UUCP> jbwaters@bsu-cs.UUCP (J. Brian Waters) writes: > What I do not understand is why it is not a addq.l #8,sp as I thought >the sp was a 32 bit counter. Why does it use the addq.w form rather then >the addq.l? Under "addq" in the 68020 manual: "When adding to address registers, the entire destination address register is used, regardless of the operation size." (It should be the same for any 68000-family CPU.) This is typical of address register operations on the 680x0 ... even a move.w to an address register is sign-extended to 32-bits and modifies the whole 32 bits of the destination. -- -=] Ford [=- "The number of Unix installations (In Real Life: Mike Ditto) has grown to 10, with more expected." ford@kenobi.cts.com - The Unix Programmer's Manual, ...!sdcsvax!crash!elgar!ford 2nd Edition, June, 1972. ditto@cbmvax.commodore.com
mikes@oakhill.UUCP (Mike Schultz) (12/09/88)
In article <5005@bsu-cs.UUCP> jbwaters@bsu-cs.UUCP (J. Brian Waters) writes: > >I have been looking at the assembly output of a C compiler ... >..... What I do not understand is why it is not a addq.l #8,sp as I thought >the sp was a 32 bit counter. Why does it use the addq.w form rather then >the addq.l? First, as others have pointed out, the immediate word value is sign extended when dealing with address registers, so it really is adding a 32 bit value to the 32 bit register. Second, the timing tables in appendix F show that the word version of the addq takes 4 clocks, while the long version takes 8. I don't know, but I suspect that the hardware adder is optimized for word adds. Mike Schultz ..!uunet!cs.utexas.edu!oakhill!mikes
cruff@ncar.ucar.edu (Craig Ruff) (12/09/88)
In article <5460@cbmvax.UUCP> ditto@cbmvax.UUCP (Michael "Ford" Ditto) writes: >In article <5005@bsu-cs.UUCP> jbwaters@bsu-cs.UUCP (J. Brian Waters) writes: >> What I do not understand is why it is not a addq.l #8,sp as I thought >>the sp was a 32 bit counter. Why does it use the addq.w form rather then >>the addq.l? > >Under "addq" in the 68020 manual: "When adding to address registers, >the entire destination address register is used, regardless of the >operation size." (It should be the same for any 68000-family CPU.) The other reason that everyone seemed to miss is that this method saves 2 bytes. If you think about it, this instruction is used commonly to pop arguments off the stack after a function call (for C). If you have many function calls, the savings can add up. Another method some compilers use is to just let the arguments build up on the stack for a while and pop a whole bunch off in one shot, saving even more instructions. -- Craig Ruff NCAR INTERNET: cruff@ncar.UCAR.EDU (303) 497-1211 P.O. Box 3000 CSNET: cruff@ncar.CSNET Boulder, CO 80307 UUCP: cruff@ncar.UUCP
rbrown@svax.cs.cornell.edu (Russell Brown) (12/10/88)
In article <1100@ncar.ucar.edu> cruff@handies.UCAR.EDU (Craig Ruff) writes: >> >>Under "addq" in the 68020 manual: "When adding to address registers, >>the entire destination address register is used, regardless of the >>operation size." (It should be the same for any 68000-family CPU.) > >The other reason that everyone seemed to miss is that this method saves >2 bytes. If you think about it, this instruction is used commonly to >pop arguments off the stack after a function call (for C). If you have >many function calls, the savings can add up. > Untrue. The addq instruction has its data in the instruction word. It can only be used to add values 1 thru 8, so it only needs 3 bits. That's why people use it. Russell G. Brown Cornell Computer Science
cruff@ncar.ucar.edu (Craig Ruff) (12/10/88)
In article <23329@cornell.UUCP> rbrown@svax.cs.cornell.edu (Russell Brown) writes: >>The other reason that everyone seemed to miss is that this method saves >>2 bytes. ... > Untrue. The addq instruction has its data in the instruction word. >It can only be used to add values 1 thru 8, so it only needs 3 bits. That's >why people use it. No, it is true. Compare: addq.w #8, a7 (2 bytes) add.w #8, a7 (4 bytes) add.l #8, a7 (6 bytes) That's also why you'll see values > 8 using add.w instead of add.l. -- Craig Ruff NCAR INTERNET: cruff@ncar.UCAR.EDU (303) 497-1211 P.O. Box 3000 CSNET: cruff@ncar.CSNET Boulder, CO 80307 UUCP: cruff@ncar.UUCP
guy@auspex.UUCP (Guy Harris) (12/10/88)
>The other reason that everyone seemed to miss is that this method saves >2 bytes. People miss it because it's not true. addq.w #8,sp and addq.l #8,sp both take two bytes. However, on the 68010, according to my '010 reference manual, the "addq.w" takes 4 clocks, and the "addq.l" takes 8.
guy@auspex.UUCP (Guy Harris) (12/11/88)
>> Untrue. The addq instruction has its data in the instruction word. >>It can only be used to add values 1 thru 8, so it only needs 3 bits. That's >>why people use it. > >No, it is true. Compare: > > addq.w #8, a7 (2 bytes) > add.w #8, a7 (4 bytes) No, it is not true. The statement being referred to is the claim that "addq.l #8,a7" takes two more bytes than "addq.w #8,a7"; "add.w" and "add.l" don't enter into it.