Commit | Line | Data |
---|---|---|
805e021f CE |
1 | /* |
2 | * Copyright 2000, International Business Machines Corporation and others. | |
3 | * All Rights Reserved. | |
4 | * | |
5 | * This software has been released under the terms of the IBM Public | |
6 | * License. For details, see the LICENSE file in the top-level source | |
7 | * directory or online at http://www.openafs.org/dl/license10.html | |
8 | */ | |
9 | ||
10 | #ifdef AFS_HPUX_ENV | |
11 | #ifdef hp9000s300 | |
12 | /* | |
13 | # | |
14 | # Process assembly language assist for HP 9000 series 300s. | |
15 | # | |
16 | */ | |
17 | ||
18 | text | |
19 | ||
20 | /* | |
21 | # | |
22 | # struct savearea { | |
23 | # char *topstack; | |
24 | # } | |
25 | # | |
26 | */ | |
27 | ||
28 | global _PRE_Block | |
29 | ||
30 | set topstack,0 | |
31 | ||
32 | /* Stuff to allow saving/restoring registers */ | |
33 | set NREGS,13 | |
34 | set REGS,0x3ffe # d1-d7 & a0-a5 | |
35 | ||
36 | /* | |
37 | # savecontext(f, area1, newsp) | |
38 | # int (*f)(); struct savearea *area1; char *newsp; | |
39 | */ | |
40 | ||
41 | /* Stack offsets of arguments */ | |
42 | set f,8 | |
43 | set area1,12 | |
44 | set newsp,16 | |
45 | ||
46 | global _savecontext | |
47 | _savecontext: | |
48 | mov.b &1,_PRE_Block # Dont allow any interrupt finagling | |
49 | link %a6,&-(NREGS*4) # Save frame pointer & ... | |
50 | # ... allocate space for nregs registers | |
51 | /* Save registers */ | |
52 | movem.l ®S,(%sp) | |
53 | ||
54 | mov.l area1(%a6),%a0 # a0 = base of savearea | |
55 | mov.l %sp,topstack(%a0) # area->topstack = sp | |
56 | mov.l newsp(%a6),%d0 # Get new sp | |
57 | beq.b l1 # If newsp == 0, no stack switch | |
58 | mov.l %d0,%sp # Switch to new stack | |
59 | l1: | |
60 | mov.l f(%a6),%a0 # a0 = f | |
61 | jsr (%a0) # f() | |
62 | ||
63 | /* It is impossible to be here, so abort() */ | |
64 | ||
65 | jsr _abort | |
66 | ||
67 | /* | |
68 | # returnto(area2) | |
69 | # struct savearea *area2; | |
70 | */ | |
71 | ||
72 | /* Stack offset of argument */ | |
73 | set area2,8 | |
74 | ||
75 | global _returnto | |
76 | _returnto: | |
77 | link %a6,&0 | |
78 | mov.l area2(%a6),%a0 # Base of savearea | |
79 | mov.l topstack(%a0),%sp # Restore sp | |
80 | /* Restore registers */ | |
81 | movem.l (%sp),®S | |
82 | ||
83 | add.l &(NREGS*4),%sp | |
84 | mov.l %sp,%a6 # Argghh...be careful here | |
85 | unlk %a6 | |
86 | clr.b _PRE_Block | |
87 | rts # Return to previous process | |
88 | #else | |
89 | ||
90 | .CODE | |
91 | ||
92 | ; | |
93 | ; savecontext(f, area1, newsp) | |
94 | ; int (*f)(); | |
95 | ; struct savearea *area1; | |
96 | ; char *newsp; | |
97 | ; | |
98 | savecontext | |
99 | .PROC | |
100 | ; | |
101 | ; Callinfo sets up register saves using the ENTRY_GR | |
102 | ; and ENTRY_FR parameters. ENTRY_FR=21 is only valid | |
103 | ; for PA 1.1. (How to deal with this for 800?) | |
104 | ; | |
105 | .CALLINFO CALLER,FRAME=0,SAVE_RP,ENTRY_GR=18,ENTRY_FR=21 | |
106 | ; The ENTER statement generates register saves and | |
107 | ; procedure setup. | |
108 | .ENTER | |
109 | ||
110 | LDI 1,%r31 ; Store a (char) 1 in | |
111 | ADDIL LR'PRE_Block-$global$,%r27 ; global variable | |
112 | STB %r31,RR'PRE_Block-$global$(0,%r1) ; PRE_Block. | |
113 | ||
114 | COPY %r26,%r22 ; Copy arg0 (f) to dyncall's input register. | |
115 | ||
116 | COMIB,= 0,%r24,L$0001 ; Compare arg2 (newsp) to 0. Execute the | |
117 | ; next instruction regardless of value. | |
118 | STWS %r30,0(0,%r25) ; Store the stack pointer in the first | |
119 | ; element (0th offset) of arg1 (area1). | |
120 | COPY %r24,%r30 ; Move arg2 (newsp) into the stack ptr. | |
121 | ||
122 | L$0001 | |
123 | .CALL | |
124 | BL $$dyncall,%r31 ; Dynamic call using pointer in r22. | |
125 | COPY %r31,%r2 | |
126 | ||
127 | .CALL | |
128 | BL abort,%r2 ; Can't get here, so abort. | |
129 | NOP | |
130 | .LEAVE | |
131 | .PROCEND | |
132 | ||
133 | ; returnto(area2) | |
134 | ; struct savearea *area2; | |
135 | ; | |
136 | returnto | |
137 | .PROC | |
138 | .CALLINFO CALLER,FRAME=0,SAVE_RP,ENTRY_GR=18,ENTRY_FR=21 | |
139 | ; No ENTRY is used since this is a magic routine. | |
140 | ADDIL LR'PRE_Block-$global$,%r27 ; PRE_Block = 0 | |
141 | STB %r0,RR'PRE_Block-$global$(0,%r1) | |
142 | ||
143 | LDWS 0(0,%r26),%r30 ; Load the stack pointer from area2 | |
144 | .LEAVE | |
145 | .PROCEND | |
146 | ||
147 | .EXPORT savecontext,ENTRY | |
148 | .EXPORT returnto,ENTRY | |
149 | .IMPORT $global$,DATA | |
150 | .IMPORT PRE_Block,DATA | |
151 | .IMPORT $$dyncall,MILLICODE | |
152 | .IMPORT abort,CODE | |
153 | ||
154 | .END | |
155 | #endif /* hp9000s300 */ | |
156 | #endif /* AFS_HPUX_ENV */ |