|
|
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.