|
|
1.1 root 1: /*ident "%W%" */
2: /**************************************************************************
3: Copyright (c) 1984 AT&T
4: All Rights Reserved
5:
6: THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF AT&T
7:
8: The copyright notice above does not evidence any
9: actual or intended publication of such source code.
10:
11: *****************************************************************************/
12: #ifndef HW_STACK_H
13: #define HW_STACK_H
14:
15: /* Machine-dependent macros, typedefs, and externs for task library.
16: * Porting these requires intimate knowledge of the stack frame layout,
17: * call and return sequences for the machine.
18: * They are used by task.c and fudge.c and sim.c.
19: *
20: * Some are grouped according to direction of stack growth.
21: *
22: * New-style asms would eliminate function calls for TOP, AP, and FP.
23: */
24:
25: typedef unsigned char MACHINE_BYTE;
26:
27: #if defined(M32) || defined(u3b2) || defined(u3b5) || defined(u3b15)
28: #define BELLMAC_CHIP
29: #endif
30: #if defined(u3b) || defined(BELLMAC_CHIP)
31: #define PROC_3B
32: #endif
33:
34: #ifdef PROC_3B
35:
36: #define STACK_GROWS_UP
37: /* typedefs for the hardware state saved on the stack after a call */
38: typedef struct {
39: unsigned long r3;
40: unsigned long r4;
41: unsigned long r5;
42: unsigned long r6;
43: unsigned long r7;
44: unsigned long r8;
45:
46: } HW_REGS;
47:
48: struct FrameLayout {
49: short n_saved; // number of registers saved in this frame.
50: // (3B's don't have masks of regs saved)
51: FrameLayout(int*); // called with frame pointer
52: };
53:
54: extern "C" {
55: extern int* FP(); /* FP of caller */
56: extern int* AP(); /* AP of caller */
57: extern void FUDGE_SP(int*, int*); /* reset ap to first arg */
58: extern int* TOP(); /* SP-1 of caller (pnts to last used word in stack) */
59: }
60: extern void save_saved_regs(HW_REGS*, int*);
61:
62: #define MAXINT_AS_FLOAT 2147483647.0
63:
64: /* Save all current regs and regs saved in this frame in reg_struct_p,
65: * for restoration when child runs.
66: * Note: SAVE_REGS needed in case task::restore() saves more regs
67: * than task::task.
68: */
69: #define SAVE_CHILD_REGS(reg_struct_p) \
70: SAVE_REGS(reg_struct_p); \
71: save_saved_regs((reg_struct_p), ta_fp);
72:
73: extern "C" {
74: extern void set_r3(int*);
75: extern void set_r4(int*);
76: extern void set_r5(int*);
77: extern void set_r6(int*);
78: extern void set_r7(int*);
79: extern void set_r8(int*);
80: }
81:
82: #ifdef u3b
83:
84: #define OLD_FP(fp) ( *( (int*)(fp) - 11 ) )
85: #define OLD_AP(fp) ( *( (int*)(fp) - 12 ) )
86: #define OLD_PC(fp) ( *( (int*)(fp) - 13 ) )
87: #define FIRST_SAVED_REG_P(fp, n) ((int*)(fp) - (n))
88: #define LAST_SAVED_REG_P(fp,n) ((int*)(fp) - 1)
89:
90: #define IS_SAVE_OPCODE(instr) ((MACHINE_BYTE)(instr) == (MACHINE_BYTE)0x7A)
91:
92: /* Given a pointer to a save instruction, yield the number of registers saved */
93: #define N_SAVED_REGS(instr) (((char *)(instr))[1] >> 4)
94:
95:
96: #else /* u3b2, u3b5, u3b15 */
97:
98:
99: #define OLD_FP(fp) ( *( (int*)(fp) - 7 ) )
100: #define OLD_AP(fp) ( *( (int*)(fp) - 8 ) )
101: #define OLD_PC(fp) ( *( (int*)(fp) - 9 ) )
102: #define FIRST_SAVED_REG_P(fp,n) ( (int*)(fp) - 6 )
103: #define LAST_SAVED_REG_P(fp,n) ( (int*)(fp) - 6 + (n) - 1)
104:
105: #define SAVE_OPERAND(instr) (((char *)(instr))[1] & 0xf)
106:
107: /* Given a pointer to a save instruction, yield the number of registers saved */
108: #define N_SAVED_REGS(instr) (8 - SAVE_OPERAND(instr) + 1)
109:
110: #define IS_SAVE_OPCODE(instr) ((MACHINE_BYTE)(instr) == (MACHINE_BYTE)0x10)
111:
112: #endif
113: /* u3b, u3b2, u3b5, u3b15 */
114: #endif /* PROC_3B */
115:
116:
117: #ifdef vax
118:
119: #define STACK_GROWS_DOWN
120: extern "C" {
121: extern int* FP(); /* FP of caller */
122: extern int* TOP(); /* SP of caller (pnts to last used word in stack) */
123: }
124: #define FUDGE_SP(ap, fp) /* unnecessary on vax */
125: #define AP() 0 /* unnecessary on vax */
126: #define OLD_AP(fp) (*((int*)(fp) + 2))
127: #define OLD_FP(fp) (*((int*)(fp) + 3))
128: #define OLD_PC(fp) (*((int*)(fp) + 4))
129: #define FIRST_SAVED_REG_P(fp,n) ((int*)(fp) + 5)
130: #define LAST_SAVED_REG_P(fp,n) ((int*)(fp) + 5 + (n) - 1)
131: #define ENTRY_MASK(fp) (*((short*)(fp) + 3))
132: #define N_VOL_REGS 6 /* assumes compiler only allocates r6-r11 for users */
133:
134: #define MAXINT_AS_FLOAT 2147483647.0
135: #define STACK_GROWS_DOWN
136:
137: /* typedef for the hardware state saved on the stack after a call */
138: typedef struct {
139: unsigned long r6;
140: unsigned long r7;
141: unsigned long r8;
142: unsigned long r9;
143: unsigned long r10;
144: unsigned long r11;
145:
146: } HW_REGS;
147:
148: /* Save all current regs and regs saved in this frame in reg_struct_p,
149: * for restoration when child runs. On the VAX, save_saved_regs is
150: * unnecessary because the return from swap will restore the regs saved
151: * in task:task.
152: */
153: #define SAVE_CHILD_REGS(reg_struct_p) \
154: SAVE_REGS(reg_struct_p);
155:
156: extern "C" {
157: extern void set_r6(int*);
158: extern void set_r7(int*);
159: extern void set_r8(int*);
160: extern void set_r9(int*);
161: extern void set_r10(int*);
162: extern void set_r11(int*);
163: }
164:
165: #endif
166:
167: #ifdef mc68000 /* Really, ifdef sun--stack frame layout
168: * is different on a UNIX PC, for example
169: */
170:
171: #define STACK_GROWS_DOWN
172: /* typedefs for the hardware state saved on the stack after a call.
173: * Assumes d0, d1, a0, a1 are scratch registers, a6 is fp, a7 is sp.
174: * a0 and a1 are included so that loops through a mask word work correctly.
175: */
176: typedef struct {
177: unsigned long d2;
178: unsigned long d3;
179: unsigned long d4;
180: unsigned long d5;
181: unsigned long d6;
182: unsigned long d7;
183: unsigned long a0; /* should not be used */
184: unsigned long a1; /* should not be used */
185: unsigned long a2;
186: unsigned long a3;
187: unsigned long a4;
188: unsigned long a5;
189: } HW_REGS;
190:
191: struct FrameLayout {
192: short offset; // of top of saved registers from fp
193: unsigned short mask; // of registers saved in frame
194: FrameLayout(int*); // called with frame pointer
195: };
196:
197: extern int* Skip_pc_p; /* global for FUDGE_SP and fudge_sp */
198: extern "C" {
199: extern int* FP(); /* FP of caller */
200: extern void FUDGE_SP(int*, int*); /* prepare to reset sp */
201: extern void fudge_sp(); /* reset sp on return through fudged
202: * frame */
203: extern int* TOP(); /* SP of caller
204: * (pnts to last used word in stack) */
205: }
206: #define AP() 0 /* unnecessary on mc68000 */
207: #define OLD_AP(fp) 0 /* unnecessary on mc68000 */
208: #define OLD_FP(fp) (*((int*)(fp)))
209: #define OLD_PC(fp) (*((int*)(fp) + 1))
210: #define OLD_PC_P(fp) ((int*)(fp) + 1)
211: #define FIRST_SAVED_REG_P(fp, o) ((int*)(fp) + (o))
212:
213:
214: extern void save_saved_regs(HW_REGS*, int*);
215:
216: /* Save all current regs and regs saved in this frame in reg_struct_p,
217: * for restoration when child runs.
218: * Note: SAVE_REGS needed in case task::restore() saves more regs
219: * than task::task.
220: */
221: #define SAVE_CHILD_REGS(reg_struct_p) \
222: SAVE_REGS(reg_struct_p); \
223: save_saved_regs((reg_struct_p), ta_fp);
224:
225: extern "C" {
226: extern void set_d2(int*);
227: extern void set_d3(int*);
228: extern void set_d4(int*);
229: extern void set_d5(int*);
230: extern void set_d6(int*);
231: extern void set_d7(int*);
232: extern void set_a2(int*);
233: extern void set_a3(int*);
234: extern void set_a4(int*);
235: extern void set_a5(int*);
236: }
237:
238: #define MAXINT_AS_FLOAT 2147483647.0
239:
240: #endif /* mc68000 */
241:
242: #ifdef i386
243:
244: #define STACK_GROWS_DOWN
245:
246: /* typedefs for the hardware state saved on the stack after a call.
247: * Assumes eax, ecx, edx are scratch registers, ebp is fp, esp is sp.
248: */
249: typedef struct {
250: unsigned long edi;
251: unsigned long esi;
252: unsigned long ebx;
253: } HW_REGS;
254:
255: struct FrameLayout {
256: int offset; // of base of saved registers from fp
257: unsigned short mask; // of registers saved in frame
258: FrameLayout(int*); // called with frame pointer
259: };
260:
261: extern int* Skip_pc_p; /* global for FUDGE_SP and fudge_sp */
262: extern "C" {
263: extern int* FP(); /* FP of caller */
264: extern void FUDGE_SP(int*, int*); /* prepare to reset sp */
265: extern void fudge_sp(); /* reset sp on return through fudged
266: * frame */
267: extern int* TOP(); /* SP of caller
268: * (pnts to last used word in stack) */
269: }
270:
271: #define AP() 0 /* unnecessary on i386 */
272: #define OLD_AP(fp) 0 /* unnecessary on i386 */
273: #define OLD_FP(fp) (*((int*)(fp)))
274: #define OLD_PC(fp) (*((int*)(fp) + 1))
275: #define OLD_PC_P(fp) ((int*)(fp) + 1)
276: #define FIRST_SAVED_REG_P(fp, o) (((int*)(fp) - (o)) - 1)
277:
278:
279: extern void save_saved_regs(HW_REGS*, int*);
280:
281: /* Save all current regs and regs saved in this frame in reg_struct_p,
282: * for restoration when child runs.
283: * Note: SAVE_REGS needed in case task::restore() saves more regs
284: * than task::task.
285: */
286: #define SAVE_CHILD_REGS(reg_struct_p) \
287: SAVE_REGS(reg_struct_p); \
288: save_saved_regs((reg_struct_p), ta_fp);
289:
290: extern "C" {
291: extern void set_ebx(int*);
292: extern void set_esi(int*);
293: extern void set_edi(int*);
294: }
295:
296: #define MAXINT_AS_FLOAT 2147483647.0
297:
298: #endif /* i386 */
299:
300: #ifdef STACK_GROWS_DOWN
301: #define STACK_LAST_WORD_P(b,s) ((b) - (s) + 1)
302: #define COPY_STACK(f,c,t) while ((c)--) *(t)-- = *(f)--
303: #define ACTIVE_STK_SZ(b,t) (b) - (t) + 1 /* size of active stack */
304: #define STACK_BASE(b,s) (b) + (s) - 1
305: #define SAVED_AREA(b,s) (b) - (s) + 1
306: #endif
307:
308: #ifdef STACK_GROWS_UP
309: #define STACK_LAST_WORD_P(b,s) ((b) + (s) - 1)
310: #define COPY_STACK(f,c,t) while ((c)--) *(t)++ = *(f)++
311: #define ACTIVE_STK_SZ(b,t) (t) - (b) + 1 /* size of active stack */
312: #define STACK_BASE(b,s) (b)
313: #define SAVED_AREA(b,s) (b)
314: #endif
315:
316: /* externs needed for all machines, definitions in hw_stack.c */
317: extern "C" {
318: extern void SAVE_REGS(HW_REGS*); /* call SAVE_REGS(&New_task_regs)
319: * copies caller's registers into
320: * HW_REGS structure
321: */
322: }
323:
324:
325: #endif /* HW_STACK_H */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.