|
|
1.1 ! root 1: .file "swap.s.3b" ! 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 and ap in running's t_framep and t_ap. ! 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 and t_ap to be the current fp and ap. ! 20: # If to_run is a new child, it explicitly restores the registers from ! 21: # New_task_regs, and returns with ret &0. ! 22: # If to_run is not a new child, it returns with ret &6. ! 23: # If running_task is TERMINATED, then we don't need to do a save. ! 24: .text ! 25: .globl swap ! 26: .align 4 ! 27: swap: ! 28: save &6 # save all user regs (r3-r8) ! 29: movw 4(%ap),%r2 # r2 = to_run ! 30: movw 12(%ap),%r1 # r1 = running_is_terminated ! 31: cmpw &1,%r1 # if running is TERMINATED ! 32: je .L_RESTORE # skip save ! 33: movw 0(%ap),%r1 # r1 = running ! 34: ! 35: # save state of running task, unless it's TERMINATED ! 36: movw %fp,20(%r1) # running->t_framep = fp ! 37: movw %ap,28(%r1) # running->t_ap = ap ! 38: movw 52(%r1),%r0 # r0 = running->t_mode ! 39: cmpw &2,%r0 # if running->t_mode == SHARED ! 40: jne .L_RESTORE ! 41: # the code here to save the t_size is the same as for sswap ! 42: subw3 32(%r1),%sp,%r0 # r0 = sp - running->t_basep (bytes) ! 43: divw3 &4,%r0,36(%r1) # running->t_size = r0 / 4 (int) ! 44: ! 45: .L_RESTORE: ! 46: movw 8(%ap), %r1 # r1 = is_new_child ! 47: ! 48: # restore state of to_run_task ! 49: movw 20(%r2),%fp # fp = to_run->t_framep ! 50: movw 28(%r2),%ap # ap = to_run->t_ap ! 51: ! 52: # if is_new_child, restore registers ! 53: cmpw &1,%r1 ! 54: je .L_CHILD ! 55: ret &6 # not a new child ! 56: ! 57: .L_CHILD: # restore registers for new child ! 58: # new child task effectively returns from task::task, so we need ! 59: # to set the return value to "this" ! 60: movw 24(%r2),%r0 # r0 = to_run->th ! 61: movw &New_task_regs,%r2 ! 62: movw 0(%r2),%r3 ! 63: movw 4(%r2),%r4 ! 64: movw 8(%r2),%r5 ! 65: movw 12(%r2),%r6 ! 66: movw 16(%r2),%r7 ! 67: movw 20(%r2),%r8 ! 68: ret &0 ! 69: ! 70: # swap of SHARED ! 71: # sswap(*running, *prevOnStack, *to_run, is_new_child, running_is_terminated) ! 72: # This routine saves the fp and ap in running's t_framep and t_ap ! 73: # and the stack size in t_size. Then it copies out the target stack ! 74: # to prevOnStack's t_savearea. If to_run is not a new child, it then ! 75: # copies the saved stack of to_run (from t_savearea) to the target stack, ! 76: # and then restores to_run's t_framep and t_ap to be the current fp and ap. ! 77: # We don't need to restore state of a child to_run object, because it's ! 78: # already in place. ! 79: # If running_task is TERMINATED, then we don't need to do a save, ! 80: # and if running_task is TERMINATED and equals prevOnStack, then we don't ! 81: # have to do the stack copy. ! 82: .text ! 83: .globl sswap ! 84: .align 4 ! 85: sswap: ! 86: save &6 # save all user regs (r3-r8) ! 87: movw 0(%ap),%r1 # r1 = running ! 88: movw 4(%ap),%r4 # r4 = prevOnStack ! 89: movw 16(%ap),%r0 # r0 = running_is_terminated ! 90: cmpw &1,%r0 # if running is TERMINATED ! 91: je .L_SKIP # skip save ! 92: #save hw state of running ! 93: movw %fp,20(%r1) # running->t_framep = fp ! 94: movw %ap,28(%r1) # running->t_ap = ap ! 95: subw3 32(%r1),%sp,%r0 # r0 = sp - running->t_basep (bytes) ! 96: divw3 &4,%r0,36(%r1) # running->t_size = r0 / 4 (int) ! 97: jmp .L_SAVE ! 98: ! 99: .L_SKIP: #if running is TERMINATED and running == prevOnStack, ! 100: #then we can skip the stack copy too ! 101: cmpw %r1,%r4 # if running == prevOnStack ! 102: je .L_REST # skip prevOnStack save ! 103: ! 104: .L_SAVE: #copy out target stack to prevOnStack->t_savearea ! 105: movw 36(%r4),%r3 # r3 = prevOnStack->t_size (count) ! 106: pushw %r3 ! 107: call &1,swap_call_new # get count bytes of storage ! 108: movw %r0,40(%r4) # prevOnStack->t_savearea = r0 (to) ! 109: movw 32(%r4),%r2 # r2 = prevOnStack->t_basep (from) ! 110: .L1: #copy out loop ! 111: cmpw %r3,&0 # while (count > 0) ! 112: jle .L2 ! 113: subw2 &1,%r3 # count-- ! 114: movw 0(%r2),0(%r0) # to = from ! 115: addw2 &4,%r2 # from++ ! 116: addw2 &4,%r0 # to++ ! 117: jmp .L1 ! 118: .L2: ! 119: .L_REST: ! 120: movw 12(%ap),%r1 # r1 = is_new_child ! 121: cmpw &1,%r1 # if is_new_child == 1 ! 122: je .L6 # skip the copy-in loop ! 123: #copy into target stack from to_run->t_savearea ! 124: movw 8(%ap),%r4 # r4 = to_run ! 125: movw 32(%r4),%r0 # r0 = to_run->t_basep (to) ! 126: movw 36(%r4),%r3 # r3 = to_run->t_size (count) ! 127: # Kick up the %sp if new stack will be taller than current. ! 128: mulw3 &4,%r3,%r2 # r2 = new stack height in bytes. ! 129: addw2 %r0,%r2 # r2 = target sp ! 130: subw2 %sp,%r2 # r2 = r2 - sp ! 131: cmpw %r2,&0 # if r2 > 0, kick up sp ! 132: jle .L3 ! 133: addw2 %r2,%sp ! 134: .L3: movw 40(%r4),%r2 # r2 = to_run->t_savearea (from) ! 135: .L4: # copy in loop ! 136: cmpw %r3,&0 # while (count > 0) ! 137: jle .L5 ! 138: subw2 &1,%r3 # count-- ! 139: movw 0(%r2),0(%r0) # to = from ! 140: addw2 &4,%r2 # from++ ! 141: addw2 &4,%r0 # to++ ! 142: jmp .L4 ! 143: ! 144: .L5: # restore hw state of to_run ! 145: movw 20(%r4),%fp # fp = to_run->t_framep ! 146: movw 28(%r4),%ap # to_run->t_ap ! 147: # finally, delete to_run's t_savearea ! 148: movw 40(%r4),%r2 # r2 = to_run->t_savearea ! 149: pushw %r2 ! 150: call &1,swap_call_delete ! 151: movw &0,40(%r4) # to_run->t_savearea = 0 ! 152: .L6: ret &6
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.