|
|
1.1 ! root 1: /*---------------------------------------------------------------------------+ ! 2: | fpu_aux.c | ! 3: | | ! 4: | Code to implement some of the FPU auxiliary instructions. | ! 5: | | ! 6: | Copyright (C) 1992 W. Metzenthen, 22 Parker St, Ormond, Vic 3163, | ! 7: | Australia. E-mail [email protected] | ! 8: | | ! 9: | | ! 10: +---------------------------------------------------------------------------*/ ! 11: ! 12: #include "fpu_system.h" ! 13: #include "exception.h" ! 14: #include "fpu_emu.h" ! 15: #include "status_w.h" ! 16: ! 17: ! 18: ! 19: static void fclex() ! 20: { ! 21: status_word &= ~(SW_B|SW_ES|SW_SF|SW_PE|SW_UE|SW_OE|SW_ZE|SW_DE|SW_IE); ! 22: FPU_entry_eip = ip_offset; /* We want no net effect */ ! 23: } ! 24: ! 25: /* Needs to be externally visible */ ! 26: void finit_instr() ! 27: { ! 28: int r; ! 29: control_word = 0x037f; ! 30: status_word = 0; ! 31: ip_offset = cs_selector = 0; ! 32: data_operand_offset = operand_selector = 0; ! 33: top = 0; ! 34: for (r = 0; r < 8; r++) ! 35: { ! 36: fpregs[r].sign = 0; ! 37: fpregs[r].tag = TW_Empty; ! 38: fpregs[r].exp = 0; ! 39: fpregs[r].sigh = 0; ! 40: fpregs[r].sigl = 0; ! 41: } ! 42: } ! 43: ! 44: static FUNC finit_table[] = { ! 45: Un_impl, Un_impl, fclex, finit_instr, Un_impl, Un_impl, Un_impl, Un_impl ! 46: }; ! 47: ! 48: void finit_() ! 49: { ! 50: (finit_table[FPU_rm])(); ! 51: } ! 52: ! 53: ! 54: static void fstsw_ax() ! 55: { ! 56: ! 57: status_word &= ~SW_TOP; ! 58: status_word |= (top&7) << SW_TOPS; ! 59: ! 60: *(short *) &FPU_EAX = status_word; ! 61: ! 62: } ! 63: ! 64: static FUNC fstsw_table[] = { ! 65: fstsw_ax, Un_impl, Un_impl, Un_impl, Un_impl, Un_impl, Un_impl, Un_impl ! 66: }; ! 67: ! 68: void fstsw_() ! 69: { ! 70: (fstsw_table[FPU_rm])(); ! 71: } ! 72: ! 73: ! 74: ! 75: static void fnop() ! 76: { ! 77: } ! 78: ! 79: FUNC fp_nop_table[] = { ! 80: fnop, Un_impl, Un_impl, Un_impl, Un_impl, Un_impl, Un_impl, Un_impl ! 81: }; ! 82: ! 83: void fp_nop() ! 84: { ! 85: (fp_nop_table[FPU_rm])(); ! 86: } ! 87: ! 88: ! 89: void fld_i_() ! 90: { ! 91: FPU_REG *st_new_ptr; ! 92: ! 93: if ( STACK_OVERFLOW ) ! 94: { stack_overflow(); return; } ! 95: ! 96: /* fld st(i) */ ! 97: if ( NOT_EMPTY(FPU_rm) ) ! 98: { reg_move(&st(FPU_rm), st_new_ptr); push(); } ! 99: else ! 100: { ! 101: if ( control_word & EX_Invalid ) ! 102: { ! 103: /* The masked response */ ! 104: push(); ! 105: stack_underflow(); ! 106: } ! 107: else ! 108: EXCEPTION(EX_StackUnder); ! 109: } ! 110: ! 111: } ! 112: ! 113: ! 114: void fxch_i() ! 115: { ! 116: /* fxch st(i) */ ! 117: FPU_REG t; ! 118: register FPU_REG *sti_ptr = &st(FPU_rm); ! 119: reg_move(FPU_st0_ptr, &t); ! 120: reg_move(sti_ptr, FPU_st0_ptr); ! 121: reg_move(&t, sti_ptr); ! 122: } ! 123: ! 124: ! 125: void ffree_() ! 126: { ! 127: /* ffree st(i) */ ! 128: st(FPU_rm).tag = TW_Empty; ! 129: } ! 130: ! 131: ! 132: void fst_i_() ! 133: { ! 134: /* fst st(i) */ ! 135: reg_move(FPU_st0_ptr, &st(FPU_rm)); ! 136: } ! 137: ! 138: ! 139: void fstp_i() ! 140: { ! 141: /* fstp st(i) */ ! 142: reg_move(FPU_st0_ptr, &st(FPU_rm)); ! 143: pop(); ! 144: } ! 145:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.