Annotation of 43BSDReno/contrib/emacs-18.55/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 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.