BSD 4_4_Lite2 development
[unix-history] / usr / src / contrib / gawk-2.15.2 / alloca.s
CommitLineData
46ad1067
C
1/* `alloca' standard 4.2 subroutine for 68000's and 16000's and others.
2 Also has _setjmp and _longjmp for pyramids.
3 Copyright (C) 1985, 1986, 1988 Free Software Foundation, Inc.
4
5This file is part of GNU Emacs.
6
7GNU Emacs is distributed in the hope that it will be useful,
8but WITHOUT ANY WARRANTY. No author or distributor
9accepts responsibility to anyone for the consequences of using it
10or for whether it serves any particular purpose or works at all,
11unless he says so in writing. Refer to the GNU Emacs General Public
12License for full details.
13
14Everyone is granted permission to copy, modify and redistribute
15GNU Emacs, but only under the conditions described in the
16GNU Emacs General Public License. A copy of this license is
17supposed to have been given to you along with GNU Emacs so you
18can know your rights and responsibilities. It should be in a
19file named COPYING. Among other things, the copyright notice
20and this notice must be preserved on all copies. */
21
22
23/* Both 68000 systems I have run this on have had broken versions of alloca.
24 Also, I am told that non-berkeley systems do not have it at all.
25 So replace whatever system-provided alloca there may be
26 on all 68000 systems. */
27
28#define NOT_C_CODE
29/* #include "config.h" */
30
31#ifndef HAVE_ALLOCA /* define this to use system's alloca */
32
33#ifndef hp9000s300
34#ifndef m68k
35#ifndef mc68k
36#ifndef m68000
37#ifndef WICAT
38#ifndef ns32000
39#ifndef ns16000
40#ifndef sequent
41#ifndef pyramid
42#ifndef ATT3B5
43#ifndef XENIX
44you
45lose!!
46#endif /* XENIX */
47#endif /* ATT3B5 */
48#endif /* pyramid */
49#endif /* sequent */
50#endif /* ns16000 */
51#endif /* ns32000 */
52#endif /* WICAT */
53#endif /* m68000 */
54#endif /* mc68k */
55#endif /* m68k */
56#endif /* hp9000s300 */
57
58
59#ifdef hp9000s300
60#ifdef OLD_HP_ASSEMBLER
61 data
62 text
63 globl _alloca
64_alloca
65 move.l (sp)+,a0 ; pop return addr from top of stack
66 move.l (sp)+,d0 ; pop size in bytes from top of stack
67 add.l #ROUND,d0 ; round size up to long word
68 and.l #MASK,d0 ; mask out lower two bits of size
69 sub.l d0,sp ; allocate by moving stack pointer
70 tst.b PROBE(sp) ; stack probe to allocate pages
71 move.l sp,d0 ; return pointer
72 add.l #-4,sp ; new top of stack
73 jmp (a0) ; not a normal return
74MASK equ -4 ; Longword alignment
75ROUND equ 3 ; ditto
76PROBE equ -128 ; safety buffer for C compiler scratch
77 data
78#else /* new hp assembler syntax */
79/*
80 The new compiler does "move.m <registers> (%sp)" to save registers,
81 so we must copy the saved registers when we mung the sp.
82 The old compiler did "move.m <register> <offset>(%a6)", which
83 gave us no trouble
84 */
85 text
86 set PROBE,-128 # safety for C frame temporaries
87 set MAXREG,22 # d2-d7, a2-a5, fp2-fp7 may have been saved
88 global _alloca
89_alloca:
90 mov.l (%sp)+,%a0 # return addess
91 mov.l (%sp)+,%d0 # number of bytes to allocate
92 mov.l %sp,%a1 # save old sp for register copy
93 mov.l %sp,%d1 # compute new sp
94 sub.l %d0,%d1 # space requested
95 and.l &-4,%d1 # round down to longword
96 sub.l &MAXREG*4,%d1 # space for saving registers
97 mov.l %d1,%sp # save new value of sp
98 tst.b PROBE(%sp) # create pages (sigh)
99 mov.l %a2,%d1 # save reg a2
100 mov.l %sp,%a2
101 move.w &MAXREG-1,%d0
102copy_regs_loop: /* save caller's saved registers */
103 mov.l (%a1)+,(%a2)+
104 dbra %d0,copy_regs_loop
105 mov.l %a2,%d0 # return value
106 mov.l %d1,%a2 # restore a2
107 add.l &-4,%sp # adjust tos
108 jmp (%a0) # rts
109#endif /* new hp assembler */
110#else
111#if defined(m68k) || defined(mc68k) /* SGS assembler totally different */
112 file "alloca.s"
113 global alloca
114alloca:
115#ifdef MOTOROLA_DELTA
116/* slightly modified version of alloca to motorola sysV/68 pcc - based
117 compiler.
118 this compiler saves used regfisters relative to %sp instead of %fp.
119 alright, just make new copy of saved register set whenever we allocate
120 new space from stack..
121 this is true at last until SVR3V5.1 . bug has reported to Motorola. */
122 set MAXREG,10 # max no of registers to save (d2-d7, a2-a5)
123 mov.l (%sp)+,%a1 # pop return addr from top of stack
124 mov.l (%sp)+,%d0 # pop size in bytes from top of stack
125 mov.l %sp,%a0 # save stack pointer for register copy
126 addq.l &3,%d0 # round size up to long word
127 andi.l &-4,%d0 # mask out lower two bits of size
128 mov.l %sp,%d1 # compute new value of sp to d1
129 sub.l %d0,%d1 # pseudo-allocate by moving stack pointer
130 sub.l &MAXREG*4,%d1 # allocate more space for saved regs.
131 mov.l %d1,%sp # actual alloaction.
132 move.w &MAXREG-1,%d0 # d0 counts saved regs.
133 mov.l %a2,%d1 # preserve a2.
134 mov.l %sp,%a2 # make pointer to new reg save area.
135copy_regs_loop: # copy stuff from old save area.
136 mov.l (%a0)+,(%a2)+ # save saved register
137 dbra %d0,copy_regs_loop
138 mov.l %a2,%a0 # now a2 is start of allocated space.
139 mov.l %a2,%d0 # return it in both a0 and d0 to play safe.
140 mov.l %d1,%a2 # restore a2.
141 subq.l &4,%sp # new top of stack
142 jmp (%a1) # far below normal return
143#else /* not MOTOROLA_DELTA */
144 mov.l (%sp)+,%a1 # pop return addr from top of stack
145 mov.l (%sp)+,%d0 # pop size in bytes from top of stack
146 add.l &R%1,%d0 # round size up to long word
147 and.l &-4,%d0 # mask out lower two bits of size
148 sub.l %d0,%sp # allocate by moving stack pointer
149 tst.b P%1(%sp) # stack probe to allocate pages
150 mov.l %sp,%a0 # return pointer as pointer
151 mov.l %sp,%d0 # return pointer as int to avoid disaster
152 add.l &-4,%sp # new top of stack
153 jmp (%a1) # not a normal return
154 set S%1,64 # safety factor for C compiler scratch
155 set R%1,3+S%1 # add to size for rounding
156 set P%1,-132 # probe this far below current top of stack
157#endif /* not MOTOROLA_DELTA */
158
159#else /* not m68k && not mc68k */
160
161#ifdef m68000
162
163#ifdef WICAT
164/*
165 * Registers are saved after the corresponding link so we have to explicitly
166 * move them to the top of the stack where they are expected to be.
167 * Since we do not know how many registers were saved in the calling function
168 * we must assume the maximum possible (d2-d7,a2-a5). Hence, we end up
169 * wasting some space on the stack.
170 *
171 * The large probe (tst.b) attempts to make up for the fact that we have
172 * potentially used up the space that the caller probed for its own needs.
173 */
174 .procss m0
175 .config "68000 1"
176 .module _alloca
177MAXREG: .const 10
178 .sect text
179 .global _alloca
180_alloca:
181 move.l (sp)+,a1 ; pop return address
182 move.l (sp)+,d0 ; pop allocation size
183 move.l sp,d1 ; get current SP value
184 sub.l d0,d1 ; adjust to reflect required size...
185 sub.l #MAXREG*4,d1 ; ...and space needed for registers
186 and.l #-4,d1 ; backup to longword boundry
187 move.l sp,a0 ; save old SP value for register copy
188 move.l d1,sp ; set the new SP value
189 tst.b -4096(sp) ; grab an extra page (to cover caller)
190 move.l a2,d1 ; save callers register
191 move.l sp,a2
192 move.w #MAXREG-1,d0 ; # of longwords to copy
193loop: move.l (a0)+,(a2)+ ; copy registers...
194 dbra d0,loop ; ...til there are no more
195 move.l a2,d0 ; end of register area is addr for new space
196 move.l d1,a2 ; restore saved a2.
197 addq.l #4,sp ; caller will increment sp by 4 after return.
198 move.l d0,a0 ; return value in both a0 and d0.
199 jmp (a1)
200 .end _alloca
201#else
202
203/* Some systems want the _, some do not. Win with both kinds. */
204.globl _alloca
205_alloca:
206.globl alloca
207alloca:
208 movl sp@+,a0
209 movl a7,d0
210 subl sp@,d0
211 andl #~3,d0
212 movl d0,sp
213 tstb sp@(0) /* Make stack pages exist */
214 /* Needed on certain systems
215 that lack true demand paging */
216 addql #4,d0
217 jmp a0@
218
219#endif /* not WICAT */
220#endif /* m68000 */
221#endif /* not m68k */
222#endif /* not hp9000s300 */
223
224#if defined (ns16000) || defined (ns32000)
225
226 .text
227 .align 2
228/* Some systems want the _, some do not. Win with both kinds. */
229.globl _alloca
230_alloca:
231.globl alloca
232alloca:
233
234/* Two different assembler syntaxes are used for the same code
235 on different systems. */
236
237#ifdef sequent
238#define IM
239#define REGISTER(x) x
240#else
241#ifdef NS5 /* ns SysV assembler */
242#define IM $
243#define REGISTER(x) x
244#else
245#define IM $
246#define REGISTER(x) 0(x)
247#endif
248#endif
249
250/*
251 * The ns16000 is a little more difficult, need to copy regs.
252 * Also the code assumes direct linkage call sequence (no mod table crap).
253 * We have to copy registers, and therefore waste 32 bytes.
254 *
255 * Stack layout:
256 * new sp -> junk
257 * registers (copy)
258 * r0 -> new data
259 * | (orig retval)
260 * | (orig arg)
261 * old sp -> regs (orig)
262 * local data
263 * fp -> old fp
264 */
265
266 movd tos,r1 /* pop return addr */
267 negd tos,r0 /* pop amount to allocate */
268 sprd sp,r2
269 addd r2,r0
270 bicb IM/**/3,r0 /* 4-byte align */
271 lprd sp,r0
272 adjspb IM/**/36 /* space for regs, +4 for caller to pop */
273 movmd 0(r2),4(sp),IM/**/4 /* copy regs */
274 movmd 0x10(r2),0x14(sp),IM/**/4
275 jump REGISTER(r1) /* funky return */
276#endif /* ns16000 or ns32000 */
277
278#ifdef pyramid
279
280.globl _alloca
281
282_alloca: addw $3,pr0 # add 3 (dec) to first argument
283 bicw $3,pr0 # then clear its last 2 bits
284 subw pr0,sp # subtract from SP the val in PR0
285 andw $-32,sp # keep sp aligned on multiple of 32.
286 movw sp,pr0 # ret. current SP
287 ret
288
289#ifdef PYRAMID_OLD /* This isn't needed in system version 4. */
290.globl __longjmp
291.globl _longjmp
292.globl __setjmp
293.globl _setjmp
294
295__longjmp: jump _longjmp
296__setjmp: jump _setjmp
297#endif
298
299#endif /* pyramid */
300
301#ifdef ATT3B5
302
303 .align 4
304 .globl alloca
305
306alloca:
307 movw %ap, %r8
308 subw2 $9*4, %r8
309 movw 0(%r8), %r1 /* pc */
310 movw 4(%r8), %fp
311 movw 8(%r8), %sp
312 addw2 %r0, %sp /* make room */
313 movw %sp, %r0 /* return value */
314 jmp (%r1) /* continue... */
315
316#endif /* ATT3B5 */
317
318#ifdef XENIX
319
320.386
321
322_TEXT segment dword use32 public 'CODE'
323assume cs:_TEXT
324
325;-------------------------------------------------------------------------
326
327public _alloca
328_alloca proc near
329
330 pop ecx ; return address
331 pop eax ; amount to alloc
332 add eax,3 ; round it to 32-bit boundary
333 and al,11111100B ;
334 mov edx,esp ; current sp in edx
335 sub edx,eax ; lower the stack
336 xchg esp,edx ; start of allocation in esp, old sp in edx
337 mov eax,esp ; return ptr to base in eax
338 push [edx+8] ; save poss. stored reg. values (esi,edi,ebx)
339 push [edx+4] ; on lowered stack
340 push [edx] ;
341 sub esp,4 ; allow for 'add esp, 4'
342 jmp ecx ; jump to return address
343
344_alloca endp
345
346_TEXT ends
347
348end
349
350#endif /* XENIX */
351
352#endif /* not HAVE_ALLOCA */