ropFXCH(uint8_t opcode,uint32_t fetchdat,uint32_t op_32,uint32_t op_pc,codeblock_t * block)1 static uint32_t ropFXCH(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
2 {
3         FP_ENTER();
4 
5         FP_FXCH(opcode & 7);
6 
7         return op_pc;
8 }
9 
ropFLD(uint8_t opcode,uint32_t fetchdat,uint32_t op_32,uint32_t op_pc,codeblock_t * block)10 static uint32_t ropFLD(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
11 {
12         FP_ENTER();
13 
14         FP_FLD(opcode & 7);
15 
16         return op_pc;
17 }
18 
ropFST(uint8_t opcode,uint32_t fetchdat,uint32_t op_32,uint32_t op_pc,codeblock_t * block)19 static uint32_t ropFST(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
20 {
21         FP_ENTER();
22 
23         FP_FST(opcode & 7);
24 
25         return op_pc;
26 }
ropFSTP(uint8_t opcode,uint32_t fetchdat,uint32_t op_32,uint32_t op_pc,codeblock_t * block)27 static uint32_t ropFSTP(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
28 {
29         FP_ENTER();
30 
31         FP_FST(opcode & 7);
32         FP_POP();
33 
34         return op_pc;
35 }
36 
37 
ropFLDs(uint8_t opcode,uint32_t fetchdat,uint32_t op_32,uint32_t op_pc,codeblock_t * block)38 static uint32_t ropFLDs(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
39 {
40         x86seg *target_seg;
41 
42         FP_ENTER();
43         op_pc--;
44         target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32);
45 
46         STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc);
47 
48         CHECK_SEG_READ(target_seg);
49         MEM_LOAD_ADDR_EA_L(target_seg);
50 
51         FP_LOAD_S();
52 
53         return op_pc + 1;
54 }
ropFLDd(uint8_t opcode,uint32_t fetchdat,uint32_t op_32,uint32_t op_pc,codeblock_t * block)55 static uint32_t ropFLDd(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
56 {
57         x86seg *target_seg;
58 
59         FP_ENTER();
60         op_pc--;
61         target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32);
62 
63         STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc);
64 
65         CHECK_SEG_READ(target_seg);
66         MEM_LOAD_ADDR_EA_Q(target_seg);
67 
68         FP_LOAD_D();
69 
70         return op_pc + 1;
71 }
72 
ropFILDw(uint8_t opcode,uint32_t fetchdat,uint32_t op_32,uint32_t op_pc,codeblock_t * block)73 static uint32_t ropFILDw(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
74 {
75         x86seg *target_seg;
76 
77         FP_ENTER();
78         op_pc--;
79         target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32);
80 
81         STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc);
82 
83         CHECK_SEG_READ(target_seg);
84         MEM_LOAD_ADDR_EA_W(target_seg);
85 
86         FP_LOAD_IW();
87 
88         return op_pc + 1;
89 }
ropFILDl(uint8_t opcode,uint32_t fetchdat,uint32_t op_32,uint32_t op_pc,codeblock_t * block)90 static uint32_t ropFILDl(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
91 {
92         x86seg *target_seg;
93 
94         FP_ENTER();
95         op_pc--;
96         target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32);
97 
98         STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc);
99 
100         CHECK_SEG_READ(target_seg);
101         MEM_LOAD_ADDR_EA_L(target_seg);
102 
103         FP_LOAD_IL();
104 
105         return op_pc + 1;
106 }
ropFILDq(uint8_t opcode,uint32_t fetchdat,uint32_t op_32,uint32_t op_pc,codeblock_t * block)107 static uint32_t ropFILDq(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
108 {
109         x86seg *target_seg;
110 
111         FP_ENTER();
112         op_pc--;
113         target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32);
114 
115         STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc);
116 
117         CHECK_SEG_READ(target_seg);
118         MEM_LOAD_ADDR_EA_Q(target_seg);
119 
120         FP_LOAD_IQ();
121 
122         codegen_fpu_loaded_iq[(cpu_state.TOP - 1) & 7] = 1;
123 
124         return op_pc + 1;
125 }
126 
ropFSTs(uint8_t opcode,uint32_t fetchdat,uint32_t op_32,uint32_t op_pc,codeblock_t * block)127 static uint32_t ropFSTs(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
128 {
129         x86seg *target_seg;
130         int host_reg;
131 
132         FP_ENTER();
133         op_pc--;
134         target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32);
135 
136         host_reg = FP_LOAD_REG(0);
137 
138         STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc);
139 
140         CHECK_SEG_WRITE(target_seg);
141 
142         MEM_STORE_ADDR_EA_L(target_seg, host_reg);
143 
144         return op_pc + 1;
145 }
ropFSTd(uint8_t opcode,uint32_t fetchdat,uint32_t op_32,uint32_t op_pc,codeblock_t * block)146 static uint32_t ropFSTd(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
147 {
148         x86seg *target_seg;
149         int host_reg1, host_reg2;
150 
151         FP_ENTER();
152         op_pc--;
153         target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32);
154 
155         FP_LOAD_REG_D(0, &host_reg1, &host_reg2);
156 
157         STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc);
158 
159         CHECK_SEG_WRITE(target_seg);
160         CHECK_SEG_LIMITS(target_seg, 7);
161 
162         MEM_STORE_ADDR_EA_Q(target_seg, host_reg1, host_reg2);
163 
164         return op_pc + 1;
165 }
166 
ropFSTPs(uint8_t opcode,uint32_t fetchdat,uint32_t op_32,uint32_t op_pc,codeblock_t * block)167 static uint32_t ropFSTPs(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
168 {
169         uint32_t new_pc = ropFSTs(opcode, fetchdat, op_32, op_pc, block);
170 
171         FP_POP();
172 
173         return new_pc;
174 }
ropFSTPd(uint8_t opcode,uint32_t fetchdat,uint32_t op_32,uint32_t op_pc,codeblock_t * block)175 static uint32_t ropFSTPd(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
176 {
177         uint32_t new_pc = ropFSTd(opcode, fetchdat, op_32, op_pc, block);
178 
179         FP_POP();
180 
181         return new_pc;
182 }
183 
184 #define ropFarith(name, size, load, op) \
185 static uint32_t ropF ## name ## size(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)     \
186 {                                                                                                                               \
187         x86seg *target_seg;                                                                                                     \
188                                                                                                                                 \
189         FP_ENTER();                                                                                                             \
190         op_pc--;                                                                                                                \
191         target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32);                                                    \
192                                                                                                                                 \
193         STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc);                                                                         \
194                                                                                                                                 \
195         CHECK_SEG_READ(target_seg);                                                                                             \
196         load(target_seg);                                                                                                       \
197                                                                                                                                 \
198         op(FPU_ ## name);                                                                                                       \
199                                                                                                                                 \
200         return op_pc + 1;                                                                                                       \
201 }
202 
203 ropFarith(ADD,  s, MEM_LOAD_ADDR_EA_L, FP_OP_S);
204 ropFarith(DIV,  s, MEM_LOAD_ADDR_EA_L, FP_OP_S);
205 ropFarith(DIVR, s, MEM_LOAD_ADDR_EA_L, FP_OP_S);
206 ropFarith(MUL,  s, MEM_LOAD_ADDR_EA_L, FP_OP_S);
207 ropFarith(SUB,  s, MEM_LOAD_ADDR_EA_L, FP_OP_S);
208 ropFarith(SUBR, s, MEM_LOAD_ADDR_EA_L, FP_OP_S);
209 ropFarith(ADD,  d, MEM_LOAD_ADDR_EA_Q, FP_OP_D);
210 ropFarith(DIV,  d, MEM_LOAD_ADDR_EA_Q, FP_OP_D);
211 ropFarith(DIVR, d, MEM_LOAD_ADDR_EA_Q, FP_OP_D);
212 ropFarith(MUL,  d, MEM_LOAD_ADDR_EA_Q, FP_OP_D);
213 ropFarith(SUB,  d, MEM_LOAD_ADDR_EA_Q, FP_OP_D);
214 ropFarith(SUBR, d, MEM_LOAD_ADDR_EA_Q, FP_OP_D);
215 ropFarith(ADD,  iw, MEM_LOAD_ADDR_EA_W, FP_OP_IW);
216 ropFarith(DIV,  iw, MEM_LOAD_ADDR_EA_W, FP_OP_IW);
217 ropFarith(DIVR, iw, MEM_LOAD_ADDR_EA_W, FP_OP_IW);
218 ropFarith(MUL,  iw, MEM_LOAD_ADDR_EA_W, FP_OP_IW);
219 ropFarith(SUB,  iw, MEM_LOAD_ADDR_EA_W, FP_OP_IW);
220 ropFarith(SUBR, iw, MEM_LOAD_ADDR_EA_W, FP_OP_IW);
221 ropFarith(ADD,  il, MEM_LOAD_ADDR_EA_L, FP_OP_IL);
222 ropFarith(DIV,  il, MEM_LOAD_ADDR_EA_L, FP_OP_IL);
223 ropFarith(DIVR, il, MEM_LOAD_ADDR_EA_L, FP_OP_IL);
224 ropFarith(MUL,  il, MEM_LOAD_ADDR_EA_L, FP_OP_IL);
225 ropFarith(SUB,  il, MEM_LOAD_ADDR_EA_L, FP_OP_IL);
226 ropFarith(SUBR, il, MEM_LOAD_ADDR_EA_L, FP_OP_IL);
227 
228 #define ropFcompare(name, size, load, op) \
229 static uint32_t ropF ## name ## size(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)     \
230 {                                                                                                                               \
231         x86seg *target_seg;                                                                                                     \
232                                                                                                                                 \
233         FP_ENTER();                                                                                                             \
234         op_pc--;                                                                                                                \
235         target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32);                                                    \
236                                                                                                                                 \
237         STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc);                                                                         \
238                                                                                                                                 \
239         CHECK_SEG_READ(target_seg);                                                                                             \
240         load(target_seg);                                                                                                       \
241                                                                                                                                 \
242         op();                                                                                                                   \
243                                                                                                                                 \
244         return op_pc + 1;                                                                                                       \
245 }                                                                                                                               \
246 static uint32_t ropF ## name ## P ## size(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)        \
247 {                                                                                                                               \
248         uint32_t new_pc = ropF ## name ## size(opcode, fetchdat, op_32, op_pc, block);                                           \
249                                                                                                                                 \
250         FP_POP();                                                                                                               \
251                                                                                                                                 \
252         return new_pc;                                                                                                          \
253 }
254 
255 ropFcompare(COM, s, MEM_LOAD_ADDR_EA_L, FP_COMPARE_S);
256 ropFcompare(COM, d, MEM_LOAD_ADDR_EA_Q, FP_COMPARE_D);
257 ropFcompare(COM, iw, MEM_LOAD_ADDR_EA_W, FP_COMPARE_IW);
258 ropFcompare(COM, il, MEM_LOAD_ADDR_EA_L, FP_COMPARE_IL);
259 
260 /*static uint32_t ropFADDs(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
261 {
262         x86seg *target_seg;
263 
264         FP_ENTER();
265         op_pc--;
266         target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32);
267 
268         STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc);
269 
270         CHECK_SEG_READ(target_seg);
271         MEM_LOAD_ADDR_EA_L(target_seg);
272 
273         FP_OP_S(FPU_ADD);
274 
275         return op_pc + 1;
276 }
277 static uint32_t ropFDIVs(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
278 {
279         x86seg *target_seg;
280 
281         FP_ENTER();
282         op_pc--;
283         target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32);
284 
285         STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc);
286 
287         CHECK_SEG_READ(target_seg);
288         MEM_LOAD_ADDR_EA_L(target_seg);
289 
290         FP_OP_S(FPU_DIV);
291 
292         return op_pc + 1;
293 }
294 static uint32_t ropFMULs(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
295 {
296         x86seg *target_seg;
297 
298         FP_ENTER();
299         op_pc--;
300         target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32);
301 
302         STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc);
303 
304         CHECK_SEG_READ(target_seg);
305         MEM_LOAD_ADDR_EA_L(target_seg);
306 
307         FP_OP_S(FPU_MUL);
308 
309         return op_pc + 1;
310 }
311 static uint32_t ropFSUBs(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
312 {
313         x86seg *target_seg;
314 
315         FP_ENTER();
316         op_pc--;
317         target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32);
318 
319         STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc);
320 
321         CHECK_SEG_READ(target_seg);
322         MEM_LOAD_ADDR_EA_L(target_seg);
323 
324         FP_OP_S(FPU_SUB);
325 
326         return op_pc + 1;
327 }*/
328 
329 
ropFADD(uint8_t opcode,uint32_t fetchdat,uint32_t op_32,uint32_t op_pc,codeblock_t * block)330 static uint32_t ropFADD(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
331 {
332         FP_ENTER();
333         FP_OP_REG(FPU_ADD, 0, opcode & 7);
334 
335         return op_pc;
336 }
ropFCOM(uint8_t opcode,uint32_t fetchdat,uint32_t op_32,uint32_t op_pc,codeblock_t * block)337 static uint32_t ropFCOM(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
338 {
339         FP_ENTER();
340         FP_COMPARE_REG(0, opcode & 7);
341 
342         return op_pc;
343 }
ropFDIV(uint8_t opcode,uint32_t fetchdat,uint32_t op_32,uint32_t op_pc,codeblock_t * block)344 static uint32_t ropFDIV(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
345 {
346         FP_ENTER();
347         FP_OP_REG(FPU_DIV, 0, opcode & 7);
348 
349         return op_pc;
350 }
ropFDIVR(uint8_t opcode,uint32_t fetchdat,uint32_t op_32,uint32_t op_pc,codeblock_t * block)351 static uint32_t ropFDIVR(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
352 {
353         FP_ENTER();
354         FP_OP_REG(FPU_DIVR, 0, opcode & 7);
355 
356         return op_pc;
357 }
ropFMUL(uint8_t opcode,uint32_t fetchdat,uint32_t op_32,uint32_t op_pc,codeblock_t * block)358 static uint32_t ropFMUL(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
359 {
360         FP_ENTER();
361         FP_OP_REG(FPU_MUL, 0, opcode & 7);
362 
363         return op_pc;
364 }
ropFSUB(uint8_t opcode,uint32_t fetchdat,uint32_t op_32,uint32_t op_pc,codeblock_t * block)365 static uint32_t ropFSUB(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
366 {
367         FP_ENTER();
368         FP_OP_REG(FPU_SUB, 0, opcode & 7);
369 
370         return op_pc;
371 }
ropFSUBR(uint8_t opcode,uint32_t fetchdat,uint32_t op_32,uint32_t op_pc,codeblock_t * block)372 static uint32_t ropFSUBR(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
373 {
374         FP_ENTER();
375         FP_OP_REG(FPU_SUBR, 0, opcode & 7);
376 
377         return op_pc;
378 }
379 
ropFADDr(uint8_t opcode,uint32_t fetchdat,uint32_t op_32,uint32_t op_pc,codeblock_t * block)380 static uint32_t ropFADDr(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
381 {
382         FP_ENTER();
383         FP_OP_REG(FPU_ADD, opcode & 7, 0);
384 
385         return op_pc;
386 }
ropFDIVr(uint8_t opcode,uint32_t fetchdat,uint32_t op_32,uint32_t op_pc,codeblock_t * block)387 static uint32_t ropFDIVr(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
388 {
389         FP_ENTER();
390         FP_OP_REG(FPU_DIV, opcode & 7, 0);
391 
392         return op_pc;
393 }
ropFDIVRr(uint8_t opcode,uint32_t fetchdat,uint32_t op_32,uint32_t op_pc,codeblock_t * block)394 static uint32_t ropFDIVRr(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
395 {
396         FP_ENTER();
397         FP_OP_REG(FPU_DIVR, opcode & 7, 0);
398 
399         return op_pc;
400 }
ropFMULr(uint8_t opcode,uint32_t fetchdat,uint32_t op_32,uint32_t op_pc,codeblock_t * block)401 static uint32_t ropFMULr(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
402 {
403         FP_ENTER();
404         FP_OP_REG(FPU_MUL, opcode & 7, 0);
405 
406         return op_pc;
407 }
ropFSUBr(uint8_t opcode,uint32_t fetchdat,uint32_t op_32,uint32_t op_pc,codeblock_t * block)408 static uint32_t ropFSUBr(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
409 {
410         FP_ENTER();
411         FP_OP_REG(FPU_SUB, opcode & 7, 0);
412 
413         return op_pc;
414 }
ropFSUBRr(uint8_t opcode,uint32_t fetchdat,uint32_t op_32,uint32_t op_pc,codeblock_t * block)415 static uint32_t ropFSUBRr(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
416 {
417         FP_ENTER();
418         FP_OP_REG(FPU_SUBR, opcode & 7, 0);
419 
420         return op_pc;
421 }
422 
ropFADDP(uint8_t opcode,uint32_t fetchdat,uint32_t op_32,uint32_t op_pc,codeblock_t * block)423 static uint32_t ropFADDP(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
424 {
425         FP_ENTER();
426         FP_OP_REG(FPU_ADD, opcode & 7, 0);
427         FP_POP();
428 
429         return op_pc;
430 }
ropFCOMP(uint8_t opcode,uint32_t fetchdat,uint32_t op_32,uint32_t op_pc,codeblock_t * block)431 static uint32_t ropFCOMP(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
432 {
433         FP_ENTER();
434         FP_COMPARE_REG(0, opcode & 7);
435         FP_POP();
436 
437         return op_pc;
438 }
ropFDIVP(uint8_t opcode,uint32_t fetchdat,uint32_t op_32,uint32_t op_pc,codeblock_t * block)439 static uint32_t ropFDIVP(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
440 {
441         FP_ENTER();
442         FP_OP_REG(FPU_DIV, opcode & 7, 0);
443         FP_POP();
444 
445         return op_pc;
446 }
ropFDIVRP(uint8_t opcode,uint32_t fetchdat,uint32_t op_32,uint32_t op_pc,codeblock_t * block)447 static uint32_t ropFDIVRP(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
448 {
449         FP_ENTER();
450         FP_OP_REG(FPU_DIVR, opcode & 7, 0);
451         FP_POP();
452 
453         return op_pc;
454 }
ropFMULP(uint8_t opcode,uint32_t fetchdat,uint32_t op_32,uint32_t op_pc,codeblock_t * block)455 static uint32_t ropFMULP(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
456 {
457         FP_ENTER();
458         FP_OP_REG(FPU_MUL, opcode & 7, 0);
459         FP_POP();
460 
461         return op_pc;
462 }
ropFSUBP(uint8_t opcode,uint32_t fetchdat,uint32_t op_32,uint32_t op_pc,codeblock_t * block)463 static uint32_t ropFSUBP(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
464 {
465         FP_ENTER();
466         FP_OP_REG(FPU_SUB, opcode & 7, 0);
467         FP_POP();
468 
469         return op_pc;
470 }
ropFSUBRP(uint8_t opcode,uint32_t fetchdat,uint32_t op_32,uint32_t op_pc,codeblock_t * block)471 static uint32_t ropFSUBRP(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
472 {
473         FP_ENTER();
474         FP_OP_REG(FPU_SUBR, opcode & 7, 0);
475         FP_POP();
476 
477         return op_pc;
478 }
479 
ropFCOMPP(uint8_t opcode,uint32_t fetchdat,uint32_t op_32,uint32_t op_pc,codeblock_t * block)480 static uint32_t ropFCOMPP(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
481 {
482         FP_ENTER();
483         FP_COMPARE_REG(0, 1);
484         FP_POP2();
485 
486         return op_pc;
487 }
488 
ropFSTSW_AX(uint8_t opcode,uint32_t fetchdat,uint32_t op_32,uint32_t op_pc,codeblock_t * block)489 static uint32_t ropFSTSW_AX(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
490 {
491         int host_reg;
492 
493         FP_ENTER();
494         host_reg = LOAD_VAR_W((uintptr_t)&cpu_state.npxs);
495         STORE_REG_TARGET_W_RELEASE(host_reg, REG_AX);
496 
497         return op_pc;
498 }
499 
500 
ropFISTw(uint8_t opcode,uint32_t fetchdat,uint32_t op_32,uint32_t op_pc,codeblock_t * block)501 static uint32_t ropFISTw(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
502 {
503         x86seg *target_seg;
504         int host_reg;
505 
506         FP_ENTER();
507         op_pc--;
508         target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32);
509 
510         host_reg = FP_LOAD_REG_INT_W(0);
511 
512         STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc);
513 
514         CHECK_SEG_WRITE(target_seg);
515 
516         MEM_STORE_ADDR_EA_W(target_seg, host_reg);
517 
518         return op_pc + 1;
519 }
ropFISTl(uint8_t opcode,uint32_t fetchdat,uint32_t op_32,uint32_t op_pc,codeblock_t * block)520 static uint32_t ropFISTl(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
521 {
522         x86seg *target_seg;
523         int host_reg;
524 
525         FP_ENTER();
526         op_pc--;
527         target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32);
528 
529         host_reg = FP_LOAD_REG_INT(0);
530 
531         STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc);
532 
533         CHECK_SEG_WRITE(target_seg);
534 
535         MEM_STORE_ADDR_EA_L(target_seg, host_reg);
536 
537         return op_pc + 1;
538 }
539 
ropFISTPw(uint8_t opcode,uint32_t fetchdat,uint32_t op_32,uint32_t op_pc,codeblock_t * block)540 static uint32_t ropFISTPw(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
541 {
542         uint32_t new_pc = ropFISTw(opcode, fetchdat, op_32, op_pc, block);
543 
544         FP_POP();
545 
546         return new_pc;
547 }
ropFISTPl(uint8_t opcode,uint32_t fetchdat,uint32_t op_32,uint32_t op_pc,codeblock_t * block)548 static uint32_t ropFISTPl(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
549 {
550         uint32_t new_pc = ropFISTl(opcode, fetchdat, op_32, op_pc, block);
551 
552         FP_POP();
553 
554         return new_pc;
555 }
ropFISTPq(uint8_t opcode,uint32_t fetchdat,uint32_t op_32,uint32_t op_pc,codeblock_t * block)556 static uint32_t ropFISTPq(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
557 {
558         x86seg *target_seg;
559         int host_reg1, host_reg2;
560 
561         FP_ENTER();
562         op_pc--;
563         target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32);
564 
565         FP_LOAD_REG_INT_Q(0, &host_reg1, &host_reg2);
566 
567         STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc);
568 
569         CHECK_SEG_WRITE(target_seg);
570 
571         MEM_STORE_ADDR_EA_Q(target_seg, host_reg1, host_reg2);
572 
573         FP_POP();
574 
575         return op_pc + 1;
576 }
577 
578 
ropFLDCW(uint8_t opcode,uint32_t fetchdat,uint32_t op_32,uint32_t op_pc,codeblock_t * block)579 static uint32_t ropFLDCW(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
580 {
581         x86seg *target_seg;
582 
583         FP_ENTER();
584         op_pc--;
585         target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32);
586 
587         CHECK_SEG_READ(target_seg);
588 
589         MEM_LOAD_ADDR_EA_W(target_seg);
590         STORE_HOST_REG_ADDR_W((uintptr_t)&cpu_state.npxc, 0);
591         UPDATE_NPXC(0);
592 
593         return op_pc + 1;
594 }
ropFSTCW(uint8_t opcode,uint32_t fetchdat,uint32_t op_32,uint32_t op_pc,codeblock_t * block)595 static uint32_t ropFSTCW(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
596 {
597         int host_reg;
598         x86seg *target_seg;
599 
600         FP_ENTER();
601         op_pc--;
602         target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32);
603 
604         CHECK_SEG_WRITE(target_seg);
605 
606         host_reg = LOAD_VAR_W((uintptr_t)&cpu_state.npxc);
607         MEM_STORE_ADDR_EA_W(target_seg, host_reg);
608 
609         return op_pc + 1;
610 }
611 
612 
ropFCHS(uint8_t opcode,uint32_t fetchdat,uint32_t op_32,uint32_t op_pc,codeblock_t * block)613 static uint32_t ropFCHS(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
614 {
615         FP_ENTER();
616         FP_FCHS();
617 
618         return op_pc;
619 }
620 
621 #define opFLDimm(name, v)                                                                                                       \
622         static uint32_t ropFLD ## name(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)   \
623         {                                                                                                                       \
624                 static double fp_imm = v;                                                                                       \
625                                                                                                                                 \
626                 FP_ENTER();                                                                                                     \
627                 FP_LOAD_IMM_Q(*(uint64_t *)&fp_imm);                                                                            \
628                                                                                                                                 \
629                 return op_pc;                                                                                                   \
630         }
631 
632 opFLDimm(1, 1.0)
633 opFLDimm(L2T, 3.3219280948873623)
634 opFLDimm(L2E, 1.4426950408889634);
635 opFLDimm(PI, 3.141592653589793);
636 opFLDimm(EG2, 0.3010299956639812);
637 opFLDimm(Z, 0.0)
638 
ropFLDLN2(uint8_t opcode,uint32_t fetchdat,uint32_t op_32,uint32_t op_pc,codeblock_t * block)639 static uint32_t ropFLDLN2(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
640 {
641         FP_ENTER();
642         FP_LOAD_IMM_Q(0x3fe62e42fefa39f0ull);
643 
644         return op_pc;
645 }
646