|
|
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.