|
|
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
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.