net@tub.UUCP (Oliver Laumann) (08/09/90)
I need an implementation of alloca() for the HP9000/3xx. The alloca() from libPW.a (which makes use of malloca/free) doesn't work for my application; I need an alloca() that actually allocates space on the stack. I came up with the following (I snarfed it from the Sun-3's libc.a and converted the syntax): _alloca: mov.l (%sp),%a0 mov.l 4(%sp),%d0 addq.w &3,%d0 and.l &-4,%d0 sub.l %d0,%a7 mov.l %sp,%d0 addq.w &8,%d0 jmp (%a0) Unfortunately it doesn't work on the HP9000/3xx. Sometime after my application has invoked alloca() the first time, the contents of a register (a local variable) is garbled. Is it possible to write a "real" alloca() for the HP at all, or is there some sort of conflict with the C compiler (i.e. does the way the stack pointer is handled make usage of alloca() impossible)? Thanks, -- Oliver Laumann, Technical University of Berlin, Germany. pyramid!tub!net net@TUB.BITNET net@tub.cs.tu-berlin.de
mjs@hpfcso.HP.COM (Marc Sabatella) (08/09/90)
>Is it possible to write a "real" alloca() for the HP at all, or is >there some sort of conflict with the C compiler (i.e. does the way >the stack pointer is handled make usage of alloca() impossible)? The conventional alloca() depends on the frame pointer / stack pointer model, in which a function references its local and parameters off of the frame pointer. alloca() diddles the stack pointer and returns, hoping that no one will notice, since all references are off a6 not a7, and a7 will be restored on the unlk. The Series 300 C compiler is smart enough to remove link/unlk pairs and convert references off a6 into references off a7. For this, it needs complete information about a7, and alloca() breaks the basic assumption that the stack pointer is preserved across the call. If you do not optimize (not even with "+O1"), you may be able to get away with using the standard alloca(). But I strongly advise against it. By its very nature, alloca() is non-portable (ie, it won't even work on machines that don't use the fp/sp model), and if one day the "remove link/unlk" feature is moved out of the optimizer and into the compiler proper, it will cease to function on the 300. -------------- Marc Sabatella (marc@hpmonk.fc.hp.com) Disclaimers: 2 + 2 = 3, for suitably small values of 2 Bill and Dave may not always agree with me
rer@hpfcdc.HP.COM (Rob Robason) (08/10/90)
Oliver> Is it possible to write a "real" alloca() for the HP at all I've seen at least one hack that claimed to be an alloca() for the 300. The problem is that the author declined to guarantee that it would work from one release to the next. So it was of little use. I think this is an inherent problem with alloca()s because they rely on knowledge about how the stack is layed out in a specific implementation, if that changes due to a compiler improvement, for example, it's busted. While I know there are some pretty significant applications that make heavy use of alloca(), it has proved so troublesome that none of the standards organizations have dared touch it. Neither POSIX, SVID, XPG3, OSF nor ANSI-C support alloca(). ANSI-C, in fact makes this point in the rationale: "Some implementations provide a function (often called alloca) which allocates the requested object from automatic storage; the object is automatically freed when the calling function exits. Such a function is not efficiently implementable in a variety of environments, so it was not adopted in the standard." For this reason, most standards (and HP) are recommending that functions and applications be modified to use malloc/free or some other standard mechanism in order to be portable to the widest range of standards conforming systems. Many of the applications I've looked at that used alloca did so out of laziness, rather than need: It was a convenient way to be sure that everything was freed without having to think. In these cases the fix is easy. There are some applications where it will be hard, but possible, to work around alloca being absent. I know this isn't what you wanted to hear. You may obtain an alloca from another source and find it adequate for now. You just need to know that it's not necessarily the best way to solve the problem. Rob "Don't kill the messenger" Robason
shankar@hpclscu.HP.COM (Shankar Unni) (08/14/90)
> >Is it possible to write a "real" alloca() for the HP at all, or is > >there some sort of conflict with the C compiler (i.e. does the way > >the stack pointer is handled make usage of alloca() impossible)? > > The conventional alloca() depends on the frame pointer / stack pointer model, > in which a function references its local and parameters off of the frame > pointer. alloca() diddles the stack pointer and returns, hoping that no one > will notice, since all references are off a6 not a7, and a7 will be restored > on the unlk. And this is exactly why it is hard to make a "real" alloca() (whatever that is) work on an 800. The 800 does not have a separate frame pointer - every local variable, including parameters, is referenced off SP (the top-of-stack pointer). Changing SP thus has terrible consequences. I suppose it would be possible to build alloca() into the compiler itself (i.e. affect the code generation for a function based on whether it calls alloca() or not), but alloca() being so non-standard, it was decided not to do so. Now that the GNU C compiler has been ported to the 800 series, that would be a good place to try out such techniques, and evaluate them. All in all, it's probably best to stay as far away from alloca() as possible. If you *have* to use alloca() (i.e. someone else's software, and you can't / won't change it), you can use some good PD alloca.c that does not fiddle with SP. The code generated will be no worse than if you actually modified the code to call malloc()/free(). ----- Shankar Unni E-Mail: Hewlett-Packard California Language Lab. Internet: shankar@hpda.hp.com Phone : (408) 447-5797 UUCP: ...!hplabs!hpda!shankar DISCLAIMER: This response does not represent the official position of, or statement by, the Hewlett-Packard Company. The above data is provided for informational purposes only. It is supplied without warranty of any kind.
moore%cdr.utah.edu@cs.utah.edu (Tim Moore) (08/15/90)
In article <1340135@hpclscu.HP.COM> shankar@hpclscu.HP.COM (Shankar Unni) writes: >>> [Is alloca() possible on HP machines]? >> in which a function references its local and parameters off of the frame >> pointer. alloca() diddles the stack pointer and returns, hoping that no one >> will notice, since all references are off a6 not a7, and a7 will be restored >> on the unlk. You could use gcc on your 300 series machine, where alloca is built in. >And this is exactly why it is hard to make a "real" alloca() (whatever that >is) work on an 800. > >The 800 does not have a separate frame pointer - every local variable, >including parameters, is referenced off SP (the top-of-stack pointer). >Changing SP thus has terrible consequences. > >I suppose it would be possible to build alloca() into the compiler itself >(i.e. affect the code generation for a function based on whether it calls >alloca() or not), but alloca() being so non-standard, it was decided not to >do so. > >Now that the GNU C compiler has been ported to the 800 series, that would >be a good place to try out such techniques, and evaluate them. The 800 port of gcc also has built in support for alloca. gcc also uses a frame pointer everywhere, for better or worse. Supposedly gcc 2.0 will have better support for not using a frame pointer, which can be an important optimization. >All in all, it's probably best to stay as far away from alloca() as >possible. If you *have* to use alloca() (i.e. someone else's software, and >you can't / won't change it), you can use some good PD alloca.c that does >not fiddle with SP. The code generated will be no worse than if you >actually modified the code to call malloc()/free(). There are all sorts of reasons why alloca is nice; the luxury of not having to call free () is only one of them. Another feature is automatic deallocation of storage on catching a signal or a longjmp. While I don't really want to rekindle the alloca flames that appear periodically in comp.lang.c, I would personally use alloca freely and rely on compiler support, or the PD code for broken :-) machines that don't support alloca. > >----- >Shankar Unni E-Mail: >Hewlett-Packard California Language Lab. Internet: shankar@hpda.hp.com >Phone : (408) 447-5797 UUCP: ...!hplabs!hpda!shankar Tim Moore moore@cs.utah.edu {bellcore,hplabs}!utah-cs!moore "Ah, youth. Ah, statute of limitations." -John Waters
net@tub.UUCP (Oliver Laumann) (08/17/90)
In article <1990Aug15.101314.9626@hellgate.utah.edu> moore%cdr.utah.edu@cs.utah.edu (Tim Moore) writes: > There are all sorts of reasons why alloca is nice; the luxury of not > having to call free () is only one of them. Another feature is > automatic deallocation of storage on catching a signal or a longjmp. Yes, there are more uses for alloca() than you may dream of in your worst alloca-nightmares. One of the reasons why the application that I have ported to the HP9000 needs alloca() is that it must adjust the stack pointer on entry to main(). The program starts like this: main (ac, av) char **av; { char foo; if (Was_Dumped) { (void)alloca (INITIAL_STK_OFFSET - (original_stkbase - &foo)); } else { original_stkbase = &foo; (void)alloca (INITIAL_STK_OFFSET); } Main (ac, av); /*NOTREACHED*/ } Yes, I know, this is probably not portable to all existing machine architectures. But the feature for which this functionality is required (creation of an executable from the running program) is inherently non-portable itself. (Of course, this version of main() can be un-#ifdef-ed on systems where "dumping" cannot be supported; a conventional main() is included.) Regards, -- Oliver Laumann, Technical University of Berlin, Germany. pyramid!tub!net net@TUB.BITNET net@tub.cs.tu-berlin.de
jrc@hpdmd48.boi.hp.com (Jim Conrad) (08/21/90)
I'm surprised no one has mentioned the implementation of alloca() distributed with GNU EMACS for the 9000. Jim Conrad jrc@hpbsrl
rer@hpfcdc.HP.COM (Rob Robason) (08/24/90)
jrc> I'm surprised no one has mentioned the implementation of alloca() jrc> distributed with GNU EMACS for the 9000. This is the same as the version shipped in libPW.a on HP-UX. It is in the public domain and was written by D A Gwyn. This version has the problems described previously of using malloc and a garbage collection scheme which is invoked when it is called subsequently. Rob
tgl@zog.cs.cmu.edu (Tom Lane) (08/27/90)
In article <5570477@hpfcdc.HP.COM>, rer@hpfcdc.HP.COM (Rob Robason) writes: > jrc> I'm surprised no one has mentioned the implementation of alloca() > jrc> distributed with GNU EMACS for the 9000. > > This is the same as the version shipped in libPW.a on HP-UX. It is in the > public domain and was written by D A Gwyn. This version has the problems > described previously of using malloc and a garbage collection scheme which > is invoked when it is called subsequently. Au contraire. Recent versions of GNU Emacs include both Gwyn's package and assembly-level hacks for some specific machines, one of which is the 300 series. The 300-specific code does a real alloca by decrementing SP. It is fairly specific to HP's cc because it knows about the compiler's register save/restore habits. I believe it stops working with the HPUX 7.0 cc if you turn optimization up past +O1; presumably this is because the compiler may start using SP-relative addressing instead of a frame pointer. But Emacs works just fine with this code and +O1 optimization; I use it daily. -- tom lane Internet: tgl@cs.cmu.edu UUCP: <your favorite internet/arpanet gateway>!cs.cmu.edu!tgl BITNET: tgl%cs.cmu.edu@cmuccvma CompuServe: >internet:tgl@cs.cmu.edu
mev@hpfcso.HP.COM (Mike Vermeulen) (08/27/90)
> Recent versions of GNU Emacs include both Gwyn's package and > assembly-level hacks for some specific machines, one of which is the 300 > series. The 300 series assembly alloca in the GNU emacs distribution works by: 1) bumping SP and 2) copying the old stack top so that all SP based addresses now refer to the copies of objects on top of the stack. > I believe it stops working with the HPUX 7.0 cc if you turn optimization up > past +O1 I believe it stopped working at HPUX 6.5/+O2 because the potential addition of the save/restore of floating point registers meant that a larger stack top had to be copied. Increasing the stack top size to 88 bytes (6 data registers, 4 address registers, 6 floating point registers), makes emacs work witho ut complaint. This alloca method is still fragile because if the peephole optimizer were to change frame pointer based addressing of locals/parameters to stack pointer based addressing; then the size of the stack top still may not be adequate when given too many locals/parameters. --mev standard disclaimer: this is not an official HP response.
piet@cs.ruu.nl (Piet van Oostrum) (08/29/90)
In article <10328@pt.cs.cmu.edu>, tgl@zog (Tom Lane) writes: | |Au contraire. Recent versions of GNU Emacs include both Gwyn's package and |assembly-level hacks for some specific machines, one of which is the 300 |series. The 300-specific code does a real alloca by decrementing SP. |It is fairly specific to HP's cc because it knows about the compiler's |register save/restore habits. I believe it stops working with the HPUX 7.0 |cc if you turn optimization up past +O1; presumably this is because the |compiler may start using SP-relative addressing instead of a frame pointer. |But Emacs works just fine with this code and +O1 optimization; I use it |daily. But note that the distributed version has a bug in it that can cause stack corruption. Here is the correct version: text set PROBE,-128 # safety for C frame temporaries set MAXREG,22 # d2-d7, a2-a5, fp2-fp7 may have been saved global _alloca _alloca: mov.l (%sp)+,%a0 # return addess mov.l (%sp)+,%d0 # number of bytes to allocate mov.l %sp,%a1 # save old sp for register copy mov.l %sp,%d1 # compute new sp sub.l %d0,%d1 # space requested and.l &-4,%d1 # round down to longword sub.l &MAXREG*4,%d1 # space for saving registers mov.l %d1,%sp # save new value of sp tst.b PROBE(%sp) # create pages (sigh) mov.l %a2,%d1 # save reg a2 mov.l %sp,%a2 move.w &MAXREG-1,%d0 copy_regs_loop: /* save caller's saved registers */ mov.l (%a1)+,(%a2)+ dbra %d0,copy_regs_loop mov.l %a2,%d0 # return value mov.l %d1,%a2 # restore a2 add.l &-4,%sp # adjust tos jmp (%a0) # rts -- Piet* van Oostrum, Dept of Computer Science, Utrecht University, Padualaan 14, P.O. Box 80.089, 3508 TB Utrecht, The Netherlands. Telephone: +31-30-531806 Uucp: uunet!mcsun!ruuinf!piet Telefax: +31-30-513791 Internet: piet@cs.ruu.nl (*`Pete')