On Tue, Sep 01, 2009 at 03:04:47PM +0200, Christian Krüger wrote: > yes, but since the high byte handling takes additional code space, inlining > is not very attractive now... Have a look at this example: void foo (int, int); int main (void) { foo (3, 4); } This compiles to: jsr decsp4 lda #$03 ldy #$02 sta (sp),y iny lda #$00 sta (sp),y tax lda #$04 ldy #$00 sta (sp),y iny txa sta (sp),y jsr _foo As you can see, the only thing where handling the high byte of the stack pointer is necessary is in decsp4. Let's look at it: .proc decsp4 lda sp sec sbc #4 sta sp bcc @L1 rts @L1: dec sp+1 rts .endproc Now, if you remove the high byte handling, all you gain are three cycles for the bcc! Ok, decsp4 may be inlined more aggressively if it is smaller, giving another 6+6 cycles for jsr/rts. But as can be easily seen from the above, this is just a small precentage of the execution time when pushing the parameters. Since you need different functions for parameters and variables, you will have larger programs with this method. While decsp4 can be used for parameters, we need another decvarsp4 or similar that reserves space on the parameter stack. Yes, we can gain a few cycles by this method, but the drawback is big: Some programs will compile into invalid code and the compiler cannot tell. Many programs will get slightly larger instead of smaller. There must be two different libraries written and maintained and the compiler must know about both sorts of runtime functions. People will complain because they link modules compiled for one mode with modules compiled for the other, and other people will complain because they run into a parameter stack overflow which overwrites memory and goes unnoticed. > This is not allways possible. My solution for 'leaf'-functions is to transfer data to static parameters, > but this is difficult to overhaul and error-prone (when it becomes a 'non-leaf-function')... You can use a struct and pass a pointer to it. This is as fast as using the stack and just one __fastcall__ parameter is passed: typedef struct Params Params; struct Params { unsigned A; unsigned B; unsigned C; }; extern void __fastcall__ FancyFunc (const Params*); int main (void) { Params P; P.A = 3; P.B = P.A + 5; P.C = 27; FancyFunc (&P); ... } In the assembler module just do .struct Params pA .word pB .word pC .word .endstruct .proc _FancyFunc sta ptr1 stx ptr1+1 ; Save pointer to P ldy #Params::pC lda (ptr1),y ; Load low byte of Params::pC ... .endproc Regards Uz -- Ullrich von Bassewitz uz@musoftware.de ---------------------------------------------------------------------- To unsubscribe from the list send mail to majordomo@musoftware.de with the string "unsubscribe cc65" in the body(!) of the mail.Received on Tue Sep 1 15:59:27 2009
This archive was generated by hypermail 2.1.8 : 2009-09-01 15:59:30 CEST