void JvmtiEnvThreadState::clear_to_frame_pop(int frame_number)  {
#ifdef ASSERT
  uint32_t debug_bits = 0;
#endif
  assert(get_thread() == Thread::current() || JvmtiEnv::is_thread_fully_suspended(get_thread(), false, &debug_bits),
         "frame pop data only accessible from same thread or while suspended");
  JvmtiFramePop fpop(frame_number);
  JvmtiEventController::clear_to_frame_pop(this, fpop);
}
Exemple #2
0
/* Execute a NEXT statement. */
void next()
{
  struct for_stack i;

  i = fpop(); /* read the loop info */

  variables[i.var]++; /* increment control variable */
  if(variables[i.var]>i.target) return;  /* all done */
  fpush( &i );  /* otherwise, restore the info */
  prog = i.loc;  /* loop */
}
Exemple #3
0
static
void fallbackQSort3(UInt32 *fmap, UInt32 *eclass, Int32 loSt, Int32 hiSt)
{
    Int32  unLo, unHi, ltLo, gtHi, n, m;
    Int32  sp, lo, hi;
    UInt32 med, r, r3;
    Int32  stackLo[FALLBACK_QSORT_STACK_SIZE];
    Int32  stackHi[FALLBACK_QSORT_STACK_SIZE];

    r = 0;

    sp = 0;
    fpush(loSt, hiSt);

    while ( sp > 0 ) {
        AssertH(sp < FALLBACK_QSORT_STACK_SIZE - 1, 1004);

        fpop(lo, hi);
        if ( hi - lo < FALLBACK_QSORT_SMALL_THRESH ) {
            fallbackSimpleSort(fmap, eclass, lo, hi);
            continue;
        }

        /* Random partitioning.  Median of 3 sometimes fails to
         *  avoid bad cases.  Median of 9 seems to help but
         *  looks rather expensive.  This too seems to work but
         *  is cheaper.  Guidance for the magic constants
         *  7621 and 32768 is taken from Sedgewick's algorithms
         *  book, chapter 35.
         */
        r  = ( (r * 7621) + 1 ) % 32768;
        r3 = r % 3;
        if ( r3 == 0 ) {
            med = eclass[fmap[lo]];
        } else {
            if ( r3 == 1 ) {
                med = eclass[fmap[(lo + hi) >> 1]];
            } else {
                med = eclass[fmap[hi]];
            }
        }
Exemple #4
0
static
void fallbackQSort3 ( UInt32* fmap, 
                      UInt32* eclass,
                      Int32   loSt, 
                      Int32   hiSt )
{
   Int32 unLo, unHi, ltLo, gtHi, n, m;
   Int32 sp, lo, hi;
   UInt32 med, r, r3;
   Int32 stackLo[FALLBACK_QSORT_STACK_SIZE];
   Int32 stackHi[FALLBACK_QSORT_STACK_SIZE];

   r = 0;

   sp = 0;
   fpush ( loSt, hiSt );

   while (sp > 0) {

      AssertH ( sp < FALLBACK_QSORT_STACK_SIZE, 1004 );

      fpop ( lo, hi );
      if (hi - lo < FALLBACK_QSORT_SMALL_THRESH) {
         fallbackSimpleSort ( fmap, eclass, lo, hi );
         continue;
      }

      /* Random partitioning.  Median of 3 sometimes fails to
         avoid bad cases.  Median of 9 seems to help but 
         looks rather expensive.  This too seems to work but
         is cheaper.  Guidance for the magic constants 
         7621 and 32768 is taken from Sedgewick's algorithms
         book, chapter 35.
      */
      r = ((r * 7621) + 1) % 32768;
      r3 = r % 3;
      if (r3 == 0) med = eclass[fmap[lo]]; else
      if (r3 == 1) med = eclass[fmap[(lo+hi)>>1]]; else
                   med = eclass[fmap[hi]];

      unLo = ltLo = lo;
      unHi = gtHi = hi;

      while (1) {
         while (1) {
            if (unLo > unHi) break;
            n = (Int32)eclass[fmap[unLo]] - (Int32)med;
            if (n == 0) { 
               fswap(fmap[unLo], fmap[ltLo]); 
               ltLo++; unLo++; 
               continue; 
            };
            if (n > 0) break;
            unLo++;
         }
         while (1) {
            if (unLo > unHi) break;
            n = (Int32)eclass[fmap[unHi]] - (Int32)med;
            if (n == 0) { 
               fswap(fmap[unHi], fmap[gtHi]); 
               gtHi--; unHi--; 
               continue; 
            };
            if (n < 0) break;
            unHi--;
         }
         if (unLo > unHi) break;
         fswap(fmap[unLo], fmap[unHi]); unLo++; unHi--;
      }

      AssertD ( unHi == unLo-1, "fallbackQSort3(2)" );

      if (gtHi < ltLo) continue;

      n = fmin(ltLo-lo, unLo-ltLo); fvswap(lo, unLo-n, n);
      m = fmin(hi-gtHi, gtHi-unHi); fvswap(unLo, hi-m+1, m);

      n = lo + unLo - ltLo - 1;
      m = hi - (gtHi - unHi) + 1;

      if (n - lo > hi - m) {
         fpush ( lo, n );
         fpush ( m, hi );
      } else {
         fpush ( m, hi );
         fpush ( lo, n );
      }
   }
void LIR_Assembler::emit_op0(LIR_Op0* op) {
    switch (op->code()) {
    case lir_word_align: {
        _masm->align(BytesPerWord);
        break;
    }

    case lir_nop:
        assert(op->info() == NULL, "not supported");
        _masm->nop();
        break;

    case lir_label:
        Unimplemented();
        break;

    case lir_build_frame:
        build_frame();
        break;

    case lir_std_entry:
        // init offsets
        offsets()->set_value(CodeOffsets::OSR_Entry, _masm->offset());
        _masm->align(CodeEntryAlignment);
        if (needs_icache(compilation()->method())) {
            check_icache();
        }
        offsets()->set_value(CodeOffsets::Verified_Entry, _masm->offset());
        _masm->verified_entry();
        build_frame();
        offsets()->set_value(CodeOffsets::Frame_Complete, _masm->offset());
        break;

    case lir_osr_entry:
        offsets()->set_value(CodeOffsets::OSR_Entry, _masm->offset());
        osr_entry();
        break;

    case lir_24bit_FPU:
        set_24bit_FPU();
        break;

    case lir_reset_FPU:
        reset_FPU();
        break;

    case lir_breakpoint:
        breakpoint();
        break;

    case lir_fpop_raw:
        fpop();
        break;

    case lir_membar:
        membar();
        break;

    case lir_membar_acquire:
        membar_acquire();
        break;

    case lir_membar_release:
        membar_release();
        break;

    case lir_membar_loadload:
        membar_loadload();
        break;

    case lir_membar_storestore:
        membar_storestore();
        break;

    case lir_membar_loadstore:
        membar_loadstore();
        break;

    case lir_membar_storeload:
        membar_storeload();
        break;

    case lir_get_thread:
        get_thread(op->result_opr());
        break;

    default:
        ShouldNotReachHere();
        break;
    }
}
static void do_emu(struct info * info)
{
	unsigned short code;
	temp_real tmp;
	char * address;

	if (I387.cwd & I387.swd & 0x3f)
		I387.swd |= 0x8000;
	else
		I387.swd &= 0x7fff;
	ORIG_EIP = EIP;
/* 0x0007 means user code space */
	if (CS != 0x000F) {
		printk("math_emulate: %04x:%08x\n\r",CS,EIP);
		panic("Math emulation needed in kernel");
	}
	code = get_fs_word((unsigned short *) EIP);
	bswapw(code);
	code &= 0x7ff;
	I387.fip = EIP;
	*(unsigned short *) &I387.fcs = CS;
	*(1+(unsigned short *) &I387.fcs) = code;
	EIP += 2;
	switch (code) {
		case 0x1d0: /* fnop */
			return;
		case 0x1d1: case 0x1d2: case 0x1d3:
		case 0x1d4: case 0x1d5: case 0x1d6: case 0x1d7:
			math_abort(info,1<<(SIGILL-1));
		case 0x1e0:
			ST(0).exponent ^= 0x8000;
			return;
		case 0x1e1:
			ST(0).exponent &= 0x7fff;
			return;
		case 0x1e2: case 0x1e3:
			math_abort(info,1<<(SIGILL-1));
		case 0x1e4:
			ftst(PST(0));
			return;
		case 0x1e5:
			printk("fxam not implemented\n\r");
			math_abort(info,1<<(SIGILL-1));
		case 0x1e6: case 0x1e7:
			math_abort(info,1<<(SIGILL-1));
		case 0x1e8:
			fpush();
			ST(0) = CONST1;
			return;
		case 0x1e9:
			fpush();
			ST(0) = CONSTL2T;
			return;
		case 0x1ea:
			fpush();
			ST(0) = CONSTL2E;
			return;
		case 0x1eb:
			fpush();
			ST(0) = CONSTPI;
			return;
		case 0x1ec:
			fpush();
			ST(0) = CONSTLG2;
			return;
		case 0x1ed:
			fpush();
			ST(0) = CONSTLN2;
			return;
		case 0x1ee:
			fpush();
			ST(0) = CONSTZ;
			return;
		case 0x1ef:
			math_abort(info,1<<(SIGILL-1));
		case 0x1f0: case 0x1f1: case 0x1f2: case 0x1f3:
		case 0x1f4: case 0x1f5: case 0x1f6: case 0x1f7:
		case 0x1f8: case 0x1f9: case 0x1fa: case 0x1fb:
		case 0x1fc: case 0x1fd: case 0x1fe: case 0x1ff:
			printk("%04x fxxx not implemented\n\r",code + 0xc800);
			math_abort(info,1<<(SIGILL-1));
		case 0x2e9:
			fucom(PST(1),PST(0));
			fpop(); fpop();
			return;
		case 0x3d0: case 0x3d1:
			return;
		case 0x3e2:
			I387.swd &= 0x7f00;
			return;
		case 0x3e3:
			I387.cwd = 0x037f;
			I387.swd = 0x0000;
			I387.twd = 0x0000;
			return;
		case 0x3e4:
			return;
		case 0x6d9:
			fcom(PST(1),PST(0));
			fpop(); fpop();
			return;
		case 0x7e0:
			*(short *) &EAX = I387.swd;
			return;
	}
	switch (code >> 3) {
		case 0x18:
			fadd(PST(0),PST(code & 7),&tmp);
			real_to_real(&tmp,&ST(0));
			return;
		case 0x19:
			fmul(PST(0),PST(code & 7),&tmp);
			real_to_real(&tmp,&ST(0));
			return;
		case 0x1a:
			fcom(PST(code & 7),&tmp);
			real_to_real(&tmp,&ST(0));
			return;
		case 0x1b:
			fcom(PST(code & 7),&tmp);
			real_to_real(&tmp,&ST(0));
			fpop();
			return;
		case 0x1c:
			real_to_real(&ST(code & 7),&tmp);
			tmp.exponent ^= 0x8000;
			fadd(PST(0),&tmp,&tmp);
			real_to_real(&tmp,&ST(0));
			return;
		case 0x1d:
			ST(0).exponent ^= 0x8000;
			fadd(PST(0),PST(code & 7),&tmp);
			real_to_real(&tmp,&ST(0));
			return;
		case 0x1e:
			fdiv(PST(0),PST(code & 7),&tmp);
			real_to_real(&tmp,&ST(0));
			return;
		case 0x1f:
			fdiv(PST(code & 7),PST(0),&tmp);
			real_to_real(&tmp,&ST(0));
			return;
		case 0x38:
			fpush();
			ST(0) = ST((code & 7)+1);
			return;
		case 0x39:
			fxchg(&ST(0),&ST(code & 7));
			return;
		case 0x3b:
			ST(code & 7) = ST(0);
			fpop();
			return;
		case 0x98:
			fadd(PST(0),PST(code & 7),&tmp);
			real_to_real(&tmp,&ST(code & 7));
			return;
		case 0x99:
			fmul(PST(0),PST(code & 7),&tmp);
			real_to_real(&tmp,&ST(code & 7));
			return;
		case 0x9a:
			fcom(PST(code & 7),PST(0));
			return;
		case 0x9b:
			fcom(PST(code & 7),PST(0));
			fpop();
			return;			
		case 0x9c:
			ST(code & 7).exponent ^= 0x8000;
			fadd(PST(0),PST(code & 7),&tmp);
			real_to_real(&tmp,&ST(code & 7));
			return;
		case 0x9d:
			real_to_real(&ST(0),&tmp);
			tmp.exponent ^= 0x8000;
			fadd(PST(code & 7),&tmp,&tmp);
			real_to_real(&tmp,&ST(code & 7));
			return;
		case 0x9e:
			fdiv(PST(0),PST(code & 7),&tmp);
			real_to_real(&tmp,&ST(code & 7));
			return;
		case 0x9f:
			fdiv(PST(code & 7),PST(0),&tmp);
			real_to_real(&tmp,&ST(code & 7));
			return;
		case 0xb8:
			printk("ffree not implemented\n\r");
			math_abort(info,1<<(SIGILL-1));
		case 0xb9:
			fxchg(&ST(0),&ST(code & 7));
			return;
		case 0xba:
			ST(code & 7) = ST(0);
			return;
		case 0xbb:
			ST(code & 7) = ST(0);
			fpop();
			return;
		case 0xbc:
			fucom(PST(code & 7),PST(0));
			return;
		case 0xbd:
			fucom(PST(code & 7),PST(0));
			fpop();
			return;
		case 0xd8:
			fadd(PST(code & 7),PST(0),&tmp);
			real_to_real(&tmp,&ST(code & 7));
			fpop();
			return;
		case 0xd9:
			fmul(PST(code & 7),PST(0),&tmp);
			real_to_real(&tmp,&ST(code & 7));
			fpop();
			return;
		case 0xda:
			fcom(PST(code & 7),PST(0));
			fpop();
			return;
		case 0xdc:
			ST(code & 7).exponent ^= 0x8000;
			fadd(PST(0),PST(code & 7),&tmp);
			real_to_real(&tmp,&ST(code & 7));
			fpop();
			return;
		case 0xdd:
			real_to_real(&ST(0),&tmp);
			tmp.exponent ^= 0x8000;
			fadd(PST(code & 7),&tmp,&tmp);
			real_to_real(&tmp,&ST(code & 7));
			fpop();
			return;
		case 0xde:
			fdiv(PST(0),PST(code & 7),&tmp);
			real_to_real(&tmp,&ST(code & 7));
			fpop();
			return;
		case 0xdf:
			fdiv(PST(code & 7),PST(0),&tmp);
			real_to_real(&tmp,&ST(code & 7));
			fpop();
			return;
		case 0xf8:
			printk("ffree not implemented\n\r");
			math_abort(info,1<<(SIGILL-1));
			fpop();
			return;
		case 0xf9:
			fxchg(&ST(0),&ST(code & 7));
			return;
		case 0xfa:
		case 0xfb:
			ST(code & 7) = ST(0);
			fpop();
			return;
	}
	switch ((code>>3) & 0xe7) {
		case 0x22:
			put_short_real(PST(0),info,code);
			return;
		case 0x23:
			put_short_real(PST(0),info,code);
			fpop();
			return;
		case 0x24:
			address = ea(info,code);
			for (code = 0 ; code < 7 ; code++) {
				((long *) & I387)[code] =
				   get_fs_long((unsigned long *) address);
				address += 4;
			}
			return;
		case 0x25:
			address = ea(info,code);
			*(unsigned short *) &I387.cwd =
				get_fs_word((unsigned short *) address);
			return;
		case 0x26:
			address = ea(info,code);
			verify_area(address,28);
			for (code = 0 ; code < 7 ; code++) {
				put_fs_long( ((long *) & I387)[code],
					(unsigned long *) address);
				address += 4;
			}
			return;
		case 0x27:
			address = ea(info,code);
			verify_area(address,2);
			put_fs_word(I387.cwd,(short *) address);
			return;
		case 0x62:
			put_long_int(PST(0),info,code);
			return;
		case 0x63:
			put_long_int(PST(0),info,code);
			fpop();
			return;
		case 0x65:
			fpush();
			get_temp_real(&tmp,info,code);
			real_to_real(&tmp,&ST(0));
			return;
		case 0x67:
			put_temp_real(PST(0),info,code);
			fpop();
			return;
		case 0xa2:
			put_long_real(PST(0),info,code);
			return;
		case 0xa3:
			put_long_real(PST(0),info,code);
			fpop();
			return;
		case 0xa4:
			address = ea(info,code);
			for (code = 0 ; code < 27 ; code++) {
				((long *) & I387)[code] =
				   get_fs_long((unsigned long *) address);
				address += 4;
			}
			return;
		case 0xa6:
			address = ea(info,code);
			verify_area(address,108);
			for (code = 0 ; code < 27 ; code++) {
				put_fs_long( ((long *) & I387)[code],
					(unsigned long *) address);
				address += 4;
			}
			I387.cwd = 0x037f;
			I387.swd = 0x0000;
			I387.twd = 0x0000;
			return;
		case 0xa7:
			address = ea(info,code);
			verify_area(address,2);
			put_fs_word(I387.swd,(short *) address);
			return;
		case 0xe2:
			put_short_int(PST(0),info,code);
			return;
		case 0xe3:
			put_short_int(PST(0),info,code);
			fpop();
			return;
		case 0xe4:
			fpush();
			get_BCD(&tmp,info,code);
			real_to_real(&tmp,&ST(0));
			return;
		case 0xe5:
			fpush();
			get_longlong_int(&tmp,info,code);
			real_to_real(&tmp,&ST(0));
			return;
		case 0xe6:
			put_BCD(PST(0),info,code);
			fpop();
			return;
		case 0xe7:
			put_longlong_int(PST(0),info,code);
			fpop();
			return;
	}
	switch (code >> 9) {
		case 0:
			get_short_real(&tmp,info,code);
			break;
		case 1:
			get_long_int(&tmp,info,code);
			break;
		case 2:
			get_long_real(&tmp,info,code);
			break;
		case 4:
			get_short_int(&tmp,info,code);
	}
	switch ((code>>3) & 0x27) {
		case 0:
			fadd(&tmp,PST(0),&tmp);
			real_to_real(&tmp,&ST(0));
			return;
		case 1:
			fmul(&tmp,PST(0),&tmp);
			real_to_real(&tmp,&ST(0));
			return;
		case 2:
			fcom(&tmp,PST(0));
			return;
		case 3:
			fcom(&tmp,PST(0));
			fpop();
			return;
		case 4:
			tmp.exponent ^= 0x8000;
			fadd(&tmp,PST(0),&tmp);
			real_to_real(&tmp,&ST(0));
			return;
		case 5:
			ST(0).exponent ^= 0x8000;
			fadd(&tmp,PST(0),&tmp);
			real_to_real(&tmp,&ST(0));
			return;
		case 6:
			fdiv(PST(0),&tmp,&tmp);
			real_to_real(&tmp,&ST(0));
			return;
		case 7:
			fdiv(&tmp,PST(0),&tmp);
			real_to_real(&tmp,&ST(0));
			return;
	}
	if ((code & 0x138) == 0x100) {
			fpush();
			real_to_real(&tmp,&ST(0));
			return;
	}
	printk("Unknown math-insns: %04x:%08x %04x\n\r",CS,EIP,code);
	math_abort(info,1<<(SIGFPE-1));
}
Exemple #7
0
static int
math_emulate(struct trapframe * info)
{
	unsigned short code;
	temp_real tmp;
	char * address;
	u_long oldeip;

	/* ever used fp? */
	if ((((struct pcb *)curproc->p_addr)->pcb_flags & FP_SOFTFP) == 0) {
		((struct pcb *)curproc->p_addr)->pcb_flags |= FP_SOFTFP;
		I387.cwd = 0x037f;
		I387.swd = 0x0000;
		I387.twd = 0x0000;
	}

	if (I387.cwd & I387.swd & 0x3f)
		I387.swd |= 0x8000;
	else
		I387.swd &= 0x7fff;
	oldeip = info->tf_eip;
/* 0x001f means user code space */
	if ((u_short)info->tf_cs != 0x001F) {
		printf("math_emulate: %04x:%08lx\n", (u_short)info->tf_cs,
			oldeip);
		panic("?Math emulation needed in kernel?");
	}
	code = get_fs_word((unsigned short *) oldeip);
	bswapw(code);
	code &= 0x7ff;
	I387.fip = oldeip;
	*(unsigned short *) &I387.fcs = (u_short) info->tf_cs;
	*(1+(unsigned short *) &I387.fcs) = code;
	info->tf_eip += 2;
	switch (code) {
		case 0x1d0: /* fnop */
			return(0);
		case 0x1d1: case 0x1d2: case 0x1d3:  /* fst to 32-bit mem */
		case 0x1d4: case 0x1d5: case 0x1d6: case 0x1d7:
			math_abort(info,SIGILL);
		case 0x1e0: /* fchs */
			ST(0).exponent ^= 0x8000;
			return(0);
		case 0x1e1: /* fabs */
			ST(0).exponent &= 0x7fff;
			return(0);
		case 0x1e2: case 0x1e3:
			math_abort(info,SIGILL);
		case 0x1e4: /* ftst */
			ftst(PST(0));
			return(0);
		case 0x1e5: /* fxam */
			printf("fxam not implemented\n");
			math_abort(info,SIGILL);
		case 0x1e6: case 0x1e7: /* fldenv */
			math_abort(info,SIGILL);
		case 0x1e8: /* fld1 */
			fpush();
			ST(0) = CONST1;
			return(0);
		case 0x1e9: /* fld2t */
			fpush();
			ST(0) = CONSTL2T;
			return(0);
		case 0x1ea: /* fld2e */
			fpush();
			ST(0) = CONSTL2E;
			return(0);
		case 0x1eb: /* fldpi */
			fpush();
			ST(0) = CONSTPI;
			return(0);
		case 0x1ec: /* fldlg2 */
			fpush();
			ST(0) = CONSTLG2;
			return(0);
		case 0x1ed: /* fldln2 */
			fpush();
			ST(0) = CONSTLN2;
			return(0);
		case 0x1ee: /* fldz */
			fpush();
			ST(0) = CONSTZ;
			return(0);
		case 0x1ef:
			math_abort(info,SIGILL);
		case 0x1f0: /* f2xm1 */
		case 0x1f1: /* fyl2x */
		case 0x1f2: /* fptan */
		case 0x1f3: /* fpatan */
		case 0x1f4: /* fxtract */
		case 0x1f5: /* fprem1 */
		case 0x1f6: /* fdecstp */
		case 0x1f7: /* fincstp */
		case 0x1f8: /* fprem */
		case 0x1f9: /* fyl2xp1 */
		case 0x1fa: /* fsqrt */
		case 0x1fb: /* fsincos */
		case 0x1fe: /* fsin */
		case 0x1ff: /* fcos */
			uprintf(
			 "math_emulate: instruction %04x not implemented\n",
			  code + 0xd800);
			math_abort(info,SIGILL);
		case 0x1fc: /* frndint */
			frndint(PST(0),&tmp);
			real_to_real(&tmp,&ST(0));
			return(0);
		case 0x1fd: /* fscale */
			/* incomplete and totally inadequate -wfj */
			Fscale(PST(0), PST(1), &tmp);
			real_to_real(&tmp,&ST(0));
			return(0);			/* 19 Sep 92*/
		case 0x2e9: /* ????? */
/* if this should be a fucomp ST(0),ST(1) , it must be a 0x3e9  ATS */
			fucom(PST(1),PST(0));
			fpop(); fpop();
			return(0);
		case 0x3d0: case 0x3d1: /* fist ?? */
			return(0);
		case 0x3e2: /* fclex */
			I387.swd &= 0x7f00;
			return(0);
		case 0x3e3: /* fninit */
			I387.cwd = 0x037f;
			I387.swd = 0x0000;
			I387.twd = 0x0000;
			return(0);
		case 0x3e4:
			return(0);
		case 0x6d9: /* fcompp */
			fcom(PST(1),PST(0));
			fpop(); fpop();
			return(0);
		case 0x7e0: /* fstsw ax */
			*(short *) &info->tf_eax = I387.swd;
			return(0);
	}
	switch (code >> 3) {
		case 0x18: /* fadd */
			fadd(PST(0),PST(code & 7),&tmp);
			real_to_real(&tmp,&ST(0));
			return(0);
		case 0x19: /* fmul */
			fmul(PST(0),PST(code & 7),&tmp);
			real_to_real(&tmp,&ST(0));
			return(0);
		case 0x1a: /* fcom */
			fcom(PST(code & 7),PST(0));
			return(0);
		case 0x1b: /* fcomp */
			fcom(PST(code & 7),PST(0));
			fpop();
			return(0);
		case 0x1c: /* fsubr */
			real_to_real(&ST(code & 7),&tmp);
			tmp.exponent ^= 0x8000;
			fadd(PST(0),&tmp,&tmp);
			real_to_real(&tmp,&ST(0));
			return(0);
		case 0x1d: /* fsub */
			ST(0).exponent ^= 0x8000;
			fadd(PST(0),PST(code & 7),&tmp);
			real_to_real(&tmp,&ST(0));
			return(0);
		case 0x1e: /* fdivr */
			fdiv(PST(0),PST(code & 7),&tmp);
			real_to_real(&tmp,&ST(0));
			return(0);
		case 0x1f: /* fdiv */
			fdiv(PST(code & 7),PST(0),&tmp);
			real_to_real(&tmp,&ST(0));
			return(0);
		case 0x38: /* fld */
			fpush();
			ST(0) = ST((code & 7)+1);  /* why plus 1 ????? ATS */
			return(0);
		case 0x39: /* fxch */
			fxchg(&ST(0),&ST(code & 7));
			return(0);
		case 0x3b: /*  ??? ??? wrong ???? ATS */
			ST(code & 7) = ST(0);
			fpop();
			return(0);
		case 0x98: /* fadd */
			fadd(PST(0),PST(code & 7),&tmp);
			real_to_real(&tmp,&ST(code & 7));
			return(0);
		case 0x99: /* fmul */
			fmul(PST(0),PST(code & 7),&tmp);
			real_to_real(&tmp,&ST(code & 7));
			return(0);
		case 0x9a: /* ???? , my manual don't list a direction bit
for fcom , ??? ATS */
			fcom(PST(code & 7),PST(0));
			return(0);
		case 0x9b: /* same as above , ATS */
			fcom(PST(code & 7),PST(0));
			fpop();
			return(0);
		case 0x9c: /* fsubr */
			ST(code & 7).exponent ^= 0x8000;
			fadd(PST(0),PST(code & 7),&tmp);
			real_to_real(&tmp,&ST(code & 7));
			return(0);
		case 0x9d: /* fsub */
			real_to_real(&ST(0),&tmp);
			tmp.exponent ^= 0x8000;
			fadd(PST(code & 7),&tmp,&tmp);
			real_to_real(&tmp,&ST(code & 7));
			return(0);
		case 0x9e: /* fdivr */
			fdiv(PST(0),PST(code & 7),&tmp);
			real_to_real(&tmp,&ST(code & 7));
			return(0);
		case 0x9f: /* fdiv */
			fdiv(PST(code & 7),PST(0),&tmp);
			real_to_real(&tmp,&ST(code & 7));
			return(0);
		case 0xb8: /* ffree */
			printf("ffree not implemented\n");
			math_abort(info,SIGILL);
		case 0xb9: /* fstp ???? where is the pop ? ATS */
			fxchg(&ST(0),&ST(code & 7));
			return(0);
		case 0xba: /* fst */
			ST(code & 7) = ST(0);
			return(0);
		case 0xbb: /* ????? encoding of fstp to mem ? ATS */
			ST(code & 7) = ST(0);
			fpop();
			return(0);
		case 0xbc: /* fucom */
			fucom(PST(code & 7),PST(0));
			return(0);
		case 0xbd: /* fucomp */
			fucom(PST(code & 7),PST(0));
			fpop();
			return(0);
		case 0xd8: /* faddp */
			fadd(PST(code & 7),PST(0),&tmp);
			real_to_real(&tmp,&ST(code & 7));
			fpop();
			return(0);
		case 0xd9: /* fmulp */
			fmul(PST(code & 7),PST(0),&tmp);
			real_to_real(&tmp,&ST(code & 7));
			fpop();
			return(0);
		case 0xda: /* ??? encoding of ficom with 16 bit mem ? ATS */
			fcom(PST(code & 7),PST(0));
			fpop();
			return(0);
		case 0xdc: /* fsubrp */
			ST(code & 7).exponent ^= 0x8000;
			fadd(PST(0),PST(code & 7),&tmp);
			real_to_real(&tmp,&ST(code & 7));
			fpop();
			return(0);
		case 0xdd: /* fsubp */
			real_to_real(&ST(0),&tmp);
			tmp.exponent ^= 0x8000;
			fadd(PST(code & 7),&tmp,&tmp);
			real_to_real(&tmp,&ST(code & 7));
			fpop();
			return(0);
		case 0xde: /* fdivrp */
			fdiv(PST(0),PST(code & 7),&tmp);
			real_to_real(&tmp,&ST(code & 7));
			fpop();
			return(0);
		case 0xdf: /* fdivp */
			fdiv(PST(code & 7),PST(0),&tmp);
			real_to_real(&tmp,&ST(code & 7));
			fpop();
			return(0);
		case 0xf8: /* fild 16-bit mem ???? ATS */
			printf("ffree not implemented\n");
			math_abort(info,SIGILL);
			fpop();
			return(0);
		case 0xf9: /*  ????? ATS */
			fxchg(&ST(0),&ST(code & 7));
			return(0);
		case 0xfa: /* fist 16-bit mem ? ATS */
		case 0xfb: /* fistp 16-bit mem ? ATS */
			ST(code & 7) = ST(0);
			fpop();
			return(0);
	}
	switch ((code>>3) & 0xe7) {
		case 0x22:
			put_short_real(PST(0),info,code);
			return(0);
		case 0x23:
			put_short_real(PST(0),info,code);
			fpop();
			return(0);
		case 0x24:
			address = ea(info,code);
			for (code = 0 ; code < 7 ; code++) {
				((long *) & I387)[code] =
				   get_fs_long((unsigned long *) address);
				address += 4;
			}
			return(0);
		case 0x25:
			address = ea(info,code);
			*(unsigned short *) &I387.cwd =
				get_fs_word((unsigned short *) address);
			return(0);
		case 0x26:
			address = ea(info,code);
			/*verify_area(address,28);*/
			for (code = 0 ; code < 7 ; code++) {
				put_fs_long( ((long *) & I387)[code],
					(unsigned long *) address);
				address += 4;
			}
			return(0);
		case 0x27:
			address = ea(info,code);
			/*verify_area(address,2);*/
			put_fs_word(I387.cwd,(short *) address);
			return(0);
		case 0x62:
			put_long_int(PST(0),info,code);
			return(0);
		case 0x63:
			put_long_int(PST(0),info,code);
			fpop();
			return(0);
		case 0x65:
			fpush();
			get_temp_real(&tmp,info,code);
			real_to_real(&tmp,&ST(0));
			return(0);
		case 0x67:
			put_temp_real(PST(0),info,code);
			fpop();
			return(0);
		case 0xa2:
			put_long_real(PST(0),info,code);
			return(0);
		case 0xa3:
			put_long_real(PST(0),info,code);
			fpop();
			return(0);
		case 0xa4:
			address = ea(info,code);
			for (code = 0 ; code < 27 ; code++) {
				((long *) & I387)[code] =
				   get_fs_long((unsigned long *) address);
				address += 4;
			}
			return(0);
		case 0xa6:
			address = ea(info,code);
			/*verify_area(address,108);*/
			for (code = 0 ; code < 27 ; code++) {
				put_fs_long( ((long *) & I387)[code],
					(unsigned long *) address);
				address += 4;
			}
			I387.cwd = 0x037f;
			I387.swd = 0x0000;
			I387.twd = 0x0000;
			return(0);
		case 0xa7:
			address = ea(info,code);
			/*verify_area(address,2);*/
			put_fs_word(I387.swd,(short *) address);
			return(0);
		case 0xe2:
			put_short_int(PST(0),info,code);
			return(0);
		case 0xe3:
			put_short_int(PST(0),info,code);
			fpop();
			return(0);
		case 0xe4:
			fpush();
			get_BCD(&tmp,info,code);
			real_to_real(&tmp,&ST(0));
			return(0);
		case 0xe5:
			fpush();
			get_longlong_int(&tmp,info,code);
			real_to_real(&tmp,&ST(0));
			return(0);
		case 0xe6:
			put_BCD(PST(0),info,code);
			fpop();
			return(0);
		case 0xe7:
			put_longlong_int(PST(0),info,code);
			fpop();
			return(0);
	}
	switch (code >> 9) {
		case 0:
			get_short_real(&tmp,info,code);
			break;
		case 1:
			get_long_int(&tmp,info,code);
			break;
		case 2:
			get_long_real(&tmp,info,code);
			break;
		case 4:
			get_short_int(&tmp,info,code);
	}
	switch ((code>>3) & 0x27) {
		case 0:
			fadd(&tmp,PST(0),&tmp);
			real_to_real(&tmp,&ST(0));
			return(0);
		case 1:
			fmul(&tmp,PST(0),&tmp);
			real_to_real(&tmp,&ST(0));
			return(0);
		case 2:
			fcom(&tmp,PST(0));
			return(0);
		case 3:
			fcom(&tmp,PST(0));
			fpop();
			return(0);
		case 4:
			tmp.exponent ^= 0x8000;
			fadd(&tmp,PST(0),&tmp);
			real_to_real(&tmp,&ST(0));
			return(0);
		case 5:
			ST(0).exponent ^= 0x8000;
			fadd(&tmp,PST(0),&tmp);
			real_to_real(&tmp,&ST(0));
			return(0);
		case 6:
			fdiv(PST(0),&tmp,&tmp);
			real_to_real(&tmp,&ST(0));
			return(0);
		case 7:
			fdiv(&tmp,PST(0),&tmp);
			real_to_real(&tmp,&ST(0));
			return(0);
	}
	if ((code & 0x138) == 0x100) {
			fpush();
			real_to_real(&tmp,&ST(0));
			return(0);
	}
	printf("Unknown math-insns: %04x:%08x %04x\n",(u_short)info->tf_cs,
		info->tf_eip,code);
	math_abort(info,SIGFPE);
}