Annotation of researchv10no/cmd/cfront/libC/task/swap.s.386, revision 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.