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

1.1       root        1: |      .file "swap.s.68k"
                      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 movem to restore the regs saved in
                     22: | the stack.
                     23: | If to_run is not a new child, it restores all the registers saved in
                     24: | the frame on returning.
                     25: | If running_task is TERMINATED, then we don't need to do a save.
                     26: | NOTE:  assumes all functions return values in d0.
                     27: 
                     28: | The following constants are displacements of elements in class task:
                     29: | t_framep, th, t_basep, t_size, t_savearea, and t_mode.
                     30: TFRAME = 20
                     31: TH = 24
                     32: TBASEP = 32
                     33: TSIZE = 36
                     34: TSAVE = 40
                     35: TMODE = 52
                     36: 
                     37: | The following constants are displacements from the fp to function args.
                     38: ARG1 = 8
                     39: ARG2 = 12
                     40: ARG3 = 16
                     41: ARG4 = 20
                     42: ARG5 = 24
                     43: 
                     44:        .text
                     45:        .globl  _swap
                     46: _swap:
                     47:        link    a6,#-40
                     48:        moveml  #0x3cfc,sp@             | save all user regs (d2-d7, a2-a5)
                     49:        movl    a6@(ARG2),a1            | a1 = to_run
                     50:        movl    a6@(ARG4),d0            | d0 = running_is_terminated
                     51:        bnes    L_RESTORE               | if running is TERMINATED
                     52:                                        |       skip the save
                     53:        movl    a6@(ARG1),a0            | a0 = running
                     54: 
                     55:        | save state of running task
                     56:        movl    a6,a0@(TFRAME)          | running->t_framep = fp (a6)
                     57:        movl    a0@(TMODE),d0           | d0 = running->t_mode
                     58:        cmpl    #2,d0                   | if running->t_mode == SHARED
                     59:        bnes    L_RESTORE
                     60:        | the code here to save the t_size is the same as for sswap
                     61:        movl    a0@(TBASEP),d0          | d0 = running->t_basep
                     62:        subl    sp,d0                   | d0 = running->t_basep - sp
                     63:        addql   #4,d0                   | (size in bytes)
                     64:        asrl    #2,d0                   | d0 /= 4 (size in ints)
                     65:        movl    d0,a0@(TSIZE)           | running->t_size = d0
                     66: 
                     67: L_RESTORE:
                     68:        movl    a6@(ARG3),d1            | d1 = is_new_child
                     69: 
                     70:        | restore state of to_run task
                     71:        movl    a1@(TFRAME),a6          | a6 (fp) = to_run->t_framep
                     72: 
                     73:        | if is_new_child, restore registers
                     74:        tstl    d1
                     75:        beqs    L_RET
                     76:        | new child task effectively returns from task::task, so we need
                     77:        | to set the return value to "this"
                     78:        movl    a1@(TH),d0              | d0 = to_run->th
                     79:        lea     _New_task_regs,a1       | a1 = address of New_task_regs
                     80:        movl    a1@,d2
                     81:        movl    a1@(4),d3
                     82:        movl    a1@(8),d4
                     83:        movl    a1@(12),d5
                     84:        movl    a1@(16),d6
                     85:        movl    a1@(20),d7
                     86:        movl    a1@(32),a2
                     87:        movl    a1@(36),a3
                     88:        movl    a1@(40),a4
                     89:        movl    a1@(44),a5
                     90:        unlk    a6                      | NOTE:  movem not needed here.
                     91:        rts
                     92: L_RET:
                     93:        moveml  a6@(-40),#0x3cfc        | restore all user regs (d2-d7, a2-a5)
                     94:        unlk    a6
                     95:        rts
                     96: 
                     97: 
                     98: |      swap of SHARED
                     99: | sswap(*running, *prevOnStack, *to_run, is_new_child, running_is_terminated)
                    100: | This routine saves the fp in running's t_framep and the stack size in t_size.
                    101: | Then it copies out the target stack to prevOnStack's t_savearea.
                    102: | If to_run is not a new child, it then copies the saved stack of to_run 
                    103: | (from t_savearea) to the target stack, and then restores to_run's t_framep 
                    104: | to be the current fp.  We don't need to restore state of a child 
                    105: | to_run object, because it's already in place.
                    106: | If running_task is TERMINATED, then we don't need to do a save,
                    107: | and if running_task is TERMINATED and equals prevOnStack, then we don't
                    108: | have to do the stack copy.
                    109: | NOTE:  assumes all functions return values in d0.
                    110:        .text
                    111:        .globl  _sswap
                    112: _sswap:
                    113:        link    a6,#-40
                    114:        moveml  #0x3cfc,sp@             | save all user regs (d2-d7, a2-a5)
                    115: 
                    116:        movl    a6@(ARG1),a1            | a1 = running
                    117:        movl    a6@(ARG2),a2            | a2 = prevOnStack
                    118:        movl    a6@(ARG5),d0            | d0 = running_is_terminated
                    119:        bnes    L_SKIP                  | if running is TERMINATED
                    120:                                        |       skip the save
                    121:        |save hw state of running
                    122:        movl    a6,a1@(TFRAME)          | running->t_framep = fp (a6)
                    123:        movl    a1@(TBASEP),d0          | d0 = running->t_basep
                    124:        subl    sp,d0                   | d0 = running->t_basep - sp
                    125:        addql   #4,d0                   | (size in bytes)
                    126:        asrl    #2,d0                   | d0 /= 4 (size in ints)
                    127:        movl    d0,a1@(TSIZE)           | running->t_size = d0
                    128:        bra     L_SAVE
                    129: L_SKIP:
                    130:        cmpl    a1,a2                   | if running == prevOnStack
                    131:        beq     L_REST                  |       skip prevOnStack save
                    132: 
                    133: L_SAVE:        |copy out target stack to prevOnStack->t_savearea
                    134:        movl    a2@(TSIZE),d2           | d2 = prevOnStack->t_size (count)
                    135:        movl    d2,sp@-                 | push count arg on stack
                    136:        jsr     _swap_call_new          | get count bytes of storage
                    137:        addql   #4,sp                   | pop arg off stack
                    138:        asll    #2,d2                   | scale d2 to bytes
                    139:        addl    d2,d0                   | d0 = base of new stack, plus 1 long
                    140:        subql   #4,d0                   | d0 = base of new stack
                    141:        movl    d0,a0                   | a0 = base of new stack (to)
                    142:        movl    a0,a2@(TSAVE)           | prevOnStack->t_savearea = a0 (to)
                    143:        movl    a2@(TBASEP),a1          | a1 = prevOnStack->t_basep (from)
                    144:        addql   #4,a0                   | prepare for predecrement
                    145:        addql   #4,a1                   | ditto
                    146:        movl    a2@(TSIZE),d0           | d0 = prevOnStack->t_size (count)
                    147:        tstl    d0
                    148:        beqs    L2                      | if size == 0, goto L2
                    149:        subql   #1,d0                   | for dbra
                    150: L1:    | copy out loop
                    151:        movl    a1@-,a0@-               | *--to = *--from
                    152:        dbra    d0,L1                   | if --d0 != 0, goto L1
                    153: L2:
                    154: L_REST:
                    155:        movl    a6@(ARG4),d0            | d0 = is_new_child
                    156:        bnes    L6                      | if is_new_child != 0
                    157:                                        |       skip the copy-in loop
                    158:        |copy into target stack from to_run->t_savearea
                    159:        movl    a6@(ARG3),a2            | a2 = to_run
                    160:        movl    a2@(TBASEP),a0          | a0 = to_run->t_basep (to)
                    161:        movl    a2@(TSIZE),d0           | d0 = to_run->t_size (count)
                    162:        | Kick up the sp if new stack will be taller than current.
                    163:        asll    #2,d0                   | d0 = new stack height in bytes
                    164:        subl    d0,a0                   | a0 = target sp
                    165:        subl    sp,a0                   | a0 = a0 - sp
                    166:        tstl    a0
                    167:        bges    L3                      | if a0 < 0
                    168:        addl    a0,sp                   |       kick up sp
                    169: L3:    movl    a2@(TBASEP),a0          | a0 = to_run->t_basep (to)
                    170:        movl    a2@(TSAVE),a1           | a1 = to_run->t_savearea (from)
                    171:        addql   #4,a1                   | prepare for predecrement
                    172:        addql   #4,a0                   | ditto
                    173:        movl    a2@(TSIZE),d0           | d0 = to_run->t_size (count)
                    174:        tstl    d0
                    175:        beqs    L5                      | if size == 0, goto L5
                    176:        subql   #1,d0                   | for dbra
                    177: L4:    | copy in loop
                    178:        movl    a1@-,a0@-               | *--to = *--from
                    179:        dbra    d0,L4                   | if --d0 != 0, goto L4
                    180: L5:
                    181:        | restore state of to_run
                    182:        movl    a2@(TFRAME),a6          | fp (a6) = to_run->t_framep
                    183:        | finally, delete to_run's t_savearea
                    184:        movl    a2@(TSIZE),d1           | d1 = to_run->t_size
                    185:        asll    #2,d1                   | scale size to bytes
                    186:        movl    a2@(TSAVE),a0           | a0 = to_run->t_savearea
                    187:        subl    d1,a0                   | get low address of savearea
                    188:        addql   #4,a0
                    189:        movl    a0,sp@-                 | push pointer to savearea on stack
                    190:        jsr     _swap_call_delete       | delete to_run->t_savearea
                    191:        addql   #4,sp                   | pop arg off stack
                    192:        movl    #0,a2@(TSAVE)           | to_run->t_savearea = 0
                    193: L6:    moveml  a6@(-40),#0x3cfc        | restore all user regs (d2-d7, a2-a5)
                    194:        unlk    a6
                    195:        rts

unix.superglobalmegacorp.com

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