Path: utzoo!utgpu!news-server.csri.toronto.edu!cs.utexas.edu!uunet!mcsun!ukc!icdoc!qmw-cs!morten From: morten@cs.qmw.ac.uk (Morten Ronseth) Newsgroups: comp.sys.mac.programmer Subject: alloca; *almost* working... Message-ID: <1801@sequent.cs.qmw.ac.uk> Date: 19 Mar 90 15:54:11 GMT Reply-To: morten@cs.qmw.ac.uk (Morten Ronseth) Organization: Computer Science Dept, QMW, University of London, UK. Lines: 94 (A lat desperate attempt to make 'alloca' work on the mac...) This is the assembly for my `alloca' routine, a rewrite of the one used in GNU Emacs. Now, the `alloca' works fine in all of my own code, both using MPW and LightspeedC. I thought I had it all figured out, until I linked it into gcc (as in the actual GNU code), using MPW C, and found I was wrong. The preprocessor cc1 just falls over on this code, and as the stackpointer gets garbled I can't do a stack-trace. When I use `malloc' instead of `alloca', everything is fine (but don't tell me to use `malloc' instead and just forget about the whole thing!) Can somebody please tell me what is wrong? Morten. Strategy: Because one can never predict how many registers (if any) are saved at function entry, (movem.l ,-(sp)), assume worst case and copy ALL registers to TOS where they are expected to be found at return-time. CASE OBJ alloca PROC EXPORT movea.l (sp)+,a0 ; pop return addr from tos move.l (sp)+,d0 ; pop size in bytes from tos move.l sp,a1 ; save old sp for register copy move.l sp,d1 ; compute new sp sub.l d0,d1 ; allocate requested space on stack and.l #-4,d1 ; round down to longword sub.l #16 * 4,d1 ; space for saving registers move.l d1,sp ; save new value of sp move.w #16 - 1,d0 ; loop counter... @loop move.l (a1)+,(sp)+ ; copy the register to top of stack dbra d0,@loop ; loop... move.l sp,d0 ; return value move.l d1,sp ; load new value for sp jmp (a0) ; rts ENDPROC END (If I remeber correctly, MPW C defers the pop'ing, `addq.l #n,sp', of params after the return of a 'jsr', i.e. relying on an `unlk' to adjust the stack. Hence I do not need a `subq.l #4,sp' in my 'alloca' to fix the stack. But what, do I hear you ask, if the calling function doesn't take any params nor uses any local vars? Well, I'm compiling with `-g' so the compiler should generate a `link' and an `unlk' no matter what...shouldn't it?) The LightspeedC version looks like this (pretty much the same, huh?): #define MAXREG 16 long alloca () { asm{ movea.l (sp)+,a0 ; pop return addr from tos move.l (sp)+,d0 ; pop size in bytes from tos move.l sp,a1 ; save old sp for register copy move.l sp,d1 ; compute new sp sub.l d0,d1 ; allocate requested space on stack and.l #-4,d1 ; round down to longword sub.l #MAXREG * 4,d1 ; space for saving registers move.l d1,sp ; save new value of sp move.w #MAXREG - 1,d0 ; loop counter... loop: move.l (a1)+,(sp)+ ; copy the register to top of stack dbra d0,@loop ; loop... move.l sp,d0 ; return value move.l d1,sp ; load new value for sp subq.l #4,sp ; caller will do `addq.l #4,sp' jmp (a0) ; rts } } (No optimization here, lets fix the stack right away, we've got all the time in the world, right?) -- ============================================================================== Morten Lerskau Ronseth UUCP: morten@qmw-cs.uucp or ...seismo!mcvax!ukc!qmw-cs!morten JANET: morten@uk.ac.qmw.cs Post: Dept of Computer Science ARPA: morten%qmw.cs@ucl-cs.arpa Queen Mary and Westfield College Easylink: 19019285 University of London Telex: 893750 QMCUOL Mile End Road Fax: +44 1 981 7517 London E1 4NS Phone: +44 1 975 5220 England