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