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