vlen = *(char*)(*os_context_pc_addr(context))++;
/* Skip Lisp error arg data bytes. */
while (vlen-- > 0) {
- ( (char*)(*os_context_pc_addr(context)) )++;
+ ++*os_context_pc_addr(context);
}
break;
int code = info->si_code;
os_context_t *context = (os_context_t*)void_context;
unsigned int trap;
- sigset_t ss;
if (single_stepping && (signal==SIGTRAP))
{
case trap_PendingInterrupt:
FSHOW((stderr, "/<trap pending interrupt>\n"));
arch_skip_instruction(context);
- sigemptyset(&ss);
- sigaddset(&ss,SIGTRAP);
- sigprocmask(SIG_UNBLOCK,&ss,0);
interrupt_handle_pending(context);
break;
break;
case trap_Breakpoint:
- (char*)(*os_context_pc_addr(context)) -= 1;
+ --*os_context_pc_addr(context);
handle_breakpoint(signal, info, context);
break;
case trap_FunEndBreakpoint:
- (char*)(*os_context_pc_addr(context)) -= 1;
+ --*os_context_pc_addr(context);
*os_context_pc_addr(context) =
(unsigned long)handle_fun_end_breakpoint(signal, info, context);
break;
}
#endif
+
+/* These setup and check *both* the sse2 and x87 FPUs. While lisp code
+ only uses the sse2 FPU, other code (such as libc) may use the x87 FPU.
+ */
+
+unsigned int
+arch_get_fp_modes()
+{
+ unsigned int temp;
+ unsigned int result;
+ /* return the x87 exception flags ored in with the sse2
+ * control+status flags */
+ asm ("fnstsw %0" : "=m" (temp));
+ result = temp;
+ result &= 0x3F;
+ asm ("stmxcsr %0" : "=m" (temp));
+ result |= temp;
+ /* flip exception mask bits */
+ return result ^ (0x3F << 7);
+}
+
+struct fpenv
+{
+ unsigned short cw;
+ unsigned short unused1;
+ unsigned short sw;
+ unsigned short unused2;
+ unsigned int other_regs[5];
+};
+
+void
+arch_set_fp_modes(unsigned int mxcsr)
+{
+ struct fpenv f_env;
+ unsigned int temp;
+
+ /* turn trap enable bits into exception mask */
+ mxcsr ^= 0x3F << 7;
+
+ /* set x87 modes */
+ asm ("fnstenv %0" : "=m" (f_env));
+ /* set control word: always long double precision
+ * get traps and rounding from mxcsr word */
+ f_env.cw = 0x300 | ((mxcsr >> 7) & 0x3F) | (((mxcsr >> 13) & 0x3) << 10);
+ /* set status word: only override exception flags, from mxcsr */
+ f_env.sw &= ~0x3F;
+ f_env.sw |= (mxcsr & 0x3F);
+
+ asm ("fldenv %0" : : "m" (f_env));
+
+ /* now, simply, load up the mxcsr register */
+ temp = mxcsr;
+ asm ("ldmxcsr %0" : : "m" (temp));
+}