Annotation of researchv10no/cmd/cfront/libC/task/swap.s.386, revision 1.1.1.1

1.1       root        1: /      .file "swap.s.386"
                      2: /      ident   "%W%"
                      3: /##############################################################################
                      4: /                      Copyright (c) 1984 AT&T
                      5: /                        All Rights Reserved   
                      6: /
                      7: /      THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF AT&T
                      8: /      
                      9: /      The copyright notice above does not evidence any        
                     10: /      actual or intended publication of such source code.
                     11: /
                     12: /##############################################################################
                     13: 
                     14: /      swap of DEDICATED
                     15: / call swap(*running_task, *to_run_task, is_new_child, running_is_terminated)
                     16: / This routine saves the fp in running's t_framep.
                     17: / If running is a SHARED task, we must save its stack size as well,
                     18: / although the stack does not need to be copied out here.
                     19: / It then restores to_run's t_framep to be the current fp.
                     20: / If to_run is a new child, it explicitly restores the registers from
                     21: / New_task_regs, and returns without restoring the regs saved in the stack.
                     22: / If to_run is not a new child, it restores all the registers saved in
                     23: / the frame on returning.
                     24: / If running_task is TERMINATED, then we don't need to do a save.
                     25: / NOTE:  assumes all functions return values in eax.
                     26: 
                     27:        .text
                     28:        .globl  swap
                     29: swap:
                     30:        pushl   %ebp                    / save caller's fp 
                     31:        movl    %esp,%ebp               / fp = sp 
                     32:        pushl   %edi                    / save all user regs: edi, esi, ebx
                     33:        pushl   %esi
                     34:        pushl   %ebx
                     35:        movl    12(%ebp),%edx           / edx = to_run
                     36:        movl    20(%ebp),%eax           / eax = running_is_terminated
                     37:        cmpl    $1,%eax                 / if eax == 1
                     38:        je      .L_RESTORE              /       skip the save
                     39:        movl    8(%ebp),%eax            / eax = running
                     40: 
                     41:        / save state of running task
                     42:        movl    %ebp,20(%eax)           / running->t_framep = fp (ebp)
                     43:        movl    52(%eax),%ecx           / %ecx = running->t_mode
                     44:        cmpw    $2,%ecx                 / if running-t_mode == SHARED
                     45:        jne     .L_RESTORE
                     46:        / the code here to save the t_size is the same as for sswap
                     47:        movl    32(%eax),%ecx           / ecx = running->t_basep
                     48:        subl    %esp,%ecx               / ecx = running->t_basep - sp
                     49:        addl    $4,%ecx                 / (size in bytes)
                     50:        shrl    $2,%ecx                 / ecx /= 4 (size in ints)
                     51:        movl    %ecx,36(%eax)           / running->t_size = ecx
                     52: 
                     53: .L_RESTORE:
                     54:        movl    16(%ebp),%ecx           / ecx = is_new_child
                     55: 
                     56:        / restore state of to_run task
                     57:        movl    20(%edx),%ebp           / ebp (fp) = to_run->t_framep
                     58: 
                     59:        / if is_new_child, restore registers
                     60:        jcxz    .L_RET                  / if ecx==0; go to .L_RET
                     61:        / new child task effectively returns from task::task, so we need
                     62:        / to set the return value to "this"
                     63:        movl    24(%edx),%eax           / eax = to_run->th
                     64:        leal    New_task_regs,%edx      / edx = address of New_task_regs
                     65:        movl    0(%edx),%edi
                     66:        movl    4(%edx),%esi
                     67:        movl    8(%edx),%ebx
                     68:        / Note: leave resets sp relative to fp, so don't need to reset sp
                     69:        / for NEW_CHILD case.
                     70:        leave
                     71:        ret
                     72: .L_RET:
                     73:        / The i386 restores registers relative to sp, so we need to reset
                     74:        / to-runs's sp.  We add 3 words (n saved regs) to the fp to get the sp.
                     75:        movl    %ebp,%edx
                     76:        sub     $12,%edx
                     77:        movl    %edx,%esp
                     78:        / restore all user regs: edi, esi, ebx
                     79:        popl    %ebx
                     80:        popl    %esi
                     81:        popl    %edi
                     82:        leave
                     83:        ret
                     84: 
                     85: 
                     86: /      swap of SHARED
                     87: / sswap(*running, *prevOnStack, *to_run, is_new_child, running_is_terminated)
                     88: / This routine saves the fp in running's t_framep and the stack size in t_size.
                     89: / Then it copies out the target stack to prevOnStack's t_savearea.
                     90: / If to_run is not a new child, it then copies the saved stack of to_run 
                     91: / (from t_savearea) to the target stack, and then restores to_run's t_framep 
                     92: / to be the current fp.  We don't need to restore state of a child 
                     93: / to_run object, because it's already in place.
                     94: / If running_task is TERMINATED, then we don't need to do a save,
                     95: / NOTE:  assumes all functions return values in eax.
                     96: / and if running_task is TERMINATED and equals prevOnStack, then we don't
                     97: / have to do the stack copy.
                     98:        .text
                     99:        .globl  sswap
                    100: sswap:
                    101:        pushl   %ebp                    / save caller's fp 
                    102:        movl    %esp,%ebp               / fp = sp 
                    103:        pushl   %edi                    / save all user regs: edi, esi, ebx
                    104:        pushl   %esi
                    105:        pushl   %ebx
                    106: 
                    107:        movl    8(%ebp),%eax            / eax = running
                    108:        movl    12(%ebp),%edi           / edi = prevOnStack
                    109:        movl    24(%ebp),%ecx           / ecx = running_is_terminated
                    110:        cmpl    $1,%ecx                 / if ecx == 1
                    111:        je      .L_SKIP                 /       skip the save
                    112:        /save hw state of running
                    113:        movl    %ebp,20(%eax)           / running->t_framep = fp (ebp)
                    114:        movl    32(%eax),%ecx           / ecx = running->t_basep
                    115:        subl    %esp,%ecx               / ecx = running->t_basep - sp
                    116:        addl    $4,%ecx                 / (size in bytes)
                    117:        shrl    $2,%ecx                 / ecx /= 4 (size in ints)
                    118:        movl    %ecx,36(%eax)           / running->t_size = ecx
                    119:        jmp     .L_SAVE
                    120: 
                    121: .L_SKIP:       /if running is TERMINATED and running == prevOnStack,
                    122:                /then we can skip the stack copy too
                    123:        cmpl    %eax,%edi               / if running == prevOnStack
                    124:        je      .L_REST                 /       skip save
                    125: 
                    126: .L_SAVE:       /copy out target stack to prevOnStack->t_savearea
                    127:        movl    36(%edi),%ecx           / ecx = prevOnStack->t_size (count)
                    128:        pushl   %ecx                    / push count arg on stack
                    129:        call    swap_call_new           / get count bytes of storage
                    130:        popl    %ecx                    / pop arg off stack
                    131:        sall    $2,%ecx                 / scale ecx to bytes
                    132:        addl    %ecx,%eax               / eax = base of new stack, plus 1 long
                    133:        subl    $4,%eax                 / eax = base of new stack (to)
                    134:        movl    %eax,40(%edi)           / prevOnStack->t_savearea = eax (to)
                    135:        movl    32(%edi),%edx           / edx = prevOnStack->t_basep (from)
                    136:        shrl    $2,%ecx                 / ecx /= 4 = size in ints (count)
                    137:        jmp     .L2
                    138: .L1:   / copy out loop
                    139:        movl    (%edx),%edi             / edi = *from
                    140:        movl    %edi,(%eax)             / *to = edi
                    141:        subl    $4,%edx                 / from--
                    142:        subl    $4,%eax                 / to--
                    143:        decl    %ecx                    / count--
                    144: .L2:
                    145:        testl   %ecx,%ecx               / if count > 0
                    146:        jg      .L1                     /       jmp .L1
                    147: .L_REST:
                    148:        movl    20(%ebp),%eax           / eax = is_new_child
                    149:        testl   %eax,%eax               / if is_new_child != 0
                    150:        jne     .L6                     /       skip the copy-in loop
                    151: 
                    152:        /copy into target stack from to_run->t_savearea
                    153:        movl    16(%ebp),%esi           / esi = to_run
                    154:        movl    32(%esi),%eax           / eax = to_run->t_basep (to)
                    155:        movl    36(%esi),%ecx           / ecx = to_run->t_size (count)
                    156:        / Kick up the sp if new stack will be taller than current.
                    157:        sall    $2,%ecx                 / ecx = new stack height in bytes
                    158:        subl    %ecx,%eax               / eax = base - size = target sp (+ 1)
                    159:        subl    %esp,%eax               / eax = eax - sp
                    160:        testl   %eax,%eax
                    161:        jge     .L3                     / if eax < 0
                    162:        addl    %eax,%esp               /       kick up sp
                    163: .L3:
                    164:        movl    32(%esi),%eax           / eax = to_run->t_basep (to)
                    165:        movl    36(%esi),%ecx           / ecx = to_run->t_size (count)
                    166:        movl    40(%esi),%edx           / edx = to_run->t_savearea (from)
                    167:        jmp     .L5
                    168: .L4:           / copy in loop
                    169:        movl    (%edx),%edi             / edi = *from
                    170:        movl    %edi,(%eax)             / *to = edi
                    171:        subl    $4,%edx                 / from--
                    172:        subl    $4,%eax                 / to--
                    173:        decl    %ecx                    / count--
                    174: .L5:
                    175:        testl   %ecx,%ecx               / if count > 0
                    176:        jg      .L4                     /       jmp .L4
                    177: 
                    178:        / restore state of to_run
                    179:        movl    20(%esi),%ebp           / fp (a6) = to_run->t_framep
                    180:        / to (eax) points to one word beyond new sp
                    181:        addl    $4,%eax
                    182:        movl    %eax,%esp               / reset sp, so regs can be restored
                    183:        / finally, delete to_run's t_savearea
                    184:        movl    36(%esi),%ecx           / ecx = to_run->t_size
                    185:        sall    $2,%ecx                 / scale size to bytes
                    186:        movl    40(%esi),%eax           / eax = to_run->t_savearea
                    187:        subl    %ecx,%eax               / get low address of savearea
                    188:        addl    $4,%eax
                    189:        pushl   %eax                    / push pointer to savearea on stack
                    190:        call    swap_call_delete        / delete to_run->t_savearea
                    191:        popl    %eax                    / pop arg off stack
                    192:        movl    $0,40(%esi)             / to_run->t_savearea = 0
                    193: / sp should be correct here, for both is and is not new child cases
                    194: .L6:   / restore all user regs: edi, esi, ebx
                    195:        popl    %ebx
                    196:        popl    %esi
                    197:        popl    %edi
                    198:        leave
                    199:        ret

unix.superglobalmegacorp.com

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