Annotation of GNUtools/emacs/src/alloca.s, revision 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.