Annotation of GNUtools/emacs/src/alloca.s, revision 1.1.1.1

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

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.