2 Copyright © 1995-2001, The AROS Development Team. All rights reserved.
9 #include <machine/psl.h>
10 #include <sys/types.h>
11 #include <sys/param.h>
17 /* Put a value of type SP_TYPE on the stack or get it off the stack. */
18 #define _PUSH(sp,val) \
20 SP_TYPE **stackp = (sp); \
22 **stackp = (SP_TYPE)(val); \
24 #define _POP(sp) (*sp++)
26 typedef struct sigcontext sigcontext_t
;
27 #define SIGHANDLER bsd_sighandler
28 #define SIGHANDLER_T __sighandler_t *
33 #define SC_DISABLE(sc) (sc->sc_mask = sig_int_mask)
34 #define SC_ENABLE(sc) (sigemptyset(&sc->sc_mask))
36 #define SP(sc) (sc->sc_esp)
37 #define FP(sc) (sc->sc_ebp)
38 #define PC(sc) (sc->sc_eip)
40 #define R0(sc) (sc->sc_eax)
41 #define R1(sc) (sc->sc_ebx)
42 #define R2(sc) (sc->sc_ecx)
43 #define R3(sc) (sc->sc_edx)
44 #define R4(sc) (sc->sc_edi)
45 #define R5(sc) (sc->sc_esi)
46 #define R6(sc) (sc->sc_isp)
49 * We can't have an #ifdef based on FreeBSD here because this structure
50 * is (wrongly) accessed from rom/exec.
52 struct AROS_cpu_context
54 ULONG regs
[9]; /* eax, ebx, ecx, edx, edi, esi, isp, fp, pc */
62 int fpstate
[128] __attribute__ ((aligned (16)));
75 struct AROS_cpu_context
*sc
;
78 #undef SIZEOF_ALL_REGISTERS
79 #define SIZEOF_ALL_REGISTERS (sizeof(struct AROS_cpu_context))
80 #define GetCpuContext(task) ((struct AROS_cpu_context *)\
81 (GetIntETask(task)->iet_Context))
82 #define GetSP(task) ((SP_TYPE **)(&task->tc_SPReg))
84 #define GLOBAL_SIGNAL_INIT \
85 static void sighandler (int sig, sigcontext_t * sc); \
87 static void SIGHANDLER (int sig, int code, struct sigcontext *sc) \
89 sighandler( sig, (sigcontext_t*)sc); \
92 #define SAVE_CPU(cc,sc) \
94 (cc)->regs[0] = R0(sc); \
95 (cc)->regs[1] = R1(sc); \
96 (cc)->regs[2] = R2(sc); \
97 (cc)->regs[3] = R3(sc); \
98 (cc)->regs[4] = R4(sc); \
99 (cc)->regs[5] = R5(sc); \
100 (cc)->regs[6] = R6(sc); \
101 (cc)->regs[7] = FP(sc); \
102 (cc)->regs[8] = PC(sc); \
105 #define RESTORE_CPU(cc,sc) \
107 R0(sc) = (cc)->regs[0]; \
108 R1(sc) = (cc)->regs[1]; \
109 R2(sc) = (cc)->regs[2]; \
110 R3(sc) = (cc)->regs[3]; \
111 R4(sc) = (cc)->regs[4]; \
112 R5(sc) = (cc)->regs[5]; \
113 R6(sc) = (cc)->regs[6]; \
114 FP(sc) = (cc)->regs[7]; \
115 PC(sc) = (cc)->regs[8]; \
118 #define SAVE_ERRNO(cc) \
120 (cc)->errno_backup = errno; \
123 #define RESTORE_ERRNO(cc) \
125 errno = (cc)->errno_backup; \
130 # if __FreeBSD_version >= 500001
132 * This is the FreeBSD 5.x and higher version
134 # define SAVE_FPU(cc,sc) \
137 (cc)->acc_u.acc_f5.fpformat = (sc)->sc_fpformat; \
138 (cc)->acc_u.acc_f5.ownedfp = (sc)->sc_ownedfp; \
139 for(i_ = 0; i_ < 128; ++i_) \
140 (cc)->acc_u.acc_f5.fpstate[i_] = (sc)->sc_fpstate[i_]; \
143 # define RESTORE_FPU(cc,sc) \
146 (sc)->sc_fpformat = (cc)->acc_u.acc_f5.fpformat; \
147 (sc)->sc_ownedfp = (cc)->acc_u.acc_f5.ownedfp; \
148 for(i_ = 0; i_ < 128; ++i_) \
149 (sc)->sc_fpstate[i_] = (cc)->acc_u.acc_f5.fpstate[i_]; \
152 # define HAS_FPU(sc) \
154 ((sc)->sc_ownedfp != _MC_FPOWNED_NONE) \
156 ((sc)->sc_fpformat != _MC_FPFMT_NODEV) \
159 # define PREPARE_FPU(cc) \
161 (cc)->acc_u.acc_f5.fpformat = _MC_FPFMT_NODEV; \
162 (cc)->acc_u.acc_f5.ownedfp = _MC_FPOWNED_NONE; \
168 * FreeBSD 4 and below have a different context format.
170 # define SAVE_FPU(cc,sc) \
173 for (i_ = 0; i_ < 28; i_++) \
174 (cc)->acc_u.acc_f4.fpstate[i_] = (sc)->sc_fpregs[i_]; \
177 # define RESTORE_FPU(cc,sc) \
180 for (i_ = 0; i_ < 28; i_++) \
181 (sc)->sc_fpregs[i_] = (cc)->acc_u.acc_f4.fpstate[i_]; \
184 # define HAS_FPU(sc) 0
186 # define PREPARE_FPU(cc) \
188 asm volatile("fninit\n\t" \
190 "fwait" : "=m" ((cc)->acc_u.acc_f4.fpstate) \
199 # define SAVE_FPU(cc,sc) \
203 # define RESTORE_FPU(cc,sc) \
207 # define HAS_FPU(sc) 0
209 # define PREPARE_FPU(cc) \
215 #define SETUP_EXCEPTION(sc,arg) \
217 _PUSH(GetSP(SysBase->ThisTask), arg); \
218 _PUSH(GetSP(SysBase->ThisTask), arg); \
221 #define PREPARE_INITIAL_FRAME(sp,startpc) \
223 GetCpuContext(task)->regs[7] = 0; \
224 GetCpuContext(task)->regs[8] = (startpc); \
227 #define PREPARE_INITIAL_CONTEXT(task,startpc) \
229 PREPARE_FPU(GetCpuContext(task)); \
232 #define SAVEREGS(task,sc) \
234 struct AROS_cpu_context *cc = GetCpuContext(task); \
235 SP_TYPE **sp = GetSP(task); \
236 *sp = (SP_TYPE *)SP(sc); \
241 cc->eflags = sc->sc_efl & PSL_USERCHANGE; \
244 #define RESTOREREGS(task,sc) \
246 struct AROS_cpu_context *cc = GetCpuContext(task); \
249 RESTORE_CPU(cc,sc); \
251 RESTORE_FPU(cc,sc); \
253 SP(sc) = (typeof(SP(sc))) *sp; \
254 sc->sc_efl = (sc->sc_efl & ~PSL_USERCHANGE) | cc->eflags; \
257 #define PRINT_SC(sc) \
258 printf (" SP=%08lx FP=%08lx PC=%08lx FPU=%s\n" \
259 " R0=%08lx R1=%08lx R2=%08lx R3=%08lx\n" \
260 " R4=%08lx R5=%08lx R6=%08lx\n" \
261 , SP(sc), FP(sc), PC(sc) \
262 , HAS_FPU(sc) ? "yes" : "no" \
263 , R0(sc), R1(sc), R2(sc), R3(sc) \
264 , R4(sc), R5(sc), R6(sc) \
267 #define PRINT_CPUCONTEXT(task) \
268 printf (" SP=%08lx FP=%08lx PC=%08lx\n" \
269 " R0=%08lx R1=%08lx R2=%08lx R3=%08lx\n" \
270 " R4=%08lx R5=%08lx R6=%08lx\n" \
271 , (ULONG)(*GetSP(task)) \
272 , GetCpuContext(task)->fp, \
273 , GetCpuContext(task)->pc, \
274 , GetCpuContext(task)->regs[0] \
275 , GetCpuContext(task)->regs[1] \
276 , GetCpuContext(task)->regs[2] \
277 , GetCpuContext(task)->regs[3] \
278 , GetCpuContext(task)->regs[4] \
279 , GetCpuContext(task)->regs[5] \
280 , GetCpuContext(task)->regs[6] \
283 #endif /* _SIGCORE_H */