ViewVC Help
View File | Revision Log | Show Annotations | Revision Graph | Root Listing
root/cebix/BasiliskII/src/uae_cpu/compiler/codegen_x86.cpp
Revision: 1.14
Committed: 2003-03-19T16:32:51Z (21 years, 6 months ago) by gbeauche
Branch: MAIN
Changes since 1.13: +18 -8 lines
Log Message:
Add missing wrappers of the new runtime-assembler primitives

File Contents

# User Rev Content
1 gbeauche 1.6 /*
2     * compiler/codegen_x86.cpp - IA-32 code generator
3     *
4     * Original 68040 JIT compiler for UAE, copyright 2000-2002 Bernd Meyer
5     *
6     * Adaptation for Basilisk II and improvements, copyright 2000-2002
7     * Gwenole Beauchesne
8     *
9     * Basilisk II (C) 1997-2002 Christian Bauer
10 gbeauche 1.7 *
11     * Portions related to CPU detection come from linux/arch/i386/kernel/setup.c
12 gbeauche 1.6 *
13     * This program is free software; you can redistribute it and/or modify
14     * it under the terms of the GNU General Public License as published by
15     * the Free Software Foundation; either version 2 of the License, or
16     * (at your option) any later version.
17     *
18     * This program is distributed in the hope that it will be useful,
19     * but WITHOUT ANY WARRANTY; without even the implied warranty of
20     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21     * GNU General Public License for more details.
22     *
23     * You should have received a copy of the GNU General Public License
24     * along with this program; if not, write to the Free Software
25     * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
26     */
27    
28 gbeauche 1.1 /* This should eventually end up in machdep/, but for now, x86 is the
29     only target, and it's easier this way... */
30    
31 gbeauche 1.5 #include "flags_x86.h"
32    
33 gbeauche 1.1 /*************************************************************************
34     * Some basic information about the the target CPU *
35     *************************************************************************/
36    
37     #define EAX_INDEX 0
38     #define ECX_INDEX 1
39     #define EDX_INDEX 2
40     #define EBX_INDEX 3
41     #define ESP_INDEX 4
42     #define EBP_INDEX 5
43     #define ESI_INDEX 6
44     #define EDI_INDEX 7
45    
46     /* The register in which subroutines return an integer return value */
47     #define REG_RESULT 0
48    
49     /* The registers subroutines take their first and second argument in */
50     #if defined( _MSC_VER ) && !defined( USE_NORMAL_CALLING_CONVENTION )
51     /* Handle the _fastcall parameters of ECX and EDX */
52     #define REG_PAR1 1
53     #define REG_PAR2 2
54     #else
55     #define REG_PAR1 0
56     #define REG_PAR2 2
57     #endif
58    
59     /* Three registers that are not used for any of the above */
60     #define REG_NOPAR1 6
61     #define REG_NOPAR2 5
62     #define REG_NOPAR3 3
63    
64     #define REG_PC_PRE 0 /* The register we use for preloading regs.pc_p */
65     #if defined( _MSC_VER ) && !defined( USE_NORMAL_CALLING_CONVENTION )
66     #define REG_PC_TMP 0
67     #else
68     #define REG_PC_TMP 1 /* Another register that is not the above */
69     #endif
70    
71     #define SHIFTCOUNT_NREG 1 /* Register that can be used for shiftcount.
72     -1 if any reg will do */
73     #define MUL_NREG1 0 /* %eax will hold the low 32 bits after a 32x32 mul */
74     #define MUL_NREG2 2 /* %edx will hold the high 32 bits */
75    
76     uae_s8 always_used[]={4,-1};
77     uae_s8 can_byte[]={0,1,2,3,-1};
78     uae_s8 can_word[]={0,1,2,3,5,6,7,-1};
79    
80     /* cpuopti mutate instruction handlers to assume registers are saved
81     by the caller */
82     uae_u8 call_saved[]={0,0,0,0,1,0,0,0};
83    
84     /* This *should* be the same as call_saved. But:
85     - We might not really know which registers are saved, and which aren't,
86     so we need to preserve some, but don't want to rely on everyone else
87     also saving those registers
88     - Special registers (such like the stack pointer) should not be "preserved"
89     by pushing, even though they are "saved" across function calls
90     */
91     uae_u8 need_to_preserve[]={1,1,1,1,0,1,1,1};
92    
93     /* Whether classes of instructions do or don't clobber the native flags */
94     #define CLOBBER_MOV
95     #define CLOBBER_LEA
96     #define CLOBBER_CMOV
97     #define CLOBBER_POP
98     #define CLOBBER_PUSH
99     #define CLOBBER_SUB clobber_flags()
100     #define CLOBBER_SBB clobber_flags()
101     #define CLOBBER_CMP clobber_flags()
102     #define CLOBBER_ADD clobber_flags()
103     #define CLOBBER_ADC clobber_flags()
104     #define CLOBBER_AND clobber_flags()
105     #define CLOBBER_OR clobber_flags()
106     #define CLOBBER_XOR clobber_flags()
107    
108     #define CLOBBER_ROL clobber_flags()
109     #define CLOBBER_ROR clobber_flags()
110     #define CLOBBER_SHLL clobber_flags()
111     #define CLOBBER_SHRL clobber_flags()
112     #define CLOBBER_SHRA clobber_flags()
113     #define CLOBBER_TEST clobber_flags()
114     #define CLOBBER_CL16
115     #define CLOBBER_CL8
116     #define CLOBBER_SE16
117     #define CLOBBER_SE8
118     #define CLOBBER_ZE16
119     #define CLOBBER_ZE8
120     #define CLOBBER_SW16 clobber_flags()
121     #define CLOBBER_SW32
122     #define CLOBBER_SETCC
123     #define CLOBBER_MUL clobber_flags()
124     #define CLOBBER_BT clobber_flags()
125     #define CLOBBER_BSF clobber_flags()
126    
127 gbeauche 1.13 /* FIXME: disabled until that's proofread. */
128     #if 0
129    
130     #if defined(__x86_64__)
131     #define X86_TARGET_64BIT 1
132     #endif
133     #define X86_FLAT_REGISTERS 0
134 gbeauche 1.14 #define X86_OPTIMIZE_ALU 1
135     #define X86_OPTIMIZE_ROTSHI 1
136 gbeauche 1.13 #include "codegen_x86.h"
137    
138     #define x86_emit_byte(B) emit_byte(B)
139     #define x86_emit_word(W) emit_word(W)
140     #define x86_emit_long(L) emit_long(L)
141     #define x86_get_target() get_target()
142     #define x86_emit_failure(MSG) jit_fail(MSG, __FILE__, __LINE__, __FUNCTION__)
143    
144     static void jit_fail(const char *msg, const char *file, int line, const char *function)
145     {
146     fprintf(stderr, "JIT failure in function %s from file %s at line %d: %s\n",
147     function, file, line, msg);
148     abort();
149     }
150    
151     LOWFUNC(NONE,WRITE,1,raw_push_l_r,(R4 r))
152     {
153     PUSHLr(r);
154     }
155     LENDFUNC(NONE,WRITE,1,raw_push_l_r,(R4 r))
156    
157     LOWFUNC(NONE,READ,1,raw_pop_l_r,(R4 r))
158     {
159     POPLr(r);
160     }
161     LENDFUNC(NONE,READ,1,raw_pop_l_r,(R4 r))
162    
163     LOWFUNC(WRITE,NONE,2,raw_bt_l_ri,(R4 r, IMM i))
164     {
165     BTLir(i, r);
166     }
167     LENDFUNC(WRITE,NONE,2,raw_bt_l_ri,(R4 r, IMM i))
168    
169     LOWFUNC(WRITE,NONE,2,raw_bt_l_rr,(R4 r, R4 b))
170     {
171     BTLrr(b, r);
172     }
173     LENDFUNC(WRITE,NONE,2,raw_bt_l_rr,(R4 r, R4 b))
174    
175     LOWFUNC(WRITE,NONE,2,raw_btc_l_ri,(RW4 r, IMM i))
176     {
177     BTCLir(i, r);
178     }
179     LENDFUNC(WRITE,NONE,2,raw_btc_l_ri,(RW4 r, IMM i))
180    
181     LOWFUNC(WRITE,NONE,2,raw_btc_l_rr,(RW4 r, R4 b))
182     {
183     BTCLrr(b, r);
184     }
185     LENDFUNC(WRITE,NONE,2,raw_btc_l_rr,(RW4 r, R4 b))
186    
187     LOWFUNC(WRITE,NONE,2,raw_btr_l_ri,(RW4 r, IMM i))
188     {
189     BTRLir(i, r);
190     }
191     LENDFUNC(WRITE,NONE,2,raw_btr_l_ri,(RW4 r, IMM i))
192    
193     LOWFUNC(WRITE,NONE,2,raw_btr_l_rr,(RW4 r, R4 b))
194     {
195     BTRLrr(b, r);
196     }
197     LENDFUNC(WRITE,NONE,2,raw_btr_l_rr,(RW4 r, R4 b))
198    
199     LOWFUNC(WRITE,NONE,2,raw_bts_l_ri,(RW4 r, IMM i))
200     {
201     BTSLir(i, r);
202     }
203     LENDFUNC(WRITE,NONE,2,raw_bts_l_ri,(RW4 r, IMM i))
204    
205     LOWFUNC(WRITE,NONE,2,raw_bts_l_rr,(RW4 r, R4 b))
206     {
207     BTSLrr(b, r);
208     }
209     LENDFUNC(WRITE,NONE,2,raw_bts_l_rr,(RW4 r, R4 b))
210    
211     LOWFUNC(WRITE,NONE,2,raw_sub_w_ri,(RW2 d, IMM i))
212     {
213     SUBWir(i, d);
214     }
215     LENDFUNC(WRITE,NONE,2,raw_sub_w_ri,(RW2 d, IMM i))
216    
217     LOWFUNC(NONE,READ,2,raw_mov_l_rm,(W4 d, MEMR s))
218     {
219     MOVLmr(s, X86_NOREG, X86_NOREG, 1, d);
220     }
221     LENDFUNC(NONE,READ,2,raw_mov_l_rm,(W4 d, MEMR s))
222    
223     LOWFUNC(NONE,WRITE,2,raw_mov_l_mi,(MEMW d, IMM s))
224     {
225     MOVLim(s, d, X86_NOREG, X86_NOREG, 1);
226     }
227     LENDFUNC(NONE,WRITE,2,raw_mov_l_mi,(MEMW d, IMM s))
228    
229     LOWFUNC(NONE,WRITE,2,raw_mov_w_mi,(MEMW d, IMM s))
230     {
231     MOVWim(s, d, X86_NOREG, X86_NOREG, 1);
232     }
233     LENDFUNC(NONE,WRITE,2,raw_mov_w_mi,(MEMW d, IMM s))
234    
235     LOWFUNC(NONE,WRITE,2,raw_mov_b_mi,(MEMW d, IMM s))
236     {
237     MOVBim(s, d, X86_NOREG, X86_NOREG, 1);
238     }
239     LENDFUNC(NONE,WRITE,2,raw_mov_b_mi,(MEMW d, IMM s))
240    
241     LOWFUNC(WRITE,RMW,2,raw_rol_b_mi,(MEMRW d, IMM i))
242     {
243     ROLBim(i, d, X86_NOREG, X86_NOREG, 1);
244     }
245     LENDFUNC(WRITE,RMW,2,raw_rol_b_mi,(MEMRW d, IMM i))
246    
247     LOWFUNC(WRITE,NONE,2,raw_rol_b_ri,(RW1 r, IMM i))
248     {
249     ROLBir(i, r);
250     }
251     LENDFUNC(WRITE,NONE,2,raw_rol_b_ri,(RW1 r, IMM i))
252    
253     LOWFUNC(WRITE,NONE,2,raw_rol_w_ri,(RW2 r, IMM i))
254     {
255     ROLWir(i, r);
256     }
257     LENDFUNC(WRITE,NONE,2,raw_rol_w_ri,(RW2 r, IMM i))
258    
259     LOWFUNC(WRITE,NONE,2,raw_rol_l_ri,(RW4 r, IMM i))
260     {
261     ROLLir(i, r);
262     }
263     LENDFUNC(WRITE,NONE,2,raw_rol_l_ri,(RW4 r, IMM i))
264    
265     LOWFUNC(WRITE,NONE,2,raw_rol_l_rr,(RW4 d, R1 r))
266     {
267     ROLLrr(r, d);
268     }
269     LENDFUNC(WRITE,NONE,2,raw_rol_l_rr,(RW4 d, R1 r))
270    
271     LOWFUNC(WRITE,NONE,2,raw_rol_w_rr,(RW2 d, R1 r))
272     {
273     ROLWrr(r, d);
274     }
275     LENDFUNC(WRITE,NONE,2,raw_rol_w_rr,(RW2 d, R1 r))
276    
277     LOWFUNC(WRITE,NONE,2,raw_rol_b_rr,(RW1 d, R1 r))
278     {
279     ROLBrr(r, d);
280     }
281     LENDFUNC(WRITE,NONE,2,raw_rol_b_rr,(RW1 d, R1 r))
282    
283     LOWFUNC(WRITE,NONE,2,raw_shll_l_rr,(RW4 d, R1 r))
284     {
285     SHLLrr(r, d);
286     }
287     LENDFUNC(WRITE,NONE,2,raw_shll_l_rr,(RW4 d, R1 r))
288    
289     LOWFUNC(WRITE,NONE,2,raw_shll_w_rr,(RW2 d, R1 r))
290     {
291     SHLWrr(r, d);
292     }
293     LENDFUNC(WRITE,NONE,2,raw_shll_w_rr,(RW2 d, R1 r))
294    
295     LOWFUNC(WRITE,NONE,2,raw_shll_b_rr,(RW1 d, R1 r))
296     {
297     SHLBrr(r, d);
298     }
299     LENDFUNC(WRITE,NONE,2,raw_shll_b_rr,(RW1 d, R1 r))
300    
301     LOWFUNC(WRITE,NONE,2,raw_ror_b_ri,(RW1 r, IMM i))
302     {
303     RORBir(i, r);
304     }
305     LENDFUNC(WRITE,NONE,2,raw_ror_b_ri,(RW1 r, IMM i))
306    
307     LOWFUNC(WRITE,NONE,2,raw_ror_w_ri,(RW2 r, IMM i))
308     {
309     RORWir(i, r);
310     }
311     LENDFUNC(WRITE,NONE,2,raw_ror_w_ri,(RW2 r, IMM i))
312    
313     LOWFUNC(WRITE,READ,2,raw_or_l_rm,(RW4 d, MEMR s))
314     {
315     ORLmr(s, X86_NOREG, X86_NOREG, 1, d);
316     }
317     LENDFUNC(WRITE,READ,2,raw_or_l_rm,(RW4 d, MEMR s))
318    
319     LOWFUNC(WRITE,NONE,2,raw_ror_l_ri,(RW4 r, IMM i))
320     {
321     RORLir(i, r);
322     }
323     LENDFUNC(WRITE,NONE,2,raw_ror_l_ri,(RW4 r, IMM i))
324    
325     LOWFUNC(WRITE,NONE,2,raw_ror_l_rr,(RW4 d, R1 r))
326     {
327     RORLrr(r, d);
328     }
329     LENDFUNC(WRITE,NONE,2,raw_ror_l_rr,(RW4 d, R1 r))
330    
331     LOWFUNC(WRITE,NONE,2,raw_ror_w_rr,(RW2 d, R1 r))
332     {
333     RORWrr(r, d);
334     }
335     LENDFUNC(WRITE,NONE,2,raw_ror_w_rr,(RW2 d, R1 r))
336    
337     LOWFUNC(WRITE,NONE,2,raw_ror_b_rr,(RW1 d, R1 r))
338     {
339     RORBrr(r, d);
340     }
341     LENDFUNC(WRITE,NONE,2,raw_ror_b_rr,(RW1 d, R1 r))
342    
343     LOWFUNC(WRITE,NONE,2,raw_shrl_l_rr,(RW4 d, R1 r))
344     {
345     SHRLrr(r, d);
346     }
347     LENDFUNC(WRITE,NONE,2,raw_shrl_l_rr,(RW4 d, R1 r))
348    
349     LOWFUNC(WRITE,NONE,2,raw_shrl_w_rr,(RW2 d, R1 r))
350     {
351     SHRWrr(r, d);
352     }
353     LENDFUNC(WRITE,NONE,2,raw_shrl_w_rr,(RW2 d, R1 r))
354    
355     LOWFUNC(WRITE,NONE,2,raw_shrl_b_rr,(RW1 d, R1 r))
356     {
357     SHRBrr(r, d);
358     }
359     LENDFUNC(WRITE,NONE,2,raw_shrl_b_rr,(RW1 d, R1 r))
360    
361     LOWFUNC(WRITE,NONE,2,raw_shra_l_rr,(RW4 d, R1 r))
362     {
363 gbeauche 1.14 SARLrr(r, d);
364 gbeauche 1.13 }
365     LENDFUNC(WRITE,NONE,2,raw_shra_l_rr,(RW4 d, R1 r))
366    
367     LOWFUNC(WRITE,NONE,2,raw_shra_w_rr,(RW2 d, R1 r))
368     {
369 gbeauche 1.14 SARWrr(r, d);
370 gbeauche 1.13 }
371     LENDFUNC(WRITE,NONE,2,raw_shra_w_rr,(RW2 d, R1 r))
372    
373     LOWFUNC(WRITE,NONE,2,raw_shra_b_rr,(RW1 d, R1 r))
374     {
375 gbeauche 1.14 SARBrr(r, d);
376 gbeauche 1.13 }
377     LENDFUNC(WRITE,NONE,2,raw_shra_b_rr,(RW1 d, R1 r))
378    
379     LOWFUNC(WRITE,NONE,2,raw_shll_l_ri,(RW4 r, IMM i))
380     {
381     SHLLir(i, r);
382     }
383     LENDFUNC(WRITE,NONE,2,raw_shll_l_ri,(RW4 r, IMM i))
384    
385     LOWFUNC(WRITE,NONE,2,raw_shll_w_ri,(RW2 r, IMM i))
386     {
387     SHLWir(i, r);
388     }
389     LENDFUNC(WRITE,NONE,2,raw_shll_w_ri,(RW2 r, IMM i))
390    
391     LOWFUNC(WRITE,NONE,2,raw_shll_b_ri,(RW1 r, IMM i))
392     {
393     SHLBir(i, r);
394     }
395     LENDFUNC(WRITE,NONE,2,raw_shll_b_ri,(RW1 r, IMM i))
396    
397     LOWFUNC(WRITE,NONE,2,raw_shrl_l_ri,(RW4 r, IMM i))
398     {
399     SHRLir(i, r);
400     }
401     LENDFUNC(WRITE,NONE,2,raw_shrl_l_ri,(RW4 r, IMM i))
402    
403     LOWFUNC(WRITE,NONE,2,raw_shrl_w_ri,(RW2 r, IMM i))
404     {
405     SHRWir(i, r);
406     }
407     LENDFUNC(WRITE,NONE,2,raw_shrl_w_ri,(RW2 r, IMM i))
408    
409     LOWFUNC(WRITE,NONE,2,raw_shrl_b_ri,(RW1 r, IMM i))
410     {
411     SHRBir(i, r);
412     }
413     LENDFUNC(WRITE,NONE,2,raw_shrl_b_ri,(RW1 r, IMM i))
414    
415     LOWFUNC(WRITE,NONE,2,raw_shra_l_ri,(RW4 r, IMM i))
416     {
417 gbeauche 1.14 SARLir(i, r);
418 gbeauche 1.13 }
419     LENDFUNC(WRITE,NONE,2,raw_shra_l_ri,(RW4 r, IMM i))
420    
421     LOWFUNC(WRITE,NONE,2,raw_shra_w_ri,(RW2 r, IMM i))
422     {
423 gbeauche 1.14 SARWir(i, r);
424 gbeauche 1.13 }
425     LENDFUNC(WRITE,NONE,2,raw_shra_w_ri,(RW2 r, IMM i))
426    
427     LOWFUNC(WRITE,NONE,2,raw_shra_b_ri,(RW1 r, IMM i))
428     {
429 gbeauche 1.14 SARBir(i, r);
430 gbeauche 1.13 }
431     LENDFUNC(WRITE,NONE,2,raw_shra_b_ri,(RW1 r, IMM i))
432    
433     LOWFUNC(WRITE,NONE,1,raw_sahf,(R2 dummy_ah))
434     {
435     SAHF();
436     }
437     LENDFUNC(WRITE,NONE,1,raw_sahf,(R2 dummy_ah))
438    
439     LOWFUNC(NONE,NONE,1,raw_cpuid,(R4 dummy_eax))
440     {
441     CPUID();
442     }
443     LENDFUNC(NONE,NONE,1,raw_cpuid,(R4 dummy_eax))
444    
445     LOWFUNC(READ,NONE,1,raw_lahf,(W2 dummy_ah))
446     {
447     LAHF();
448     }
449     LENDFUNC(READ,NONE,1,raw_lahf,(W2 dummy_ah))
450    
451     LOWFUNC(READ,NONE,2,raw_setcc,(W1 d, IMM cc))
452     {
453     SETCCir(cc, d);
454     }
455     LENDFUNC(READ,NONE,2,raw_setcc,(W1 d, IMM cc))
456    
457     LOWFUNC(READ,WRITE,2,raw_setcc_m,(MEMW d, IMM cc))
458     {
459     SETCCim(cc, d, X86_NOREG, X86_NOREG, 1);
460     }
461     LENDFUNC(READ,WRITE,2,raw_setcc_m,(MEMW d, IMM cc))
462    
463     LOWFUNC(READ,NONE,3,raw_cmov_l_rr,(RW4 d, R4 s, IMM cc))
464     {
465     CMOVLrr(cc, s, d);
466     }
467     LENDFUNC(READ,NONE,3,raw_cmov_l_rr,(RW4 d, R4 s, IMM cc))
468    
469     LOWFUNC(WRITE,NONE,2,raw_bsf_l_rr,(W4 d, R4 s))
470     {
471     BSFLrr(s, d);
472     }
473     LENDFUNC(WRITE,NONE,2,raw_bsf_l_rr,(W4 d, R4 s))
474    
475     LOWFUNC(NONE,NONE,2,raw_sign_extend_16_rr,(W4 d, R2 s))
476     {
477     MOVSWLrr(s, d);
478     }
479     LENDFUNC(NONE,NONE,2,raw_sign_extend_16_rr,(W4 d, R2 s))
480    
481     LOWFUNC(NONE,NONE,2,raw_sign_extend_8_rr,(W4 d, R1 s))
482     {
483     MOVSBLrr(s, d);
484     }
485     LENDFUNC(NONE,NONE,2,raw_sign_extend_8_rr,(W4 d, R1 s))
486    
487     LOWFUNC(NONE,NONE,2,raw_zero_extend_16_rr,(W4 d, R2 s))
488     {
489     MOVZWLrr(s, d);
490     }
491     LENDFUNC(NONE,NONE,2,raw_zero_extend_16_rr,(W4 d, R2 s))
492    
493     LOWFUNC(NONE,NONE,2,raw_zero_extend_8_rr,(W4 d, R1 s))
494     {
495     MOVZBLrr(s, d);
496     }
497     LENDFUNC(NONE,NONE,2,raw_zero_extend_8_rr,(W4 d, R1 s))
498    
499     LOWFUNC(NONE,NONE,2,raw_imul_32_32,(RW4 d, R4 s))
500     {
501 gbeauche 1.14 IMULLrr(s, d);
502 gbeauche 1.13 }
503     LENDFUNC(NONE,NONE,2,raw_imul_32_32,(RW4 d, R4 s))
504    
505     LOWFUNC(NONE,NONE,2,raw_imul_64_32,(RW4 d, RW4 s))
506     {
507 gbeauche 1.14 if (d!=MUL_NREG1 || s!=MUL_NREG2) {
508     write_log("Bad register in IMUL: d=%d, s=%d\n",d,s);
509 gbeauche 1.13 abort();
510 gbeauche 1.14 }
511     IMULLr(s);
512 gbeauche 1.13 }
513     LENDFUNC(NONE,NONE,2,raw_imul_64_32,(RW4 d, RW4 s))
514    
515     LOWFUNC(NONE,NONE,2,raw_mul_64_32,(RW4 d, RW4 s))
516     {
517 gbeauche 1.14 if (d!=MUL_NREG1 || s!=MUL_NREG2) {
518     write_log("Bad register in MUL: d=%d, s=%d\n",d,s);
519 gbeauche 1.13 abort();
520 gbeauche 1.14 }
521     MULLr(s);
522 gbeauche 1.13 }
523     LENDFUNC(NONE,NONE,2,raw_mul_64_32,(RW4 d, RW4 s))
524    
525     LOWFUNC(NONE,NONE,2,raw_mul_32_32,(RW4 d, R4 s))
526     {
527 gbeauche 1.14 abort(); /* %^$&%^$%#^ x86! */
528 gbeauche 1.13 }
529     LENDFUNC(NONE,NONE,2,raw_mul_32_32,(RW4 d, R4 s))
530    
531     LOWFUNC(NONE,NONE,2,raw_mov_b_rr,(W1 d, R1 s))
532     {
533     MOVBrr(s, d);
534     }
535     LENDFUNC(NONE,NONE,2,raw_mov_b_rr,(W1 d, R1 s))
536    
537     LOWFUNC(NONE,NONE,2,raw_mov_w_rr,(W2 d, R2 s))
538     {
539     MOVWrr(s, d);
540     }
541     LENDFUNC(NONE,NONE,2,raw_mov_w_rr,(W2 d, R2 s))
542    
543     LOWFUNC(NONE,READ,4,raw_mov_l_rrm_indexed,(W4 d,R4 baser, R4 index, IMM factor))
544     {
545     MOVLmr(0, baser, index, factor, d);
546     }
547     LENDFUNC(NONE,READ,4,raw_mov_l_rrm_indexed,(W4 d,R4 baser, R4 index, IMM factor))
548    
549     LOWFUNC(NONE,READ,4,raw_mov_w_rrm_indexed,(W2 d, R4 baser, R4 index, IMM factor))
550     {
551     MOVWmr(0, baser, index, factor, d);
552     }
553     LENDFUNC(NONE,READ,4,raw_mov_w_rrm_indexed,(W2 d, R4 baser, R4 index, IMM factor))
554    
555     LOWFUNC(NONE,READ,4,raw_mov_b_rrm_indexed,(W1 d, R4 baser, R4 index, IMM factor))
556     {
557     MOVBmr(0, baser, index, factor, d);
558     }
559     LENDFUNC(NONE,READ,4,raw_mov_b_rrm_indexed,(W1 d, R4 baser, R4 index, IMM factor))
560    
561     LOWFUNC(NONE,WRITE,4,raw_mov_l_mrr_indexed,(R4 baser, R4 index, IMM factor, R4 s))
562     {
563     MOVLrm(s, 0, baser, index, factor);
564     }
565     LENDFUNC(NONE,WRITE,4,raw_mov_l_mrr_indexed,(R4 baser, R4 index, IMM factor, R4 s))
566    
567     LOWFUNC(NONE,WRITE,4,raw_mov_w_mrr_indexed,(R4 baser, R4 index, IMM factor, R2 s))
568     {
569     MOVWrm(s, 0, baser, index, factor);
570     }
571     LENDFUNC(NONE,WRITE,4,raw_mov_w_mrr_indexed,(R4 baser, R4 index, IMM factor, R2 s))
572    
573     LOWFUNC(NONE,WRITE,4,raw_mov_b_mrr_indexed,(R4 baser, R4 index, IMM factor, R1 s))
574     {
575     MOVBrm(s, 0, baser, index, factor);
576     }
577     LENDFUNC(NONE,WRITE,4,raw_mov_b_mrr_indexed,(R4 baser, R4 index, IMM factor, R1 s))
578    
579     LOWFUNC(NONE,WRITE,5,raw_mov_l_bmrr_indexed,(IMM base, R4 baser, R4 index, IMM factor, R4 s))
580     {
581     MOVLrm(s, base, baser, index, factor);
582     }
583     LENDFUNC(NONE,WRITE,5,raw_mov_l_bmrr_indexed,(IMM base, R4 baser, R4 index, IMM factor, R4 s))
584    
585     LOWFUNC(NONE,WRITE,5,raw_mov_w_bmrr_indexed,(IMM base, R4 baser, R4 index, IMM factor, R2 s))
586     {
587     MOVWrm(s, base, baser, index, factor);
588     }
589     LENDFUNC(NONE,WRITE,5,raw_mov_w_bmrr_indexed,(IMM base, R4 baser, R4 index, IMM factor, R2 s))
590    
591     LOWFUNC(NONE,WRITE,5,raw_mov_b_bmrr_indexed,(IMM base, R4 baser, R4 index, IMM factor, R1 s))
592     {
593     MOVBrm(s, base, baser, index, factor);
594     }
595     LENDFUNC(NONE,WRITE,5,raw_mov_b_bmrr_indexed,(IMM base, R4 baser, R4 index, IMM factor, R1 s))
596    
597     LOWFUNC(NONE,READ,5,raw_mov_l_brrm_indexed,(W4 d, IMM base, R4 baser, R4 index, IMM factor))
598     {
599     MOVLmr(base, baser, index, factor, d);
600     }
601     LENDFUNC(NONE,READ,5,raw_mov_l_brrm_indexed,(W4 d, IMM base, R4 baser, R4 index, IMM factor))
602    
603     LOWFUNC(NONE,READ,5,raw_mov_w_brrm_indexed,(W2 d, IMM base, R4 baser, R4 index, IMM factor))
604     {
605     MOVWmr(base, baser, index, factor, d);
606     }
607     LENDFUNC(NONE,READ,5,raw_mov_w_brrm_indexed,(W2 d, IMM base, R4 baser, R4 index, IMM factor))
608    
609     LOWFUNC(NONE,READ,5,raw_mov_b_brrm_indexed,(W1 d, IMM base, R4 baser, R4 index, IMM factor))
610     {
611     MOVBmr(base, baser, index, factor, d);
612     }
613     LENDFUNC(NONE,READ,5,raw_mov_b_brrm_indexed,(W1 d, IMM base, R4 baser, R4 index, IMM factor))
614    
615     LOWFUNC(NONE,READ,4,raw_mov_l_rm_indexed,(W4 d, IMM base, R4 index, IMM factor))
616     {
617     MOVLmr(base, X86_NOREG, index, factor, d);
618     }
619     LENDFUNC(NONE,READ,4,raw_mov_l_rm_indexed,(W4 d, IMM base, R4 index, IMM factor))
620    
621     LOWFUNC(NONE,READ,5,raw_cmov_l_rm_indexed,(W4 d, IMM base, R4 index, IMM factor, IMM cond))
622     {
623     CMOVLmr(cond, base, X86_NOREG, index, factor, d);
624     }
625     LENDFUNC(NONE,READ,5,raw_cmov_l_rm_indexed,(W4 d, IMM base, R4 index, IMM factor, IMM cond))
626    
627     LOWFUNC(NONE,READ,3,raw_cmov_l_rm,(W4 d, IMM mem, IMM cond))
628     {
629     CMOVLmr(cond, mem, X86_NOREG, X86_NOREG, 1, d);
630     }
631     LENDFUNC(NONE,READ,3,raw_cmov_l_rm,(W4 d, IMM mem, IMM cond))
632    
633     LOWFUNC(NONE,READ,3,raw_mov_l_rR,(W4 d, R4 s, IMM offset))
634     {
635     MOVLmr(offset, s, X86_NOREG, 1, d);
636     }
637     LENDFUNC(NONE,READ,3,raw_mov_l_rR,(W4 d, R4 s, IMM offset))
638    
639     LOWFUNC(NONE,READ,3,raw_mov_w_rR,(W2 d, R4 s, IMM offset))
640     {
641     MOVWmr(offset, s, X86_NOREG, 1, d);
642     }
643     LENDFUNC(NONE,READ,3,raw_mov_w_rR,(W2 d, R4 s, IMM offset))
644    
645     LOWFUNC(NONE,READ,3,raw_mov_b_rR,(W1 d, R4 s, IMM offset))
646     {
647     MOVBmr(offset, s, X86_NOREG, 1, d);
648     }
649     LENDFUNC(NONE,READ,3,raw_mov_b_rR,(W1 d, R4 s, IMM offset))
650    
651     LOWFUNC(NONE,READ,3,raw_mov_l_brR,(W4 d, R4 s, IMM offset))
652     {
653     MOVLmr(offset, s, X86_NOREG, 1, d);
654     }
655     LENDFUNC(NONE,READ,3,raw_mov_l_brR,(W4 d, R4 s, IMM offset))
656    
657     LOWFUNC(NONE,READ,3,raw_mov_w_brR,(W2 d, R4 s, IMM offset))
658     {
659     MOVWmr(offset, s, X86_NOREG, 1, d);
660     }
661     LENDFUNC(NONE,READ,3,raw_mov_w_brR,(W2 d, R4 s, IMM offset))
662    
663     LOWFUNC(NONE,READ,3,raw_mov_b_brR,(W1 d, R4 s, IMM offset))
664     {
665     MOVBmr(offset, s, X86_NOREG, 1, d);
666     }
667     LENDFUNC(NONE,READ,3,raw_mov_b_brR,(W1 d, R4 s, IMM offset))
668    
669     LOWFUNC(NONE,WRITE,3,raw_mov_l_Ri,(R4 d, IMM i, IMM offset))
670     {
671     MOVLim(i, offset, d, X86_NOREG, 1);
672     }
673     LENDFUNC(NONE,WRITE,3,raw_mov_l_Ri,(R4 d, IMM i, IMM offset))
674    
675     LOWFUNC(NONE,WRITE,3,raw_mov_w_Ri,(R4 d, IMM i, IMM offset))
676     {
677     MOVWim(i, offset, d, X86_NOREG, 1);
678     }
679     LENDFUNC(NONE,WRITE,3,raw_mov_w_Ri,(R4 d, IMM i, IMM offset))
680    
681     LOWFUNC(NONE,WRITE,3,raw_mov_b_Ri,(R4 d, IMM i, IMM offset))
682     {
683     MOVBim(i, offset, d, X86_NOREG, 1);
684     }
685     LENDFUNC(NONE,WRITE,3,raw_mov_b_Ri,(R4 d, IMM i, IMM offset))
686    
687     LOWFUNC(NONE,WRITE,3,raw_mov_l_Rr,(R4 d, R4 s, IMM offset))
688     {
689     MOVLrm(s, offset, d, X86_NOREG, 1);
690     }
691     LENDFUNC(NONE,WRITE,3,raw_mov_l_Rr,(R4 d, R4 s, IMM offset))
692    
693     LOWFUNC(NONE,WRITE,3,raw_mov_w_Rr,(R4 d, R2 s, IMM offset))
694     {
695     MOVWrm(s, offset, d, X86_NOREG, 1);
696     }
697     LENDFUNC(NONE,WRITE,3,raw_mov_w_Rr,(R4 d, R2 s, IMM offset))
698    
699     LOWFUNC(NONE,WRITE,3,raw_mov_b_Rr,(R4 d, R1 s, IMM offset))
700     {
701     MOVBrm(s, offset, d, X86_NOREG, 1);
702     }
703     LENDFUNC(NONE,WRITE,3,raw_mov_b_Rr,(R4 d, R1 s, IMM offset))
704    
705     LOWFUNC(NONE,NONE,3,raw_lea_l_brr,(W4 d, R4 s, IMM offset))
706     {
707     LEALmr(offset, s, X86_NOREG, 1, d);
708     }
709     LENDFUNC(NONE,NONE,3,raw_lea_l_brr,(W4 d, R4 s, IMM offset))
710    
711     LOWFUNC(NONE,NONE,5,raw_lea_l_brr_indexed,(W4 d, R4 s, R4 index, IMM factor, IMM offset))
712     {
713     LEALmr(offset, s, index, factor, d);
714     }
715     LENDFUNC(NONE,NONE,5,raw_lea_l_brr_indexed,(W4 d, R4 s, R4 index, IMM factor, IMM offset))
716    
717     LOWFUNC(NONE,NONE,4,raw_lea_l_rr_indexed,(W4 d, R4 s, R4 index, IMM factor))
718     {
719     LEALmr(0, s, index, factor, d);
720     }
721     LENDFUNC(NONE,NONE,4,raw_lea_l_rr_indexed,(W4 d, R4 s, R4 index, IMM factor))
722    
723     LOWFUNC(NONE,WRITE,3,raw_mov_l_bRr,(R4 d, R4 s, IMM offset))
724     {
725     MOVLrm(s, offset, d, X86_NOREG, 1);
726     }
727     LENDFUNC(NONE,WRITE,3,raw_mov_l_bRr,(R4 d, R4 s, IMM offset))
728    
729     LOWFUNC(NONE,WRITE,3,raw_mov_w_bRr,(R4 d, R2 s, IMM offset))
730     {
731     MOVWrm(s, offset, d, X86_NOREG, 1);
732     }
733     LENDFUNC(NONE,WRITE,3,raw_mov_w_bRr,(R4 d, R2 s, IMM offset))
734    
735     LOWFUNC(NONE,WRITE,3,raw_mov_b_bRr,(R4 d, R1 s, IMM offset))
736     {
737     MOVBrm(s, offset, d, X86_NOREG, 1);
738     }
739     LENDFUNC(NONE,WRITE,3,raw_mov_b_bRr,(R4 d, R1 s, IMM offset))
740    
741     LOWFUNC(NONE,NONE,1,raw_bswap_32,(RW4 r))
742     {
743     BSWAPLr(r);
744     }
745     LENDFUNC(NONE,NONE,1,raw_bswap_32,(RW4 r))
746    
747     LOWFUNC(WRITE,NONE,1,raw_bswap_16,(RW2 r))
748     {
749     ROLWir(8, r);
750     }
751     LENDFUNC(WRITE,NONE,1,raw_bswap_16,(RW2 r))
752    
753     LOWFUNC(NONE,NONE,2,raw_mov_l_rr,(W4 d, R4 s))
754     {
755     MOVLrr(s, d);
756     }
757     LENDFUNC(NONE,NONE,2,raw_mov_l_rr,(W4 d, R4 s))
758    
759     LOWFUNC(NONE,WRITE,2,raw_mov_l_mr,(IMM d, R4 s))
760     {
761     MOVLrm(s, d, X86_NOREG, X86_NOREG, 1);
762     }
763     LENDFUNC(NONE,WRITE,2,raw_mov_l_mr,(IMM d, R4 s))
764    
765     LOWFUNC(NONE,WRITE,2,raw_mov_w_mr,(IMM d, R2 s))
766     {
767     MOVWrm(s, d, X86_NOREG, X86_NOREG, 1);
768     }
769     LENDFUNC(NONE,WRITE,2,raw_mov_w_mr,(IMM d, R2 s))
770    
771     LOWFUNC(NONE,READ,2,raw_mov_w_rm,(W2 d, IMM s))
772     {
773     MOVWmr(s, X86_NOREG, X86_NOREG, 1, d);
774     }
775     LENDFUNC(NONE,READ,2,raw_mov_w_rm,(W2 d, IMM s))
776    
777     LOWFUNC(NONE,WRITE,2,raw_mov_b_mr,(IMM d, R1 s))
778     {
779     MOVBrm(s, d, X86_NOREG, X86_NOREG, 1);
780     }
781     LENDFUNC(NONE,WRITE,2,raw_mov_b_mr,(IMM d, R1 s))
782    
783     LOWFUNC(NONE,READ,2,raw_mov_b_rm,(W1 d, IMM s))
784     {
785     MOVBmr(s, X86_NOREG, X86_NOREG, 1, d);
786     }
787     LENDFUNC(NONE,READ,2,raw_mov_b_rm,(W1 d, IMM s))
788    
789     LOWFUNC(NONE,NONE,2,raw_mov_l_ri,(W4 d, IMM s))
790     {
791     MOVLir(s, d);
792     }
793     LENDFUNC(NONE,NONE,2,raw_mov_l_ri,(W4 d, IMM s))
794    
795     LOWFUNC(NONE,NONE,2,raw_mov_w_ri,(W2 d, IMM s))
796     {
797     MOVWir(s, d);
798     }
799     LENDFUNC(NONE,NONE,2,raw_mov_w_ri,(W2 d, IMM s))
800    
801     LOWFUNC(NONE,NONE,2,raw_mov_b_ri,(W1 d, IMM s))
802     {
803     MOVBir(s, d);
804     }
805     LENDFUNC(NONE,NONE,2,raw_mov_b_ri,(W1 d, IMM s))
806    
807     LOWFUNC(RMW,RMW,2,raw_adc_l_mi,(MEMRW d, IMM s))
808     {
809     ADCLim(s, d, X86_NOREG, X86_NOREG, 1);
810     }
811     LENDFUNC(RMW,RMW,2,raw_adc_l_mi,(MEMRW d, IMM s))
812    
813     LOWFUNC(WRITE,RMW,2,raw_add_l_mi,(IMM d, IMM s))
814     {
815     ADDLim(s, d, X86_NOREG, X86_NOREG, 1);
816     }
817     LENDFUNC(WRITE,RMW,2,raw_add_l_mi,(IMM d, IMM s))
818    
819     LOWFUNC(WRITE,RMW,2,raw_add_w_mi,(IMM d, IMM s))
820     {
821     ADDWim(s, d, X86_NOREG, X86_NOREG, 1);
822     }
823     LENDFUNC(WRITE,RMW,2,raw_add_w_mi,(IMM d, IMM s))
824    
825     LOWFUNC(WRITE,RMW,2,raw_add_b_mi,(IMM d, IMM s))
826     {
827     ADDBim(s, d, X86_NOREG, X86_NOREG, 1);
828     }
829     LENDFUNC(WRITE,RMW,2,raw_add_b_mi,(IMM d, IMM s))
830    
831     LOWFUNC(WRITE,NONE,2,raw_test_l_ri,(R4 d, IMM i))
832     {
833     TESTLir(i, d);
834     }
835     LENDFUNC(WRITE,NONE,2,raw_test_l_ri,(R4 d, IMM i))
836    
837     LOWFUNC(WRITE,NONE,2,raw_test_l_rr,(R4 d, R4 s))
838     {
839     TESTLrr(s, d);
840     }
841     LENDFUNC(WRITE,NONE,2,raw_test_l_rr,(R4 d, R4 s))
842    
843     LOWFUNC(WRITE,NONE,2,raw_test_w_rr,(R2 d, R2 s))
844     {
845     TESTWrr(s, d);
846     }
847     LENDFUNC(WRITE,NONE,2,raw_test_w_rr,(R2 d, R2 s))
848    
849     LOWFUNC(WRITE,NONE,2,raw_test_b_rr,(R1 d, R1 s))
850     {
851     TESTBrr(s, d);
852     }
853     LENDFUNC(WRITE,NONE,2,raw_test_b_rr,(R1 d, R1 s))
854    
855     LOWFUNC(WRITE,NONE,2,raw_and_l_ri,(RW4 d, IMM i))
856     {
857     ANDLir(i, d);
858     }
859     LENDFUNC(WRITE,NONE,2,raw_and_l_ri,(RW4 d, IMM i))
860    
861     LOWFUNC(WRITE,NONE,2,raw_and_w_ri,(RW2 d, IMM i))
862     {
863     ANDWir(i, d);
864     }
865     LENDFUNC(WRITE,NONE,2,raw_and_w_ri,(RW2 d, IMM i))
866    
867     LOWFUNC(WRITE,NONE,2,raw_and_l,(RW4 d, R4 s))
868     {
869     ANDLrr(s, d);
870     }
871     LENDFUNC(WRITE,NONE,2,raw_and_l,(RW4 d, R4 s))
872    
873     LOWFUNC(WRITE,NONE,2,raw_and_w,(RW2 d, R2 s))
874     {
875     ANDWrr(s, d);
876     }
877     LENDFUNC(WRITE,NONE,2,raw_and_w,(RW2 d, R2 s))
878    
879     LOWFUNC(WRITE,NONE,2,raw_and_b,(RW1 d, R1 s))
880     {
881     ANDBrr(s, d);
882     }
883     LENDFUNC(WRITE,NONE,2,raw_and_b,(RW1 d, R1 s))
884    
885     LOWFUNC(WRITE,NONE,2,raw_or_l_ri,(RW4 d, IMM i))
886     {
887     ORLir(i, d);
888     }
889     LENDFUNC(WRITE,NONE,2,raw_or_l_ri,(RW4 d, IMM i))
890    
891     LOWFUNC(WRITE,NONE,2,raw_or_l,(RW4 d, R4 s))
892     {
893     ORLrr(s, d);
894     }
895     LENDFUNC(WRITE,NONE,2,raw_or_l,(RW4 d, R4 s))
896    
897     LOWFUNC(WRITE,NONE,2,raw_or_w,(RW2 d, R2 s))
898     {
899     ORWrr(s, d);
900     }
901     LENDFUNC(WRITE,NONE,2,raw_or_w,(RW2 d, R2 s))
902    
903     LOWFUNC(WRITE,NONE,2,raw_or_b,(RW1 d, R1 s))
904     {
905     ORBrr(s, d);
906     }
907     LENDFUNC(WRITE,NONE,2,raw_or_b,(RW1 d, R1 s))
908    
909     LOWFUNC(RMW,NONE,2,raw_adc_l,(RW4 d, R4 s))
910     {
911     ADCLrr(s, d);
912     }
913     LENDFUNC(RMW,NONE,2,raw_adc_l,(RW4 d, R4 s))
914    
915     LOWFUNC(RMW,NONE,2,raw_adc_w,(RW2 d, R2 s))
916     {
917     ADCWrr(s, d);
918     }
919     LENDFUNC(RMW,NONE,2,raw_adc_w,(RW2 d, R2 s))
920    
921     LOWFUNC(RMW,NONE,2,raw_adc_b,(RW1 d, R1 s))
922     {
923     ADCBrr(s, d);
924     }
925     LENDFUNC(RMW,NONE,2,raw_adc_b,(RW1 d, R1 s))
926    
927     LOWFUNC(WRITE,NONE,2,raw_add_l,(RW4 d, R4 s))
928     {
929     ADDLrr(s, d);
930     }
931     LENDFUNC(WRITE,NONE,2,raw_add_l,(RW4 d, R4 s))
932    
933     LOWFUNC(WRITE,NONE,2,raw_add_w,(RW2 d, R2 s))
934     {
935     ADDWrr(s, d);
936     }
937     LENDFUNC(WRITE,NONE,2,raw_add_w,(RW2 d, R2 s))
938    
939     LOWFUNC(WRITE,NONE,2,raw_add_b,(RW1 d, R1 s))
940     {
941     ADDBrr(s, d);
942     }
943     LENDFUNC(WRITE,NONE,2,raw_add_b,(RW1 d, R1 s))
944    
945     LOWFUNC(WRITE,NONE,2,raw_sub_l_ri,(RW4 d, IMM i))
946     {
947     SUBLir(i, d);
948     }
949     LENDFUNC(WRITE,NONE,2,raw_sub_l_ri,(RW4 d, IMM i))
950    
951     LOWFUNC(WRITE,NONE,2,raw_sub_b_ri,(RW1 d, IMM i))
952     {
953     SUBBir(i, d);
954     }
955     LENDFUNC(WRITE,NONE,2,raw_sub_b_ri,(RW1 d, IMM i))
956    
957     LOWFUNC(WRITE,NONE,2,raw_add_l_ri,(RW4 d, IMM i))
958     {
959     ADDLir(i, d);
960     }
961     LENDFUNC(WRITE,NONE,2,raw_add_l_ri,(RW4 d, IMM i))
962    
963     LOWFUNC(WRITE,NONE,2,raw_add_w_ri,(RW2 d, IMM i))
964     {
965     ADDWir(i, d);
966     }
967     LENDFUNC(WRITE,NONE,2,raw_add_w_ri,(RW2 d, IMM i))
968    
969     LOWFUNC(WRITE,NONE,2,raw_add_b_ri,(RW1 d, IMM i))
970     {
971     ADDBir(i, d);
972     }
973     LENDFUNC(WRITE,NONE,2,raw_add_b_ri,(RW1 d, IMM i))
974    
975     LOWFUNC(RMW,NONE,2,raw_sbb_l,(RW4 d, R4 s))
976     {
977     SBBLrr(s, d);
978     }
979     LENDFUNC(RMW,NONE,2,raw_sbb_l,(RW4 d, R4 s))
980    
981     LOWFUNC(RMW,NONE,2,raw_sbb_w,(RW2 d, R2 s))
982     {
983     SBBWrr(s, d);
984     }
985     LENDFUNC(RMW,NONE,2,raw_sbb_w,(RW2 d, R2 s))
986    
987     LOWFUNC(RMW,NONE,2,raw_sbb_b,(RW1 d, R1 s))
988     {
989     SBBBrr(s, d);
990     }
991     LENDFUNC(RMW,NONE,2,raw_sbb_b,(RW1 d, R1 s))
992    
993     LOWFUNC(WRITE,NONE,2,raw_sub_l,(RW4 d, R4 s))
994     {
995     SUBLrr(s, d);
996     }
997     LENDFUNC(WRITE,NONE,2,raw_sub_l,(RW4 d, R4 s))
998    
999     LOWFUNC(WRITE,NONE,2,raw_sub_w,(RW2 d, R2 s))
1000     {
1001     SUBWrr(s, d);
1002     }
1003     LENDFUNC(WRITE,NONE,2,raw_sub_w,(RW2 d, R2 s))
1004    
1005     LOWFUNC(WRITE,NONE,2,raw_sub_b,(RW1 d, R1 s))
1006     {
1007     SUBBrr(s, d);
1008     }
1009     LENDFUNC(WRITE,NONE,2,raw_sub_b,(RW1 d, R1 s))
1010    
1011     LOWFUNC(WRITE,NONE,2,raw_cmp_l,(R4 d, R4 s))
1012     {
1013     CMPLrr(s, d);
1014     }
1015     LENDFUNC(WRITE,NONE,2,raw_cmp_l,(R4 d, R4 s))
1016    
1017     LOWFUNC(WRITE,NONE,2,raw_cmp_l_ri,(R4 r, IMM i))
1018     {
1019     CMPLir(i, r);
1020     }
1021     LENDFUNC(WRITE,NONE,2,raw_cmp_l_ri,(R4 r, IMM i))
1022    
1023     LOWFUNC(WRITE,NONE,2,raw_cmp_w,(R2 d, R2 s))
1024     {
1025     CMPWrr(s, d);
1026     }
1027     LENDFUNC(WRITE,NONE,2,raw_cmp_w,(R2 d, R2 s))
1028    
1029     LOWFUNC(WRITE,READ,2,raw_cmp_b_mi,(MEMR d, IMM s))
1030     {
1031     CMPBim(s, d, X86_NOREG, X86_NOREG, 1);
1032     }
1033     LENDFUNC(WRITE,READ,2,raw_cmp_l_mi,(MEMR d, IMM s))
1034    
1035     LOWFUNC(WRITE,NONE,2,raw_cmp_b_ri,(R1 d, IMM i))
1036     {
1037     CMPBir(i, d);
1038     }
1039     LENDFUNC(WRITE,NONE,2,raw_cmp_b_ri,(R1 d, IMM i))
1040    
1041     LOWFUNC(WRITE,NONE,2,raw_cmp_b,(R1 d, R1 s))
1042     {
1043     CMPBrr(s, d);
1044     }
1045     LENDFUNC(WRITE,NONE,2,raw_cmp_b,(R1 d, R1 s))
1046    
1047     LOWFUNC(WRITE,READ,4,raw_cmp_l_rm_indexed,(R4 d, IMM offset, R4 index, IMM factor))
1048     {
1049     CMPLmr(offset, X86_NOREG, index, factor, d);
1050     }
1051     LENDFUNC(WRITE,READ,4,raw_cmp_l_rm_indexed,(R4 d, IMM offset, R4 index, IMM factor))
1052    
1053     LOWFUNC(WRITE,NONE,2,raw_xor_l,(RW4 d, R4 s))
1054     {
1055     XORLrr(s, d);
1056     }
1057     LENDFUNC(WRITE,NONE,2,raw_xor_l,(RW4 d, R4 s))
1058    
1059     LOWFUNC(WRITE,NONE,2,raw_xor_w,(RW2 d, R2 s))
1060     {
1061     XORWrr(s, d);
1062     }
1063     LENDFUNC(WRITE,NONE,2,raw_xor_w,(RW2 d, R2 s))
1064    
1065     LOWFUNC(WRITE,NONE,2,raw_xor_b,(RW1 d, R1 s))
1066     {
1067     XORBrr(s, d);
1068     }
1069     LENDFUNC(WRITE,NONE,2,raw_xor_b,(RW1 d, R1 s))
1070    
1071     LOWFUNC(WRITE,RMW,2,raw_sub_l_mi,(MEMRW d, IMM s))
1072     {
1073     SUBLim(s, d, X86_NOREG, X86_NOREG, 1);
1074     }
1075     LENDFUNC(WRITE,RMW,2,raw_sub_l_mi,(MEMRW d, IMM s))
1076    
1077     LOWFUNC(WRITE,READ,2,raw_cmp_l_mi,(MEMR d, IMM s))
1078     {
1079     CMPLim(s, d, X86_NOREG, X86_NOREG, 1);
1080     }
1081     LENDFUNC(WRITE,READ,2,raw_cmp_l_mi,(MEMR d, IMM s))
1082    
1083     LOWFUNC(NONE,NONE,2,raw_xchg_l_rr,(RW4 r1, RW4 r2))
1084     {
1085     XCHGLrr(r2, r1);
1086     }
1087     LENDFUNC(NONE,NONE,2,raw_xchg_l_rr,(RW4 r1, RW4 r2))
1088    
1089     LOWFUNC(READ,WRITE,0,raw_pushfl,(void))
1090     {
1091     PUSHFD();
1092     }
1093     LENDFUNC(READ,WRITE,0,raw_pushfl,(void))
1094    
1095     LOWFUNC(WRITE,READ,0,raw_popfl,(void))
1096     {
1097     POPFD();
1098     }
1099     LENDFUNC(WRITE,READ,0,raw_popfl,(void))
1100    
1101     #else
1102    
1103 gbeauche 1.2 const bool optimize_accum = true;
1104 gbeauche 1.1 const bool optimize_imm8 = true;
1105     const bool optimize_shift_once = true;
1106    
1107     /*************************************************************************
1108     * Actual encoding of the instructions on the target CPU *
1109     *************************************************************************/
1110    
1111 gbeauche 1.2 static __inline__ int isaccum(int r)
1112     {
1113     return (r == EAX_INDEX);
1114     }
1115    
1116 gbeauche 1.1 static __inline__ int isbyte(uae_s32 x)
1117     {
1118     return (x>=-128 && x<=127);
1119     }
1120    
1121     static __inline__ int isword(uae_s32 x)
1122     {
1123     return (x>=-32768 && x<=32767);
1124     }
1125    
1126     LOWFUNC(NONE,WRITE,1,raw_push_l_r,(R4 r))
1127     {
1128     emit_byte(0x50+r);
1129     }
1130     LENDFUNC(NONE,WRITE,1,raw_push_l_r,(R4 r))
1131    
1132     LOWFUNC(NONE,READ,1,raw_pop_l_r,(R4 r))
1133     {
1134     emit_byte(0x58+r);
1135     }
1136     LENDFUNC(NONE,READ,1,raw_pop_l_r,(R4 r))
1137    
1138     LOWFUNC(WRITE,NONE,2,raw_bt_l_ri,(R4 r, IMM i))
1139     {
1140     emit_byte(0x0f);
1141     emit_byte(0xba);
1142     emit_byte(0xe0+r);
1143     emit_byte(i);
1144     }
1145     LENDFUNC(WRITE,NONE,2,raw_bt_l_ri,(R4 r, IMM i))
1146    
1147     LOWFUNC(WRITE,NONE,2,raw_bt_l_rr,(R4 r, R4 b))
1148     {
1149     emit_byte(0x0f);
1150     emit_byte(0xa3);
1151     emit_byte(0xc0+8*b+r);
1152     }
1153     LENDFUNC(WRITE,NONE,2,raw_bt_l_rr,(R4 r, R4 b))
1154    
1155     LOWFUNC(WRITE,NONE,2,raw_btc_l_ri,(RW4 r, IMM i))
1156     {
1157     emit_byte(0x0f);
1158     emit_byte(0xba);
1159     emit_byte(0xf8+r);
1160     emit_byte(i);
1161     }
1162     LENDFUNC(WRITE,NONE,2,raw_btc_l_ri,(RW4 r, IMM i))
1163    
1164     LOWFUNC(WRITE,NONE,2,raw_btc_l_rr,(RW4 r, R4 b))
1165     {
1166     emit_byte(0x0f);
1167     emit_byte(0xbb);
1168     emit_byte(0xc0+8*b+r);
1169     }
1170     LENDFUNC(WRITE,NONE,2,raw_btc_l_rr,(RW4 r, R4 b))
1171    
1172    
1173     LOWFUNC(WRITE,NONE,2,raw_btr_l_ri,(RW4 r, IMM i))
1174     {
1175     emit_byte(0x0f);
1176     emit_byte(0xba);
1177     emit_byte(0xf0+r);
1178     emit_byte(i);
1179     }
1180     LENDFUNC(WRITE,NONE,2,raw_btr_l_ri,(RW4 r, IMM i))
1181    
1182     LOWFUNC(WRITE,NONE,2,raw_btr_l_rr,(RW4 r, R4 b))
1183     {
1184     emit_byte(0x0f);
1185     emit_byte(0xb3);
1186     emit_byte(0xc0+8*b+r);
1187     }
1188     LENDFUNC(WRITE,NONE,2,raw_btr_l_rr,(RW4 r, R4 b))
1189    
1190     LOWFUNC(WRITE,NONE,2,raw_bts_l_ri,(RW4 r, IMM i))
1191     {
1192     emit_byte(0x0f);
1193     emit_byte(0xba);
1194     emit_byte(0xe8+r);
1195     emit_byte(i);
1196     }
1197     LENDFUNC(WRITE,NONE,2,raw_bts_l_ri,(RW4 r, IMM i))
1198    
1199     LOWFUNC(WRITE,NONE,2,raw_bts_l_rr,(RW4 r, R4 b))
1200     {
1201     emit_byte(0x0f);
1202     emit_byte(0xab);
1203     emit_byte(0xc0+8*b+r);
1204     }
1205     LENDFUNC(WRITE,NONE,2,raw_bts_l_rr,(RW4 r, R4 b))
1206    
1207     LOWFUNC(WRITE,NONE,2,raw_sub_w_ri,(RW2 d, IMM i))
1208     {
1209     emit_byte(0x66);
1210     if (isbyte(i)) {
1211     emit_byte(0x83);
1212     emit_byte(0xe8+d);
1213     emit_byte(i);
1214     }
1215     else {
1216 gbeauche 1.2 if (optimize_accum && isaccum(d))
1217     emit_byte(0x2d);
1218     else {
1219 gbeauche 1.1 emit_byte(0x81);
1220     emit_byte(0xe8+d);
1221 gbeauche 1.2 }
1222 gbeauche 1.1 emit_word(i);
1223     }
1224     }
1225     LENDFUNC(WRITE,NONE,2,raw_sub_w_ri,(RW2 d, IMM i))
1226    
1227    
1228     LOWFUNC(NONE,READ,2,raw_mov_l_rm,(W4 d, MEMR s))
1229     {
1230     emit_byte(0x8b);
1231     emit_byte(0x05+8*d);
1232     emit_long(s);
1233     }
1234     LENDFUNC(NONE,READ,2,raw_mov_l_rm,(W4 d, MEMR s))
1235    
1236     LOWFUNC(NONE,WRITE,2,raw_mov_l_mi,(MEMW d, IMM s))
1237     {
1238     emit_byte(0xc7);
1239     emit_byte(0x05);
1240     emit_long(d);
1241     emit_long(s);
1242     }
1243     LENDFUNC(NONE,WRITE,2,raw_mov_l_mi,(MEMW d, IMM s))
1244    
1245     LOWFUNC(NONE,WRITE,2,raw_mov_w_mi,(MEMW d, IMM s))
1246     {
1247     emit_byte(0x66);
1248     emit_byte(0xc7);
1249     emit_byte(0x05);
1250     emit_long(d);
1251     emit_word(s);
1252     }
1253     LENDFUNC(NONE,WRITE,2,raw_mov_w_mi,(MEMW d, IMM s))
1254    
1255     LOWFUNC(NONE,WRITE,2,raw_mov_b_mi,(MEMW d, IMM s))
1256     {
1257     emit_byte(0xc6);
1258     emit_byte(0x05);
1259     emit_long(d);
1260     emit_byte(s);
1261     }
1262     LENDFUNC(NONE,WRITE,2,raw_mov_b_mi,(MEMW d, IMM s))
1263    
1264     LOWFUNC(WRITE,RMW,2,raw_rol_b_mi,(MEMRW d, IMM i))
1265     {
1266     if (optimize_shift_once && (i == 1)) {
1267     emit_byte(0xd0);
1268     emit_byte(0x05);
1269     emit_long(d);
1270     }
1271     else {
1272     emit_byte(0xc0);
1273     emit_byte(0x05);
1274     emit_long(d);
1275     emit_byte(i);
1276     }
1277     }
1278     LENDFUNC(WRITE,RMW,2,raw_rol_b_mi,(MEMRW d, IMM i))
1279    
1280     LOWFUNC(WRITE,NONE,2,raw_rol_b_ri,(RW1 r, IMM i))
1281     {
1282     if (optimize_shift_once && (i == 1)) {
1283     emit_byte(0xd0);
1284     emit_byte(0xc0+r);
1285     }
1286     else {
1287     emit_byte(0xc0);
1288     emit_byte(0xc0+r);
1289     emit_byte(i);
1290     }
1291     }
1292     LENDFUNC(WRITE,NONE,2,raw_rol_b_ri,(RW1 r, IMM i))
1293    
1294     LOWFUNC(WRITE,NONE,2,raw_rol_w_ri,(RW2 r, IMM i))
1295     {
1296     emit_byte(0x66);
1297     emit_byte(0xc1);
1298     emit_byte(0xc0+r);
1299     emit_byte(i);
1300     }
1301     LENDFUNC(WRITE,NONE,2,raw_rol_w_ri,(RW2 r, IMM i))
1302    
1303     LOWFUNC(WRITE,NONE,2,raw_rol_l_ri,(RW4 r, IMM i))
1304     {
1305     if (optimize_shift_once && (i == 1)) {
1306     emit_byte(0xd1);
1307     emit_byte(0xc0+r);
1308     }
1309     else {
1310     emit_byte(0xc1);
1311     emit_byte(0xc0+r);
1312     emit_byte(i);
1313     }
1314     }
1315     LENDFUNC(WRITE,NONE,2,raw_rol_l_ri,(RW4 r, IMM i))
1316    
1317     LOWFUNC(WRITE,NONE,2,raw_rol_l_rr,(RW4 d, R1 r))
1318     {
1319     emit_byte(0xd3);
1320     emit_byte(0xc0+d);
1321     }
1322     LENDFUNC(WRITE,NONE,2,raw_rol_l_rr,(RW4 d, R1 r))
1323    
1324     LOWFUNC(WRITE,NONE,2,raw_rol_w_rr,(RW2 d, R1 r))
1325     {
1326     emit_byte(0x66);
1327     emit_byte(0xd3);
1328     emit_byte(0xc0+d);
1329     }
1330     LENDFUNC(WRITE,NONE,2,raw_rol_w_rr,(RW2 d, R1 r))
1331    
1332     LOWFUNC(WRITE,NONE,2,raw_rol_b_rr,(RW1 d, R1 r))
1333     {
1334     emit_byte(0xd2);
1335     emit_byte(0xc0+d);
1336     }
1337     LENDFUNC(WRITE,NONE,2,raw_rol_b_rr,(RW1 d, R1 r))
1338    
1339     LOWFUNC(WRITE,NONE,2,raw_shll_l_rr,(RW4 d, R1 r))
1340     {
1341     emit_byte(0xd3);
1342     emit_byte(0xe0+d);
1343     }
1344     LENDFUNC(WRITE,NONE,2,raw_shll_l_rr,(RW4 d, R1 r))
1345    
1346     LOWFUNC(WRITE,NONE,2,raw_shll_w_rr,(RW2 d, R1 r))
1347     {
1348     emit_byte(0x66);
1349     emit_byte(0xd3);
1350     emit_byte(0xe0+d);
1351     }
1352     LENDFUNC(WRITE,NONE,2,raw_shll_w_rr,(RW2 d, R1 r))
1353    
1354     LOWFUNC(WRITE,NONE,2,raw_shll_b_rr,(RW1 d, R1 r))
1355     {
1356     emit_byte(0xd2);
1357     emit_byte(0xe0+d);
1358     }
1359     LENDFUNC(WRITE,NONE,2,raw_shll_b_rr,(RW1 d, R1 r))
1360    
1361     LOWFUNC(WRITE,NONE,2,raw_ror_b_ri,(RW1 r, IMM i))
1362     {
1363     if (optimize_shift_once && (i == 1)) {
1364     emit_byte(0xd0);
1365     emit_byte(0xc8+r);
1366     }
1367     else {
1368     emit_byte(0xc0);
1369     emit_byte(0xc8+r);
1370     emit_byte(i);
1371     }
1372     }
1373     LENDFUNC(WRITE,NONE,2,raw_ror_b_ri,(RW1 r, IMM i))
1374    
1375     LOWFUNC(WRITE,NONE,2,raw_ror_w_ri,(RW2 r, IMM i))
1376     {
1377     emit_byte(0x66);
1378     emit_byte(0xc1);
1379     emit_byte(0xc8+r);
1380     emit_byte(i);
1381     }
1382     LENDFUNC(WRITE,NONE,2,raw_ror_w_ri,(RW2 r, IMM i))
1383    
1384     // gb-- used for making an fpcr value in compemu_fpp.cpp
1385     LOWFUNC(WRITE,READ,2,raw_or_l_rm,(RW4 d, MEMR s))
1386     {
1387     emit_byte(0x0b);
1388     emit_byte(0x05+8*d);
1389     emit_long(s);
1390     }
1391     LENDFUNC(WRITE,READ,2,raw_or_l_rm,(RW4 d, MEMR s))
1392    
1393     LOWFUNC(WRITE,NONE,2,raw_ror_l_ri,(RW4 r, IMM i))
1394     {
1395     if (optimize_shift_once && (i == 1)) {
1396     emit_byte(0xd1);
1397     emit_byte(0xc8+r);
1398     }
1399     else {
1400     emit_byte(0xc1);
1401     emit_byte(0xc8+r);
1402     emit_byte(i);
1403     }
1404     }
1405     LENDFUNC(WRITE,NONE,2,raw_ror_l_ri,(RW4 r, IMM i))
1406    
1407     LOWFUNC(WRITE,NONE,2,raw_ror_l_rr,(RW4 d, R1 r))
1408     {
1409     emit_byte(0xd3);
1410     emit_byte(0xc8+d);
1411     }
1412     LENDFUNC(WRITE,NONE,2,raw_ror_l_rr,(RW4 d, R1 r))
1413    
1414     LOWFUNC(WRITE,NONE,2,raw_ror_w_rr,(RW2 d, R1 r))
1415     {
1416     emit_byte(0x66);
1417     emit_byte(0xd3);
1418     emit_byte(0xc8+d);
1419     }
1420     LENDFUNC(WRITE,NONE,2,raw_ror_w_rr,(RW2 d, R1 r))
1421    
1422     LOWFUNC(WRITE,NONE,2,raw_ror_b_rr,(RW1 d, R1 r))
1423     {
1424     emit_byte(0xd2);
1425     emit_byte(0xc8+d);
1426     }
1427     LENDFUNC(WRITE,NONE,2,raw_ror_b_rr,(RW1 d, R1 r))
1428    
1429     LOWFUNC(WRITE,NONE,2,raw_shrl_l_rr,(RW4 d, R1 r))
1430     {
1431     emit_byte(0xd3);
1432     emit_byte(0xe8+d);
1433     }
1434     LENDFUNC(WRITE,NONE,2,raw_shrl_l_rr,(RW4 d, R1 r))
1435    
1436     LOWFUNC(WRITE,NONE,2,raw_shrl_w_rr,(RW2 d, R1 r))
1437     {
1438     emit_byte(0x66);
1439     emit_byte(0xd3);
1440     emit_byte(0xe8+d);
1441     }
1442     LENDFUNC(WRITE,NONE,2,raw_shrl_w_rr,(RW2 d, R1 r))
1443    
1444     LOWFUNC(WRITE,NONE,2,raw_shrl_b_rr,(RW1 d, R1 r))
1445     {
1446     emit_byte(0xd2);
1447     emit_byte(0xe8+d);
1448     }
1449     LENDFUNC(WRITE,NONE,2,raw_shrl_b_rr,(RW1 d, R1 r))
1450    
1451     LOWFUNC(WRITE,NONE,2,raw_shra_l_rr,(RW4 d, R1 r))
1452     {
1453     emit_byte(0xd3);
1454     emit_byte(0xf8+d);
1455     }
1456     LENDFUNC(WRITE,NONE,2,raw_shra_l_rr,(RW4 d, R1 r))
1457    
1458     LOWFUNC(WRITE,NONE,2,raw_shra_w_rr,(RW2 d, R1 r))
1459     {
1460     emit_byte(0x66);
1461     emit_byte(0xd3);
1462     emit_byte(0xf8+d);
1463     }
1464     LENDFUNC(WRITE,NONE,2,raw_shra_w_rr,(RW2 d, R1 r))
1465    
1466     LOWFUNC(WRITE,NONE,2,raw_shra_b_rr,(RW1 d, R1 r))
1467     {
1468     emit_byte(0xd2);
1469     emit_byte(0xf8+d);
1470     }
1471     LENDFUNC(WRITE,NONE,2,raw_shra_b_rr,(RW1 d, R1 r))
1472    
1473     LOWFUNC(WRITE,NONE,2,raw_shll_l_ri,(RW4 r, IMM i))
1474     {
1475     if (optimize_shift_once && (i == 1)) {
1476     emit_byte(0xd1);
1477     emit_byte(0xe0+r);
1478     }
1479     else {
1480     emit_byte(0xc1);
1481     emit_byte(0xe0+r);
1482     emit_byte(i);
1483     }
1484     }
1485     LENDFUNC(WRITE,NONE,2,raw_shll_l_ri,(RW4 r, IMM i))
1486    
1487     LOWFUNC(WRITE,NONE,2,raw_shll_w_ri,(RW2 r, IMM i))
1488     {
1489     emit_byte(0x66);
1490     emit_byte(0xc1);
1491     emit_byte(0xe0+r);
1492     emit_byte(i);
1493     }
1494     LENDFUNC(WRITE,NONE,2,raw_shll_w_ri,(RW2 r, IMM i))
1495    
1496     LOWFUNC(WRITE,NONE,2,raw_shll_b_ri,(RW1 r, IMM i))
1497     {
1498     if (optimize_shift_once && (i == 1)) {
1499     emit_byte(0xd0);
1500     emit_byte(0xe0+r);
1501     }
1502     else {
1503     emit_byte(0xc0);
1504     emit_byte(0xe0+r);
1505     emit_byte(i);
1506     }
1507     }
1508     LENDFUNC(WRITE,NONE,2,raw_shll_b_ri,(RW1 r, IMM i))
1509    
1510     LOWFUNC(WRITE,NONE,2,raw_shrl_l_ri,(RW4 r, IMM i))
1511     {
1512     if (optimize_shift_once && (i == 1)) {
1513     emit_byte(0xd1);
1514     emit_byte(0xe8+r);
1515     }
1516     else {
1517     emit_byte(0xc1);
1518     emit_byte(0xe8+r);
1519     emit_byte(i);
1520     }
1521     }
1522     LENDFUNC(WRITE,NONE,2,raw_shrl_l_ri,(RW4 r, IMM i))
1523    
1524     LOWFUNC(WRITE,NONE,2,raw_shrl_w_ri,(RW2 r, IMM i))
1525     {
1526     emit_byte(0x66);
1527     emit_byte(0xc1);
1528     emit_byte(0xe8+r);
1529     emit_byte(i);
1530     }
1531     LENDFUNC(WRITE,NONE,2,raw_shrl_w_ri,(RW2 r, IMM i))
1532    
1533     LOWFUNC(WRITE,NONE,2,raw_shrl_b_ri,(RW1 r, IMM i))
1534     {
1535     if (optimize_shift_once && (i == 1)) {
1536     emit_byte(0xd0);
1537     emit_byte(0xe8+r);
1538     }
1539     else {
1540     emit_byte(0xc0);
1541     emit_byte(0xe8+r);
1542     emit_byte(i);
1543     }
1544     }
1545     LENDFUNC(WRITE,NONE,2,raw_shrl_b_ri,(RW1 r, IMM i))
1546    
1547     LOWFUNC(WRITE,NONE,2,raw_shra_l_ri,(RW4 r, IMM i))
1548     {
1549     if (optimize_shift_once && (i == 1)) {
1550     emit_byte(0xd1);
1551     emit_byte(0xf8+r);
1552     }
1553     else {
1554     emit_byte(0xc1);
1555     emit_byte(0xf8+r);
1556     emit_byte(i);
1557     }
1558     }
1559     LENDFUNC(WRITE,NONE,2,raw_shra_l_ri,(RW4 r, IMM i))
1560    
1561     LOWFUNC(WRITE,NONE,2,raw_shra_w_ri,(RW2 r, IMM i))
1562     {
1563     emit_byte(0x66);
1564     emit_byte(0xc1);
1565     emit_byte(0xf8+r);
1566     emit_byte(i);
1567     }
1568     LENDFUNC(WRITE,NONE,2,raw_shra_w_ri,(RW2 r, IMM i))
1569    
1570     LOWFUNC(WRITE,NONE,2,raw_shra_b_ri,(RW1 r, IMM i))
1571     {
1572     if (optimize_shift_once && (i == 1)) {
1573     emit_byte(0xd0);
1574     emit_byte(0xf8+r);
1575     }
1576     else {
1577     emit_byte(0xc0);
1578     emit_byte(0xf8+r);
1579     emit_byte(i);
1580     }
1581     }
1582     LENDFUNC(WRITE,NONE,2,raw_shra_b_ri,(RW1 r, IMM i))
1583    
1584     LOWFUNC(WRITE,NONE,1,raw_sahf,(R2 dummy_ah))
1585     {
1586     emit_byte(0x9e);
1587     }
1588     LENDFUNC(WRITE,NONE,1,raw_sahf,(R2 dummy_ah))
1589    
1590     LOWFUNC(NONE,NONE,1,raw_cpuid,(R4 dummy_eax))
1591     {
1592     emit_byte(0x0f);
1593     emit_byte(0xa2);
1594     }
1595     LENDFUNC(NONE,NONE,1,raw_cpuid,(R4 dummy_eax))
1596    
1597     LOWFUNC(READ,NONE,1,raw_lahf,(W2 dummy_ah))
1598     {
1599     emit_byte(0x9f);
1600     }
1601     LENDFUNC(READ,NONE,1,raw_lahf,(W2 dummy_ah))
1602    
1603     LOWFUNC(READ,NONE,2,raw_setcc,(W1 d, IMM cc))
1604     {
1605     emit_byte(0x0f);
1606     emit_byte(0x90+cc);
1607     emit_byte(0xc0+d);
1608     }
1609     LENDFUNC(READ,NONE,2,raw_setcc,(W1 d, IMM cc))
1610    
1611     LOWFUNC(READ,WRITE,2,raw_setcc_m,(MEMW d, IMM cc))
1612     {
1613     emit_byte(0x0f);
1614     emit_byte(0x90+cc);
1615     emit_byte(0x05);
1616     emit_long(d);
1617     }
1618     LENDFUNC(READ,WRITE,2,raw_setcc_m,(MEMW d, IMM cc))
1619    
1620     LOWFUNC(READ,NONE,3,raw_cmov_l_rr,(RW4 d, R4 s, IMM cc))
1621     {
1622     if (have_cmov) {
1623     emit_byte(0x0f);
1624     emit_byte(0x40+cc);
1625     emit_byte(0xc0+8*d+s);
1626     }
1627     else { /* replacement using branch and mov */
1628     int uncc=(cc^1);
1629     emit_byte(0x70+uncc);
1630     emit_byte(2); /* skip next 2 bytes if not cc=true */
1631     emit_byte(0x89);
1632     emit_byte(0xc0+8*s+d);
1633     }
1634     }
1635     LENDFUNC(READ,NONE,3,raw_cmov_l_rr,(RW4 d, R4 s, IMM cc))
1636    
1637     LOWFUNC(WRITE,NONE,2,raw_bsf_l_rr,(W4 d, R4 s))
1638     {
1639     emit_byte(0x0f);
1640     emit_byte(0xbc);
1641     emit_byte(0xc0+8*d+s);
1642     }
1643     LENDFUNC(WRITE,NONE,2,raw_bsf_l_rr,(W4 d, R4 s))
1644    
1645     LOWFUNC(NONE,NONE,2,raw_sign_extend_16_rr,(W4 d, R2 s))
1646     {
1647     emit_byte(0x0f);
1648     emit_byte(0xbf);
1649     emit_byte(0xc0+8*d+s);
1650     }
1651     LENDFUNC(NONE,NONE,2,raw_sign_extend_16_rr,(W4 d, R2 s))
1652    
1653     LOWFUNC(NONE,NONE,2,raw_sign_extend_8_rr,(W4 d, R1 s))
1654     {
1655     emit_byte(0x0f);
1656     emit_byte(0xbe);
1657     emit_byte(0xc0+8*d+s);
1658     }
1659     LENDFUNC(NONE,NONE,2,raw_sign_extend_8_rr,(W4 d, R1 s))
1660    
1661     LOWFUNC(NONE,NONE,2,raw_zero_extend_16_rr,(W4 d, R2 s))
1662     {
1663     emit_byte(0x0f);
1664     emit_byte(0xb7);
1665     emit_byte(0xc0+8*d+s);
1666     }
1667     LENDFUNC(NONE,NONE,2,raw_zero_extend_16_rr,(W4 d, R2 s))
1668    
1669     LOWFUNC(NONE,NONE,2,raw_zero_extend_8_rr,(W4 d, R1 s))
1670     {
1671     emit_byte(0x0f);
1672     emit_byte(0xb6);
1673     emit_byte(0xc0+8*d+s);
1674     }
1675     LENDFUNC(NONE,NONE,2,raw_zero_extend_8_rr,(W4 d, R1 s))
1676    
1677     LOWFUNC(NONE,NONE,2,raw_imul_32_32,(RW4 d, R4 s))
1678     {
1679     emit_byte(0x0f);
1680     emit_byte(0xaf);
1681     emit_byte(0xc0+8*d+s);
1682     }
1683     LENDFUNC(NONE,NONE,2,raw_imul_32_32,(RW4 d, R4 s))
1684    
1685     LOWFUNC(NONE,NONE,2,raw_imul_64_32,(RW4 d, RW4 s))
1686     {
1687     if (d!=MUL_NREG1 || s!=MUL_NREG2)
1688     abort();
1689     emit_byte(0xf7);
1690     emit_byte(0xea);
1691     }
1692     LENDFUNC(NONE,NONE,2,raw_imul_64_32,(RW4 d, RW4 s))
1693    
1694     LOWFUNC(NONE,NONE,2,raw_mul_64_32,(RW4 d, RW4 s))
1695     {
1696     if (d!=MUL_NREG1 || s!=MUL_NREG2) {
1697     printf("Bad register in MUL: d=%d, s=%d\n",d,s);
1698     abort();
1699     }
1700     emit_byte(0xf7);
1701     emit_byte(0xe2);
1702     }
1703     LENDFUNC(NONE,NONE,2,raw_mul_64_32,(RW4 d, RW4 s))
1704    
1705     LOWFUNC(NONE,NONE,2,raw_mul_32_32,(RW4 d, R4 s))
1706     {
1707     abort(); /* %^$&%^$%#^ x86! */
1708     emit_byte(0x0f);
1709     emit_byte(0xaf);
1710     emit_byte(0xc0+8*d+s);
1711     }
1712     LENDFUNC(NONE,NONE,2,raw_mul_32_32,(RW4 d, R4 s))
1713    
1714     LOWFUNC(NONE,NONE,2,raw_mov_b_rr,(W1 d, R1 s))
1715     {
1716     emit_byte(0x88);
1717     emit_byte(0xc0+8*s+d);
1718     }
1719     LENDFUNC(NONE,NONE,2,raw_mov_b_rr,(W1 d, R1 s))
1720    
1721     LOWFUNC(NONE,NONE,2,raw_mov_w_rr,(W2 d, R2 s))
1722     {
1723     emit_byte(0x66);
1724     emit_byte(0x89);
1725     emit_byte(0xc0+8*s+d);
1726     }
1727     LENDFUNC(NONE,NONE,2,raw_mov_w_rr,(W2 d, R2 s))
1728    
1729     LOWFUNC(NONE,READ,4,raw_mov_l_rrm_indexed,(W4 d,R4 baser, R4 index, IMM factor))
1730     {
1731     int isebp=(baser==5)?0x40:0;
1732     int fi;
1733    
1734     switch(factor) {
1735     case 1: fi=0; break;
1736     case 2: fi=1; break;
1737     case 4: fi=2; break;
1738     case 8: fi=3; break;
1739     default: abort();
1740     }
1741    
1742    
1743     emit_byte(0x8b);
1744     emit_byte(0x04+8*d+isebp);
1745     emit_byte(baser+8*index+0x40*fi);
1746     if (isebp)
1747     emit_byte(0x00);
1748     }
1749     LENDFUNC(NONE,READ,4,raw_mov_l_rrm_indexed,(W4 d,R4 baser, R4 index, IMM factor))
1750    
1751     LOWFUNC(NONE,READ,4,raw_mov_w_rrm_indexed,(W2 d, R4 baser, R4 index, IMM factor))
1752     {
1753     int fi;
1754     int isebp;
1755    
1756     switch(factor) {
1757     case 1: fi=0; break;
1758     case 2: fi=1; break;
1759     case 4: fi=2; break;
1760     case 8: fi=3; break;
1761     default: abort();
1762     }
1763     isebp=(baser==5)?0x40:0;
1764    
1765     emit_byte(0x66);
1766     emit_byte(0x8b);
1767     emit_byte(0x04+8*d+isebp);
1768     emit_byte(baser+8*index+0x40*fi);
1769     if (isebp)
1770     emit_byte(0x00);
1771     }
1772     LENDFUNC(NONE,READ,4,raw_mov_w_rrm_indexed,(W2 d, R4 baser, R4 index, IMM factor))
1773    
1774     LOWFUNC(NONE,READ,4,raw_mov_b_rrm_indexed,(W1 d, R4 baser, R4 index, IMM factor))
1775     {
1776     int fi;
1777     int isebp;
1778    
1779     switch(factor) {
1780     case 1: fi=0; break;
1781     case 2: fi=1; break;
1782     case 4: fi=2; break;
1783     case 8: fi=3; break;
1784     default: abort();
1785     }
1786     isebp=(baser==5)?0x40:0;
1787    
1788     emit_byte(0x8a);
1789     emit_byte(0x04+8*d+isebp);
1790     emit_byte(baser+8*index+0x40*fi);
1791     if (isebp)
1792     emit_byte(0x00);
1793     }
1794     LENDFUNC(NONE,READ,4,raw_mov_b_rrm_indexed,(W1 d, R4 baser, R4 index, IMM factor))
1795    
1796     LOWFUNC(NONE,WRITE,4,raw_mov_l_mrr_indexed,(R4 baser, R4 index, IMM factor, R4 s))
1797     {
1798     int fi;
1799     int isebp;
1800    
1801     switch(factor) {
1802     case 1: fi=0; break;
1803     case 2: fi=1; break;
1804     case 4: fi=2; break;
1805     case 8: fi=3; break;
1806     default: abort();
1807     }
1808    
1809    
1810     isebp=(baser==5)?0x40:0;
1811    
1812     emit_byte(0x89);
1813     emit_byte(0x04+8*s+isebp);
1814     emit_byte(baser+8*index+0x40*fi);
1815     if (isebp)
1816     emit_byte(0x00);
1817     }
1818     LENDFUNC(NONE,WRITE,4,raw_mov_l_mrr_indexed,(R4 baser, R4 index, IMM factor, R4 s))
1819    
1820     LOWFUNC(NONE,WRITE,4,raw_mov_w_mrr_indexed,(R4 baser, R4 index, IMM factor, R2 s))
1821     {
1822     int fi;
1823     int isebp;
1824    
1825     switch(factor) {
1826     case 1: fi=0; break;
1827     case 2: fi=1; break;
1828     case 4: fi=2; break;
1829     case 8: fi=3; break;
1830     default: abort();
1831     }
1832     isebp=(baser==5)?0x40:0;
1833    
1834     emit_byte(0x66);
1835     emit_byte(0x89);
1836     emit_byte(0x04+8*s+isebp);
1837     emit_byte(baser+8*index+0x40*fi);
1838     if (isebp)
1839     emit_byte(0x00);
1840     }
1841     LENDFUNC(NONE,WRITE,4,raw_mov_w_mrr_indexed,(R4 baser, R4 index, IMM factor, R2 s))
1842    
1843     LOWFUNC(NONE,WRITE,4,raw_mov_b_mrr_indexed,(R4 baser, R4 index, IMM factor, R1 s))
1844     {
1845     int fi;
1846     int isebp;
1847    
1848     switch(factor) {
1849     case 1: fi=0; break;
1850     case 2: fi=1; break;
1851     case 4: fi=2; break;
1852     case 8: fi=3; break;
1853     default: abort();
1854     }
1855     isebp=(baser==5)?0x40:0;
1856    
1857     emit_byte(0x88);
1858     emit_byte(0x04+8*s+isebp);
1859     emit_byte(baser+8*index+0x40*fi);
1860     if (isebp)
1861     emit_byte(0x00);
1862     }
1863     LENDFUNC(NONE,WRITE,4,raw_mov_b_mrr_indexed,(R4 baser, R4 index, IMM factor, R1 s))
1864    
1865     LOWFUNC(NONE,WRITE,5,raw_mov_l_bmrr_indexed,(IMM base, R4 baser, R4 index, IMM factor, R4 s))
1866     {
1867     int fi;
1868    
1869     switch(factor) {
1870     case 1: fi=0; break;
1871     case 2: fi=1; break;
1872     case 4: fi=2; break;
1873     case 8: fi=3; break;
1874     default: abort();
1875     }
1876    
1877     emit_byte(0x89);
1878     emit_byte(0x84+8*s);
1879     emit_byte(baser+8*index+0x40*fi);
1880     emit_long(base);
1881     }
1882     LENDFUNC(NONE,WRITE,5,raw_mov_l_bmrr_indexed,(IMM base, R4 baser, R4 index, IMM factor, R4 s))
1883    
1884     LOWFUNC(NONE,WRITE,5,raw_mov_w_bmrr_indexed,(IMM base, R4 baser, R4 index, IMM factor, R2 s))
1885     {
1886     int fi;
1887    
1888     switch(factor) {
1889     case 1: fi=0; break;
1890     case 2: fi=1; break;
1891     case 4: fi=2; break;
1892     case 8: fi=3; break;
1893     default: abort();
1894     }
1895    
1896     emit_byte(0x66);
1897     emit_byte(0x89);
1898     emit_byte(0x84+8*s);
1899     emit_byte(baser+8*index+0x40*fi);
1900     emit_long(base);
1901     }
1902     LENDFUNC(NONE,WRITE,5,raw_mov_w_bmrr_indexed,(IMM base, R4 baser, R4 index, IMM factor, R2 s))
1903    
1904     LOWFUNC(NONE,WRITE,5,raw_mov_b_bmrr_indexed,(IMM base, R4 baser, R4 index, IMM factor, R1 s))
1905     {
1906     int fi;
1907    
1908     switch(factor) {
1909     case 1: fi=0; break;
1910     case 2: fi=1; break;
1911     case 4: fi=2; break;
1912     case 8: fi=3; break;
1913     default: abort();
1914     }
1915    
1916     emit_byte(0x88);
1917     emit_byte(0x84+8*s);
1918     emit_byte(baser+8*index+0x40*fi);
1919     emit_long(base);
1920     }
1921     LENDFUNC(NONE,WRITE,5,raw_mov_b_bmrr_indexed,(IMM base, R4 baser, R4 index, IMM factor, R1 s))
1922    
1923     LOWFUNC(NONE,READ,5,raw_mov_l_brrm_indexed,(W4 d, IMM base, R4 baser, R4 index, IMM factor))
1924     {
1925     int fi;
1926    
1927     switch(factor) {
1928     case 1: fi=0; break;
1929     case 2: fi=1; break;
1930     case 4: fi=2; break;
1931     case 8: fi=3; break;
1932     default: abort();
1933     }
1934    
1935     emit_byte(0x8b);
1936     emit_byte(0x84+8*d);
1937     emit_byte(baser+8*index+0x40*fi);
1938     emit_long(base);
1939     }
1940     LENDFUNC(NONE,READ,5,raw_mov_l_brrm_indexed,(W4 d, IMM base, R4 baser, R4 index, IMM factor))
1941    
1942     LOWFUNC(NONE,READ,5,raw_mov_w_brrm_indexed,(W2 d, IMM base, R4 baser, R4 index, IMM factor))
1943     {
1944     int fi;
1945    
1946     switch(factor) {
1947     case 1: fi=0; break;
1948     case 2: fi=1; break;
1949     case 4: fi=2; break;
1950     case 8: fi=3; break;
1951     default: abort();
1952     }
1953    
1954     emit_byte(0x66);
1955     emit_byte(0x8b);
1956     emit_byte(0x84+8*d);
1957     emit_byte(baser+8*index+0x40*fi);
1958     emit_long(base);
1959     }
1960     LENDFUNC(NONE,READ,5,raw_mov_w_brrm_indexed,(W2 d, IMM base, R4 baser, R4 index, IMM factor))
1961    
1962     LOWFUNC(NONE,READ,5,raw_mov_b_brrm_indexed,(W1 d, IMM base, R4 baser, R4 index, IMM factor))
1963     {
1964     int fi;
1965    
1966     switch(factor) {
1967     case 1: fi=0; break;
1968     case 2: fi=1; break;
1969     case 4: fi=2; break;
1970     case 8: fi=3; break;
1971     default: abort();
1972     }
1973    
1974     emit_byte(0x8a);
1975     emit_byte(0x84+8*d);
1976     emit_byte(baser+8*index+0x40*fi);
1977     emit_long(base);
1978     }
1979     LENDFUNC(NONE,READ,5,raw_mov_b_brrm_indexed,(W1 d, IMM base, R4 baser, R4 index, IMM factor))
1980    
1981     LOWFUNC(NONE,READ,4,raw_mov_l_rm_indexed,(W4 d, IMM base, R4 index, IMM factor))
1982     {
1983     int fi;
1984     switch(factor) {
1985     case 1: fi=0; break;
1986     case 2: fi=1; break;
1987     case 4: fi=2; break;
1988     case 8: fi=3; break;
1989     default:
1990     fprintf(stderr,"Bad factor %d in mov_l_rm_indexed!\n",factor);
1991     abort();
1992     }
1993     emit_byte(0x8b);
1994     emit_byte(0x04+8*d);
1995     emit_byte(0x05+8*index+64*fi);
1996     emit_long(base);
1997     }
1998     LENDFUNC(NONE,READ,4,raw_mov_l_rm_indexed,(W4 d, IMM base, R4 index, IMM factor))
1999    
2000     LOWFUNC(NONE,READ,5,raw_cmov_l_rm_indexed,(W4 d, IMM base, R4 index, IMM factor, IMM cond))
2001     {
2002     int fi;
2003     switch(factor) {
2004     case 1: fi=0; break;
2005     case 2: fi=1; break;
2006     case 4: fi=2; break;
2007     case 8: fi=3; break;
2008     default:
2009     fprintf(stderr,"Bad factor %d in mov_l_rm_indexed!\n",factor);
2010     abort();
2011     }
2012     if (have_cmov) {
2013     emit_byte(0x0f);
2014     emit_byte(0x40+cond);
2015     emit_byte(0x04+8*d);
2016     emit_byte(0x05+8*index+64*fi);
2017     emit_long(base);
2018     }
2019     else { /* replacement using branch and mov */
2020     int uncc=(cond^1);
2021     emit_byte(0x70+uncc);
2022     emit_byte(7); /* skip next 7 bytes if not cc=true */
2023     emit_byte(0x8b);
2024     emit_byte(0x04+8*d);
2025     emit_byte(0x05+8*index+64*fi);
2026     emit_long(base);
2027     }
2028     }
2029     LENDFUNC(NONE,READ,5,raw_cmov_l_rm_indexed,(W4 d, IMM base, R4 index, IMM factor, IMM cond))
2030    
2031     LOWFUNC(NONE,READ,3,raw_cmov_l_rm,(W4 d, IMM mem, IMM cond))
2032     {
2033     if (have_cmov) {
2034     emit_byte(0x0f);
2035     emit_byte(0x40+cond);
2036     emit_byte(0x05+8*d);
2037     emit_long(mem);
2038     }
2039     else { /* replacement using branch and mov */
2040     int uncc=(cond^1);
2041     emit_byte(0x70+uncc);
2042     emit_byte(6); /* skip next 6 bytes if not cc=true */
2043     emit_byte(0x8b);
2044     emit_byte(0x05+8*d);
2045     emit_long(mem);
2046     }
2047     }
2048     LENDFUNC(NONE,READ,3,raw_cmov_l_rm,(W4 d, IMM mem, IMM cond))
2049    
2050     LOWFUNC(NONE,READ,3,raw_mov_l_rR,(W4 d, R4 s, IMM offset))
2051     {
2052 gbeauche 1.9 Dif(!isbyte(offset)) abort();
2053 gbeauche 1.1 emit_byte(0x8b);
2054     emit_byte(0x40+8*d+s);
2055     emit_byte(offset);
2056     }
2057     LENDFUNC(NONE,READ,3,raw_mov_l_rR,(W4 d, R4 s, IMM offset))
2058    
2059     LOWFUNC(NONE,READ,3,raw_mov_w_rR,(W2 d, R4 s, IMM offset))
2060     {
2061 gbeauche 1.9 Dif(!isbyte(offset)) abort();
2062 gbeauche 1.1 emit_byte(0x66);
2063     emit_byte(0x8b);
2064     emit_byte(0x40+8*d+s);
2065     emit_byte(offset);
2066     }
2067     LENDFUNC(NONE,READ,3,raw_mov_w_rR,(W2 d, R4 s, IMM offset))
2068    
2069     LOWFUNC(NONE,READ,3,raw_mov_b_rR,(W1 d, R4 s, IMM offset))
2070     {
2071 gbeauche 1.9 Dif(!isbyte(offset)) abort();
2072 gbeauche 1.1 emit_byte(0x8a);
2073     emit_byte(0x40+8*d+s);
2074     emit_byte(offset);
2075     }
2076     LENDFUNC(NONE,READ,3,raw_mov_b_rR,(W1 d, R4 s, IMM offset))
2077    
2078     LOWFUNC(NONE,READ,3,raw_mov_l_brR,(W4 d, R4 s, IMM offset))
2079     {
2080     emit_byte(0x8b);
2081     emit_byte(0x80+8*d+s);
2082     emit_long(offset);
2083     }
2084     LENDFUNC(NONE,READ,3,raw_mov_l_brR,(W4 d, R4 s, IMM offset))
2085    
2086     LOWFUNC(NONE,READ,3,raw_mov_w_brR,(W2 d, R4 s, IMM offset))
2087     {
2088     emit_byte(0x66);
2089     emit_byte(0x8b);
2090     emit_byte(0x80+8*d+s);
2091     emit_long(offset);
2092     }
2093     LENDFUNC(NONE,READ,3,raw_mov_w_brR,(W2 d, R4 s, IMM offset))
2094    
2095     LOWFUNC(NONE,READ,3,raw_mov_b_brR,(W1 d, R4 s, IMM offset))
2096     {
2097     emit_byte(0x8a);
2098     emit_byte(0x80+8*d+s);
2099     emit_long(offset);
2100     }
2101     LENDFUNC(NONE,READ,3,raw_mov_b_brR,(W1 d, R4 s, IMM offset))
2102    
2103     LOWFUNC(NONE,WRITE,3,raw_mov_l_Ri,(R4 d, IMM i, IMM offset))
2104     {
2105 gbeauche 1.9 Dif(!isbyte(offset)) abort();
2106 gbeauche 1.1 emit_byte(0xc7);
2107     emit_byte(0x40+d);
2108     emit_byte(offset);
2109     emit_long(i);
2110     }
2111     LENDFUNC(NONE,WRITE,3,raw_mov_l_Ri,(R4 d, IMM i, IMM offset))
2112    
2113     LOWFUNC(NONE,WRITE,3,raw_mov_w_Ri,(R4 d, IMM i, IMM offset))
2114     {
2115 gbeauche 1.9 Dif(!isbyte(offset)) abort();
2116 gbeauche 1.1 emit_byte(0x66);
2117     emit_byte(0xc7);
2118     emit_byte(0x40+d);
2119     emit_byte(offset);
2120     emit_word(i);
2121     }
2122     LENDFUNC(NONE,WRITE,3,raw_mov_w_Ri,(R4 d, IMM i, IMM offset))
2123    
2124     LOWFUNC(NONE,WRITE,3,raw_mov_b_Ri,(R4 d, IMM i, IMM offset))
2125     {
2126 gbeauche 1.9 Dif(!isbyte(offset)) abort();
2127 gbeauche 1.1 emit_byte(0xc6);
2128     emit_byte(0x40+d);
2129     emit_byte(offset);
2130     emit_byte(i);
2131     }
2132     LENDFUNC(NONE,WRITE,3,raw_mov_b_Ri,(R4 d, IMM i, IMM offset))
2133    
2134     LOWFUNC(NONE,WRITE,3,raw_mov_l_Rr,(R4 d, R4 s, IMM offset))
2135     {
2136 gbeauche 1.9 Dif(!isbyte(offset)) abort();
2137 gbeauche 1.1 emit_byte(0x89);
2138     emit_byte(0x40+8*s+d);
2139     emit_byte(offset);
2140     }
2141     LENDFUNC(NONE,WRITE,3,raw_mov_l_Rr,(R4 d, R4 s, IMM offset))
2142    
2143     LOWFUNC(NONE,WRITE,3,raw_mov_w_Rr,(R4 d, R2 s, IMM offset))
2144     {
2145 gbeauche 1.9 Dif(!isbyte(offset)) abort();
2146 gbeauche 1.1 emit_byte(0x66);
2147     emit_byte(0x89);
2148     emit_byte(0x40+8*s+d);
2149     emit_byte(offset);
2150     }
2151     LENDFUNC(NONE,WRITE,3,raw_mov_w_Rr,(R4 d, R2 s, IMM offset))
2152    
2153     LOWFUNC(NONE,WRITE,3,raw_mov_b_Rr,(R4 d, R1 s, IMM offset))
2154     {
2155 gbeauche 1.9 Dif(!isbyte(offset)) abort();
2156 gbeauche 1.1 emit_byte(0x88);
2157     emit_byte(0x40+8*s+d);
2158     emit_byte(offset);
2159     }
2160     LENDFUNC(NONE,WRITE,3,raw_mov_b_Rr,(R4 d, R1 s, IMM offset))
2161    
2162     LOWFUNC(NONE,NONE,3,raw_lea_l_brr,(W4 d, R4 s, IMM offset))
2163     {
2164     if (optimize_imm8 && isbyte(offset)) {
2165     emit_byte(0x8d);
2166     emit_byte(0x40+8*d+s);
2167     emit_byte(offset);
2168     }
2169     else {
2170     emit_byte(0x8d);
2171     emit_byte(0x80+8*d+s);
2172     emit_long(offset);
2173     }
2174     }
2175     LENDFUNC(NONE,NONE,3,raw_lea_l_brr,(W4 d, R4 s, IMM offset))
2176    
2177     LOWFUNC(NONE,NONE,5,raw_lea_l_brr_indexed,(W4 d, R4 s, R4 index, IMM factor, IMM offset))
2178     {
2179     int fi;
2180    
2181     switch(factor) {
2182     case 1: fi=0; break;
2183     case 2: fi=1; break;
2184     case 4: fi=2; break;
2185     case 8: fi=3; break;
2186     default: abort();
2187     }
2188    
2189     if (optimize_imm8 && isbyte(offset)) {
2190     emit_byte(0x8d);
2191     emit_byte(0x44+8*d);
2192     emit_byte(0x40*fi+8*index+s);
2193     emit_byte(offset);
2194     }
2195     else {
2196     emit_byte(0x8d);
2197     emit_byte(0x84+8*d);
2198     emit_byte(0x40*fi+8*index+s);
2199     emit_long(offset);
2200     }
2201     }
2202     LENDFUNC(NONE,NONE,5,raw_lea_l_brr_indexed,(W4 d, R4 s, R4 index, IMM factor, IMM offset))
2203    
2204     LOWFUNC(NONE,NONE,4,raw_lea_l_rr_indexed,(W4 d, R4 s, R4 index, IMM factor))
2205     {
2206     int isebp=(s==5)?0x40:0;
2207     int fi;
2208    
2209     switch(factor) {
2210     case 1: fi=0; break;
2211     case 2: fi=1; break;
2212     case 4: fi=2; break;
2213     case 8: fi=3; break;
2214     default: abort();
2215     }
2216    
2217     emit_byte(0x8d);
2218     emit_byte(0x04+8*d+isebp);
2219     emit_byte(0x40*fi+8*index+s);
2220     if (isebp)
2221     emit_byte(0);
2222     }
2223     LENDFUNC(NONE,NONE,4,raw_lea_l_rr_indexed,(W4 d, R4 s, R4 index, IMM factor))
2224    
2225     LOWFUNC(NONE,WRITE,3,raw_mov_l_bRr,(R4 d, R4 s, IMM offset))
2226     {
2227     if (optimize_imm8 && isbyte(offset)) {
2228     emit_byte(0x89);
2229     emit_byte(0x40+8*s+d);
2230     emit_byte(offset);
2231     }
2232     else {
2233     emit_byte(0x89);
2234     emit_byte(0x80+8*s+d);
2235     emit_long(offset);
2236     }
2237     }
2238     LENDFUNC(NONE,WRITE,3,raw_mov_l_bRr,(R4 d, R4 s, IMM offset))
2239    
2240     LOWFUNC(NONE,WRITE,3,raw_mov_w_bRr,(R4 d, R2 s, IMM offset))
2241     {
2242     emit_byte(0x66);
2243     emit_byte(0x89);
2244     emit_byte(0x80+8*s+d);
2245     emit_long(offset);
2246     }
2247     LENDFUNC(NONE,WRITE,3,raw_mov_w_bRr,(R4 d, R2 s, IMM offset))
2248    
2249     LOWFUNC(NONE,WRITE,3,raw_mov_b_bRr,(R4 d, R1 s, IMM offset))
2250     {
2251     if (optimize_imm8 && isbyte(offset)) {
2252     emit_byte(0x88);
2253     emit_byte(0x40+8*s+d);
2254     emit_byte(offset);
2255     }
2256     else {
2257     emit_byte(0x88);
2258     emit_byte(0x80+8*s+d);
2259     emit_long(offset);
2260     }
2261     }
2262     LENDFUNC(NONE,WRITE,3,raw_mov_b_bRr,(R4 d, R1 s, IMM offset))
2263    
2264     LOWFUNC(NONE,NONE,1,raw_bswap_32,(RW4 r))
2265     {
2266     emit_byte(0x0f);
2267     emit_byte(0xc8+r);
2268     }
2269     LENDFUNC(NONE,NONE,1,raw_bswap_32,(RW4 r))
2270    
2271     LOWFUNC(WRITE,NONE,1,raw_bswap_16,(RW2 r))
2272     {
2273     emit_byte(0x66);
2274     emit_byte(0xc1);
2275     emit_byte(0xc0+r);
2276     emit_byte(0x08);
2277     }
2278     LENDFUNC(WRITE,NONE,1,raw_bswap_16,(RW2 r))
2279    
2280     LOWFUNC(NONE,NONE,2,raw_mov_l_rr,(W4 d, R4 s))
2281     {
2282     emit_byte(0x89);
2283     emit_byte(0xc0+8*s+d);
2284     }
2285     LENDFUNC(NONE,NONE,2,raw_mov_l_rr,(W4 d, R4 s))
2286    
2287     LOWFUNC(NONE,WRITE,2,raw_mov_l_mr,(IMM d, R4 s))
2288     {
2289     emit_byte(0x89);
2290     emit_byte(0x05+8*s);
2291     emit_long(d);
2292     }
2293     LENDFUNC(NONE,WRITE,2,raw_mov_l_mr,(IMM d, R4 s))
2294    
2295     LOWFUNC(NONE,WRITE,2,raw_mov_w_mr,(IMM d, R2 s))
2296     {
2297     emit_byte(0x66);
2298     emit_byte(0x89);
2299     emit_byte(0x05+8*s);
2300     emit_long(d);
2301     }
2302     LENDFUNC(NONE,WRITE,2,raw_mov_w_mr,(IMM d, R2 s))
2303    
2304     LOWFUNC(NONE,READ,2,raw_mov_w_rm,(W2 d, IMM s))
2305     {
2306     emit_byte(0x66);
2307     emit_byte(0x8b);
2308     emit_byte(0x05+8*d);
2309     emit_long(s);
2310     }
2311     LENDFUNC(NONE,READ,2,raw_mov_w_rm,(W2 d, IMM s))
2312    
2313     LOWFUNC(NONE,WRITE,2,raw_mov_b_mr,(IMM d, R1 s))
2314     {
2315     emit_byte(0x88);
2316     emit_byte(0x05+8*s);
2317     emit_long(d);
2318     }
2319     LENDFUNC(NONE,WRITE,2,raw_mov_b_mr,(IMM d, R1 s))
2320    
2321     LOWFUNC(NONE,READ,2,raw_mov_b_rm,(W1 d, IMM s))
2322     {
2323     emit_byte(0x8a);
2324     emit_byte(0x05+8*d);
2325     emit_long(s);
2326     }
2327     LENDFUNC(NONE,READ,2,raw_mov_b_rm,(W1 d, IMM s))
2328    
2329     LOWFUNC(NONE,NONE,2,raw_mov_l_ri,(W4 d, IMM s))
2330     {
2331     emit_byte(0xb8+d);
2332     emit_long(s);
2333     }
2334     LENDFUNC(NONE,NONE,2,raw_mov_l_ri,(W4 d, IMM s))
2335    
2336     LOWFUNC(NONE,NONE,2,raw_mov_w_ri,(W2 d, IMM s))
2337     {
2338     emit_byte(0x66);
2339     emit_byte(0xb8+d);
2340     emit_word(s);
2341     }
2342     LENDFUNC(NONE,NONE,2,raw_mov_w_ri,(W2 d, IMM s))
2343    
2344     LOWFUNC(NONE,NONE,2,raw_mov_b_ri,(W1 d, IMM s))
2345     {
2346     emit_byte(0xb0+d);
2347     emit_byte(s);
2348     }
2349     LENDFUNC(NONE,NONE,2,raw_mov_b_ri,(W1 d, IMM s))
2350    
2351     LOWFUNC(RMW,RMW,2,raw_adc_l_mi,(MEMRW d, IMM s))
2352     {
2353     emit_byte(0x81);
2354     emit_byte(0x15);
2355     emit_long(d);
2356     emit_long(s);
2357     }
2358     LENDFUNC(RMW,RMW,2,raw_adc_l_mi,(MEMRW d, IMM s))
2359    
2360     LOWFUNC(WRITE,RMW,2,raw_add_l_mi,(IMM d, IMM s))
2361     {
2362     if (optimize_imm8 && isbyte(s)) {
2363     emit_byte(0x83);
2364     emit_byte(0x05);
2365     emit_long(d);
2366     emit_byte(s);
2367     }
2368     else {
2369     emit_byte(0x81);
2370     emit_byte(0x05);
2371     emit_long(d);
2372     emit_long(s);
2373     }
2374     }
2375     LENDFUNC(WRITE,RMW,2,raw_add_l_mi,(IMM d, IMM s))
2376    
2377     LOWFUNC(WRITE,RMW,2,raw_add_w_mi,(IMM d, IMM s))
2378     {
2379     emit_byte(0x66);
2380     emit_byte(0x81);
2381     emit_byte(0x05);
2382     emit_long(d);
2383     emit_word(s);
2384     }
2385     LENDFUNC(WRITE,RMW,2,raw_add_w_mi,(IMM d, IMM s))
2386    
2387     LOWFUNC(WRITE,RMW,2,raw_add_b_mi,(IMM d, IMM s))
2388     {
2389     emit_byte(0x80);
2390     emit_byte(0x05);
2391     emit_long(d);
2392     emit_byte(s);
2393     }
2394     LENDFUNC(WRITE,RMW,2,raw_add_b_mi,(IMM d, IMM s))
2395    
2396     LOWFUNC(WRITE,NONE,2,raw_test_l_ri,(R4 d, IMM i))
2397     {
2398 gbeauche 1.2 if (optimize_accum && isaccum(d))
2399     emit_byte(0xa9);
2400     else {
2401 gbeauche 1.1 emit_byte(0xf7);
2402     emit_byte(0xc0+d);
2403 gbeauche 1.2 }
2404 gbeauche 1.1 emit_long(i);
2405     }
2406     LENDFUNC(WRITE,NONE,2,raw_test_l_ri,(R4 d, IMM i))
2407    
2408     LOWFUNC(WRITE,NONE,2,raw_test_l_rr,(R4 d, R4 s))
2409     {
2410     emit_byte(0x85);
2411     emit_byte(0xc0+8*s+d);
2412     }
2413     LENDFUNC(WRITE,NONE,2,raw_test_l_rr,(R4 d, R4 s))
2414    
2415     LOWFUNC(WRITE,NONE,2,raw_test_w_rr,(R2 d, R2 s))
2416     {
2417     emit_byte(0x66);
2418     emit_byte(0x85);
2419     emit_byte(0xc0+8*s+d);
2420     }
2421     LENDFUNC(WRITE,NONE,2,raw_test_w_rr,(R2 d, R2 s))
2422    
2423     LOWFUNC(WRITE,NONE,2,raw_test_b_rr,(R1 d, R1 s))
2424     {
2425     emit_byte(0x84);
2426     emit_byte(0xc0+8*s+d);
2427     }
2428     LENDFUNC(WRITE,NONE,2,raw_test_b_rr,(R1 d, R1 s))
2429    
2430     LOWFUNC(WRITE,NONE,2,raw_and_l_ri,(RW4 d, IMM i))
2431     {
2432     if (optimize_imm8 && isbyte(i)) {
2433 gbeauche 1.2 emit_byte(0x83);
2434     emit_byte(0xe0+d);
2435     emit_byte(i);
2436 gbeauche 1.1 }
2437     else {
2438 gbeauche 1.2 if (optimize_accum && isaccum(d))
2439     emit_byte(0x25);
2440     else {
2441     emit_byte(0x81);
2442     emit_byte(0xe0+d);
2443     }
2444     emit_long(i);
2445 gbeauche 1.1 }
2446     }
2447     LENDFUNC(WRITE,NONE,2,raw_and_l_ri,(RW4 d, IMM i))
2448    
2449     LOWFUNC(WRITE,NONE,2,raw_and_w_ri,(RW2 d, IMM i))
2450     {
2451 gbeauche 1.2 emit_byte(0x66);
2452     if (optimize_imm8 && isbyte(i)) {
2453     emit_byte(0x83);
2454     emit_byte(0xe0+d);
2455     emit_byte(i);
2456     }
2457     else {
2458     if (optimize_accum && isaccum(d))
2459     emit_byte(0x25);
2460     else {
2461     emit_byte(0x81);
2462     emit_byte(0xe0+d);
2463     }
2464     emit_word(i);
2465     }
2466 gbeauche 1.1 }
2467     LENDFUNC(WRITE,NONE,2,raw_and_w_ri,(RW2 d, IMM i))
2468    
2469     LOWFUNC(WRITE,NONE,2,raw_and_l,(RW4 d, R4 s))
2470     {
2471     emit_byte(0x21);
2472     emit_byte(0xc0+8*s+d);
2473     }
2474     LENDFUNC(WRITE,NONE,2,raw_and_l,(RW4 d, R4 s))
2475    
2476     LOWFUNC(WRITE,NONE,2,raw_and_w,(RW2 d, R2 s))
2477     {
2478     emit_byte(0x66);
2479     emit_byte(0x21);
2480     emit_byte(0xc0+8*s+d);
2481     }
2482     LENDFUNC(WRITE,NONE,2,raw_and_w,(RW2 d, R2 s))
2483    
2484     LOWFUNC(WRITE,NONE,2,raw_and_b,(RW1 d, R1 s))
2485     {
2486     emit_byte(0x20);
2487     emit_byte(0xc0+8*s+d);
2488     }
2489     LENDFUNC(WRITE,NONE,2,raw_and_b,(RW1 d, R1 s))
2490    
2491     LOWFUNC(WRITE,NONE,2,raw_or_l_ri,(RW4 d, IMM i))
2492     {
2493     if (optimize_imm8 && isbyte(i)) {
2494     emit_byte(0x83);
2495     emit_byte(0xc8+d);
2496     emit_byte(i);
2497     }
2498     else {
2499 gbeauche 1.2 if (optimize_accum && isaccum(d))
2500     emit_byte(0x0d);
2501     else {
2502 gbeauche 1.1 emit_byte(0x81);
2503     emit_byte(0xc8+d);
2504 gbeauche 1.2 }
2505 gbeauche 1.1 emit_long(i);
2506     }
2507     }
2508     LENDFUNC(WRITE,NONE,2,raw_or_l_ri,(RW4 d, IMM i))
2509    
2510     LOWFUNC(WRITE,NONE,2,raw_or_l,(RW4 d, R4 s))
2511     {
2512     emit_byte(0x09);
2513     emit_byte(0xc0+8*s+d);
2514     }
2515     LENDFUNC(WRITE,NONE,2,raw_or_l,(RW4 d, R4 s))
2516    
2517     LOWFUNC(WRITE,NONE,2,raw_or_w,(RW2 d, R2 s))
2518     {
2519     emit_byte(0x66);
2520     emit_byte(0x09);
2521     emit_byte(0xc0+8*s+d);
2522     }
2523     LENDFUNC(WRITE,NONE,2,raw_or_w,(RW2 d, R2 s))
2524    
2525     LOWFUNC(WRITE,NONE,2,raw_or_b,(RW1 d, R1 s))
2526     {
2527     emit_byte(0x08);
2528     emit_byte(0xc0+8*s+d);
2529     }
2530     LENDFUNC(WRITE,NONE,2,raw_or_b,(RW1 d, R1 s))
2531    
2532     LOWFUNC(RMW,NONE,2,raw_adc_l,(RW4 d, R4 s))
2533     {
2534     emit_byte(0x11);
2535     emit_byte(0xc0+8*s+d);
2536     }
2537     LENDFUNC(RMW,NONE,2,raw_adc_l,(RW4 d, R4 s))
2538    
2539     LOWFUNC(RMW,NONE,2,raw_adc_w,(RW2 d, R2 s))
2540     {
2541     emit_byte(0x66);
2542     emit_byte(0x11);
2543     emit_byte(0xc0+8*s+d);
2544     }
2545     LENDFUNC(RMW,NONE,2,raw_adc_w,(RW2 d, R2 s))
2546    
2547     LOWFUNC(RMW,NONE,2,raw_adc_b,(RW1 d, R1 s))
2548     {
2549     emit_byte(0x10);
2550     emit_byte(0xc0+8*s+d);
2551     }
2552     LENDFUNC(RMW,NONE,2,raw_adc_b,(RW1 d, R1 s))
2553    
2554     LOWFUNC(WRITE,NONE,2,raw_add_l,(RW4 d, R4 s))
2555     {
2556     emit_byte(0x01);
2557     emit_byte(0xc0+8*s+d);
2558     }
2559     LENDFUNC(WRITE,NONE,2,raw_add_l,(RW4 d, R4 s))
2560    
2561     LOWFUNC(WRITE,NONE,2,raw_add_w,(RW2 d, R2 s))
2562     {
2563     emit_byte(0x66);
2564     emit_byte(0x01);
2565     emit_byte(0xc0+8*s+d);
2566     }
2567     LENDFUNC(WRITE,NONE,2,raw_add_w,(RW2 d, R2 s))
2568    
2569     LOWFUNC(WRITE,NONE,2,raw_add_b,(RW1 d, R1 s))
2570     {
2571     emit_byte(0x00);
2572     emit_byte(0xc0+8*s+d);
2573     }
2574     LENDFUNC(WRITE,NONE,2,raw_add_b,(RW1 d, R1 s))
2575    
2576     LOWFUNC(WRITE,NONE,2,raw_sub_l_ri,(RW4 d, IMM i))
2577     {
2578     if (isbyte(i)) {
2579     emit_byte(0x83);
2580     emit_byte(0xe8+d);
2581     emit_byte(i);
2582     }
2583     else {
2584 gbeauche 1.2 if (optimize_accum && isaccum(d))
2585     emit_byte(0x2d);
2586     else {
2587 gbeauche 1.1 emit_byte(0x81);
2588     emit_byte(0xe8+d);
2589 gbeauche 1.2 }
2590 gbeauche 1.1 emit_long(i);
2591     }
2592     }
2593     LENDFUNC(WRITE,NONE,2,raw_sub_l_ri,(RW4 d, IMM i))
2594    
2595     LOWFUNC(WRITE,NONE,2,raw_sub_b_ri,(RW1 d, IMM i))
2596     {
2597 gbeauche 1.2 if (optimize_accum && isaccum(d))
2598     emit_byte(0x2c);
2599     else {
2600 gbeauche 1.1 emit_byte(0x80);
2601     emit_byte(0xe8+d);
2602 gbeauche 1.2 }
2603 gbeauche 1.1 emit_byte(i);
2604     }
2605     LENDFUNC(WRITE,NONE,2,raw_sub_b_ri,(RW1 d, IMM i))
2606    
2607     LOWFUNC(WRITE,NONE,2,raw_add_l_ri,(RW4 d, IMM i))
2608     {
2609     if (isbyte(i)) {
2610     emit_byte(0x83);
2611     emit_byte(0xc0+d);
2612     emit_byte(i);
2613     }
2614     else {
2615 gbeauche 1.2 if (optimize_accum && isaccum(d))
2616     emit_byte(0x05);
2617     else {
2618 gbeauche 1.1 emit_byte(0x81);
2619     emit_byte(0xc0+d);
2620 gbeauche 1.2 }
2621 gbeauche 1.1 emit_long(i);
2622     }
2623     }
2624     LENDFUNC(WRITE,NONE,2,raw_add_l_ri,(RW4 d, IMM i))
2625    
2626     LOWFUNC(WRITE,NONE,2,raw_add_w_ri,(RW2 d, IMM i))
2627     {
2628 gbeauche 1.2 emit_byte(0x66);
2629 gbeauche 1.1 if (isbyte(i)) {
2630     emit_byte(0x83);
2631     emit_byte(0xc0+d);
2632     emit_byte(i);
2633     }
2634     else {
2635 gbeauche 1.2 if (optimize_accum && isaccum(d))
2636     emit_byte(0x05);
2637     else {
2638 gbeauche 1.1 emit_byte(0x81);
2639     emit_byte(0xc0+d);
2640 gbeauche 1.2 }
2641 gbeauche 1.1 emit_word(i);
2642     }
2643     }
2644     LENDFUNC(WRITE,NONE,2,raw_add_w_ri,(RW2 d, IMM i))
2645    
2646     LOWFUNC(WRITE,NONE,2,raw_add_b_ri,(RW1 d, IMM i))
2647     {
2648 gbeauche 1.2 if (optimize_accum && isaccum(d))
2649     emit_byte(0x04);
2650     else {
2651     emit_byte(0x80);
2652     emit_byte(0xc0+d);
2653     }
2654 gbeauche 1.1 emit_byte(i);
2655     }
2656     LENDFUNC(WRITE,NONE,2,raw_add_b_ri,(RW1 d, IMM i))
2657    
2658     LOWFUNC(RMW,NONE,2,raw_sbb_l,(RW4 d, R4 s))
2659     {
2660     emit_byte(0x19);
2661     emit_byte(0xc0+8*s+d);
2662     }
2663     LENDFUNC(RMW,NONE,2,raw_sbb_l,(RW4 d, R4 s))
2664    
2665     LOWFUNC(RMW,NONE,2,raw_sbb_w,(RW2 d, R2 s))
2666     {
2667     emit_byte(0x66);
2668     emit_byte(0x19);
2669     emit_byte(0xc0+8*s+d);
2670     }
2671     LENDFUNC(RMW,NONE,2,raw_sbb_w,(RW2 d, R2 s))
2672    
2673     LOWFUNC(RMW,NONE,2,raw_sbb_b,(RW1 d, R1 s))
2674     {
2675     emit_byte(0x18);
2676     emit_byte(0xc0+8*s+d);
2677     }
2678     LENDFUNC(RMW,NONE,2,raw_sbb_b,(RW1 d, R1 s))
2679    
2680     LOWFUNC(WRITE,NONE,2,raw_sub_l,(RW4 d, R4 s))
2681     {
2682     emit_byte(0x29);
2683     emit_byte(0xc0+8*s+d);
2684     }
2685     LENDFUNC(WRITE,NONE,2,raw_sub_l,(RW4 d, R4 s))
2686    
2687     LOWFUNC(WRITE,NONE,2,raw_sub_w,(RW2 d, R2 s))
2688     {
2689     emit_byte(0x66);
2690     emit_byte(0x29);
2691     emit_byte(0xc0+8*s+d);
2692     }
2693     LENDFUNC(WRITE,NONE,2,raw_sub_w,(RW2 d, R2 s))
2694    
2695     LOWFUNC(WRITE,NONE,2,raw_sub_b,(RW1 d, R1 s))
2696     {
2697     emit_byte(0x28);
2698     emit_byte(0xc0+8*s+d);
2699     }
2700     LENDFUNC(WRITE,NONE,2,raw_sub_b,(RW1 d, R1 s))
2701    
2702     LOWFUNC(WRITE,NONE,2,raw_cmp_l,(R4 d, R4 s))
2703     {
2704     emit_byte(0x39);
2705     emit_byte(0xc0+8*s+d);
2706     }
2707     LENDFUNC(WRITE,NONE,2,raw_cmp_l,(R4 d, R4 s))
2708    
2709     LOWFUNC(WRITE,NONE,2,raw_cmp_l_ri,(R4 r, IMM i))
2710     {
2711     if (optimize_imm8 && isbyte(i)) {
2712     emit_byte(0x83);
2713     emit_byte(0xf8+r);
2714     emit_byte(i);
2715     }
2716     else {
2717 gbeauche 1.2 if (optimize_accum && isaccum(r))
2718     emit_byte(0x3d);
2719     else {
2720 gbeauche 1.1 emit_byte(0x81);
2721     emit_byte(0xf8+r);
2722 gbeauche 1.2 }
2723 gbeauche 1.1 emit_long(i);
2724     }
2725     }
2726     LENDFUNC(WRITE,NONE,2,raw_cmp_l_ri,(R4 r, IMM i))
2727    
2728     LOWFUNC(WRITE,NONE,2,raw_cmp_w,(R2 d, R2 s))
2729     {
2730     emit_byte(0x66);
2731     emit_byte(0x39);
2732     emit_byte(0xc0+8*s+d);
2733     }
2734     LENDFUNC(WRITE,NONE,2,raw_cmp_w,(R2 d, R2 s))
2735    
2736 gbeauche 1.5 LOWFUNC(WRITE,READ,2,raw_cmp_b_mi,(MEMR d, IMM s))
2737     {
2738     emit_byte(0x80);
2739     emit_byte(0x3d);
2740     emit_long(d);
2741     emit_byte(s);
2742     }
2743     LENDFUNC(WRITE,READ,2,raw_cmp_l_mi,(MEMR d, IMM s))
2744    
2745 gbeauche 1.1 LOWFUNC(WRITE,NONE,2,raw_cmp_b_ri,(R1 d, IMM i))
2746     {
2747 gbeauche 1.2 if (optimize_accum && isaccum(d))
2748     emit_byte(0x3c);
2749     else {
2750 gbeauche 1.1 emit_byte(0x80);
2751     emit_byte(0xf8+d);
2752 gbeauche 1.2 }
2753 gbeauche 1.1 emit_byte(i);
2754     }
2755     LENDFUNC(WRITE,NONE,2,raw_cmp_b_ri,(R1 d, IMM i))
2756    
2757     LOWFUNC(WRITE,NONE,2,raw_cmp_b,(R1 d, R1 s))
2758     {
2759     emit_byte(0x38);
2760     emit_byte(0xc0+8*s+d);
2761     }
2762     LENDFUNC(WRITE,NONE,2,raw_cmp_b,(R1 d, R1 s))
2763    
2764     LOWFUNC(WRITE,READ,4,raw_cmp_l_rm_indexed,(R4 d, IMM offset, R4 index, IMM factor))
2765     {
2766     int fi;
2767    
2768     switch(factor) {
2769     case 1: fi=0; break;
2770     case 2: fi=1; break;
2771     case 4: fi=2; break;
2772     case 8: fi=3; break;
2773     default: abort();
2774     }
2775     emit_byte(0x39);
2776     emit_byte(0x04+8*d);
2777     emit_byte(5+8*index+0x40*fi);
2778     emit_long(offset);
2779     }
2780     LENDFUNC(WRITE,READ,4,raw_cmp_l_rm_indexed,(R4 d, IMM offset, R4 index, IMM factor))
2781    
2782     LOWFUNC(WRITE,NONE,2,raw_xor_l,(RW4 d, R4 s))
2783     {
2784     emit_byte(0x31);
2785     emit_byte(0xc0+8*s+d);
2786     }
2787     LENDFUNC(WRITE,NONE,2,raw_xor_l,(RW4 d, R4 s))
2788    
2789     LOWFUNC(WRITE,NONE,2,raw_xor_w,(RW2 d, R2 s))
2790     {
2791     emit_byte(0x66);
2792     emit_byte(0x31);
2793     emit_byte(0xc0+8*s+d);
2794     }
2795     LENDFUNC(WRITE,NONE,2,raw_xor_w,(RW2 d, R2 s))
2796    
2797     LOWFUNC(WRITE,NONE,2,raw_xor_b,(RW1 d, R1 s))
2798     {
2799     emit_byte(0x30);
2800     emit_byte(0xc0+8*s+d);
2801     }
2802     LENDFUNC(WRITE,NONE,2,raw_xor_b,(RW1 d, R1 s))
2803    
2804     LOWFUNC(WRITE,RMW,2,raw_sub_l_mi,(MEMRW d, IMM s))
2805     {
2806     if (optimize_imm8 && isbyte(s)) {
2807     emit_byte(0x83);
2808     emit_byte(0x2d);
2809     emit_long(d);
2810     emit_byte(s);
2811     }
2812     else {
2813     emit_byte(0x81);
2814     emit_byte(0x2d);
2815     emit_long(d);
2816     emit_long(s);
2817     }
2818     }
2819     LENDFUNC(WRITE,RMW,2,raw_sub_l_mi,(MEMRW d, IMM s))
2820    
2821     LOWFUNC(WRITE,READ,2,raw_cmp_l_mi,(MEMR d, IMM s))
2822     {
2823     if (optimize_imm8 && isbyte(s)) {
2824     emit_byte(0x83);
2825     emit_byte(0x3d);
2826     emit_long(d);
2827     emit_byte(s);
2828     }
2829     else {
2830     emit_byte(0x81);
2831     emit_byte(0x3d);
2832     emit_long(d);
2833     emit_long(s);
2834     }
2835     }
2836     LENDFUNC(WRITE,READ,2,raw_cmp_l_mi,(MEMR d, IMM s))
2837    
2838     LOWFUNC(NONE,NONE,2,raw_xchg_l_rr,(RW4 r1, RW4 r2))
2839     {
2840     emit_byte(0x87);
2841     emit_byte(0xc0+8*r1+r2);
2842     }
2843     LENDFUNC(NONE,NONE,2,raw_xchg_l_rr,(RW4 r1, RW4 r2))
2844    
2845     /*************************************************************************
2846     * FIXME: mem access modes probably wrong *
2847     *************************************************************************/
2848    
2849     LOWFUNC(READ,WRITE,0,raw_pushfl,(void))
2850     {
2851     emit_byte(0x9c);
2852     }
2853     LENDFUNC(READ,WRITE,0,raw_pushfl,(void))
2854    
2855     LOWFUNC(WRITE,READ,0,raw_popfl,(void))
2856     {
2857     emit_byte(0x9d);
2858     }
2859     LENDFUNC(WRITE,READ,0,raw_popfl,(void))
2860 gbeauche 1.13
2861     #endif
2862 gbeauche 1.1
2863     /*************************************************************************
2864     * Unoptimizable stuff --- jump *
2865     *************************************************************************/
2866    
2867     static __inline__ void raw_call_r(R4 r)
2868     {
2869     emit_byte(0xff);
2870     emit_byte(0xd0+r);
2871 gbeauche 1.5 }
2872    
2873     static __inline__ void raw_call_m_indexed(uae_u32 base, uae_u32 r, uae_u32 m)
2874     {
2875     int mu;
2876     switch(m) {
2877     case 1: mu=0; break;
2878     case 2: mu=1; break;
2879     case 4: mu=2; break;
2880     case 8: mu=3; break;
2881     default: abort();
2882     }
2883     emit_byte(0xff);
2884     emit_byte(0x14);
2885     emit_byte(0x05+8*r+0x40*mu);
2886     emit_long(base);
2887 gbeauche 1.1 }
2888    
2889     static __inline__ void raw_jmp_r(R4 r)
2890     {
2891     emit_byte(0xff);
2892     emit_byte(0xe0+r);
2893     }
2894    
2895     static __inline__ void raw_jmp_m_indexed(uae_u32 base, uae_u32 r, uae_u32 m)
2896     {
2897     int mu;
2898     switch(m) {
2899     case 1: mu=0; break;
2900     case 2: mu=1; break;
2901     case 4: mu=2; break;
2902     case 8: mu=3; break;
2903     default: abort();
2904     }
2905     emit_byte(0xff);
2906     emit_byte(0x24);
2907     emit_byte(0x05+8*r+0x40*mu);
2908     emit_long(base);
2909     }
2910    
2911     static __inline__ void raw_jmp_m(uae_u32 base)
2912     {
2913     emit_byte(0xff);
2914     emit_byte(0x25);
2915     emit_long(base);
2916     }
2917    
2918    
2919     static __inline__ void raw_call(uae_u32 t)
2920     {
2921     emit_byte(0xe8);
2922     emit_long(t-(uae_u32)target-4);
2923     }
2924    
2925     static __inline__ void raw_jmp(uae_u32 t)
2926     {
2927     emit_byte(0xe9);
2928     emit_long(t-(uae_u32)target-4);
2929     }
2930    
2931     static __inline__ void raw_jl(uae_u32 t)
2932     {
2933     emit_byte(0x0f);
2934     emit_byte(0x8c);
2935     emit_long(t-(uae_u32)target-4);
2936     }
2937    
2938     static __inline__ void raw_jz(uae_u32 t)
2939     {
2940     emit_byte(0x0f);
2941     emit_byte(0x84);
2942     emit_long(t-(uae_u32)target-4);
2943     }
2944    
2945     static __inline__ void raw_jnz(uae_u32 t)
2946     {
2947     emit_byte(0x0f);
2948     emit_byte(0x85);
2949     emit_long(t-(uae_u32)target-4);
2950     }
2951    
2952     static __inline__ void raw_jnz_l_oponly(void)
2953     {
2954     emit_byte(0x0f);
2955     emit_byte(0x85);
2956     }
2957    
2958     static __inline__ void raw_jcc_l_oponly(int cc)
2959     {
2960     emit_byte(0x0f);
2961     emit_byte(0x80+cc);
2962     }
2963    
2964     static __inline__ void raw_jnz_b_oponly(void)
2965     {
2966     emit_byte(0x75);
2967     }
2968    
2969     static __inline__ void raw_jz_b_oponly(void)
2970     {
2971     emit_byte(0x74);
2972     }
2973    
2974     static __inline__ void raw_jcc_b_oponly(int cc)
2975     {
2976     emit_byte(0x70+cc);
2977     }
2978    
2979     static __inline__ void raw_jmp_l_oponly(void)
2980     {
2981     emit_byte(0xe9);
2982     }
2983    
2984     static __inline__ void raw_jmp_b_oponly(void)
2985     {
2986     emit_byte(0xeb);
2987     }
2988    
2989     static __inline__ void raw_ret(void)
2990     {
2991     emit_byte(0xc3);
2992     }
2993    
2994     static __inline__ void raw_nop(void)
2995     {
2996     emit_byte(0x90);
2997     }
2998    
2999 gbeauche 1.8 static __inline__ void raw_emit_nop_filler(int nbytes)
3000     {
3001     /* Source: GNU Binutils 2.12.90.0.15 */
3002     /* Various efficient no-op patterns for aligning code labels.
3003     Note: Don't try to assemble the instructions in the comments.
3004     0L and 0w are not legal. */
3005     static const uae_u8 f32_1[] =
3006     {0x90}; /* nop */
3007     static const uae_u8 f32_2[] =
3008     {0x89,0xf6}; /* movl %esi,%esi */
3009     static const uae_u8 f32_3[] =
3010     {0x8d,0x76,0x00}; /* leal 0(%esi),%esi */
3011     static const uae_u8 f32_4[] =
3012     {0x8d,0x74,0x26,0x00}; /* leal 0(%esi,1),%esi */
3013     static const uae_u8 f32_5[] =
3014     {0x90, /* nop */
3015     0x8d,0x74,0x26,0x00}; /* leal 0(%esi,1),%esi */
3016     static const uae_u8 f32_6[] =
3017     {0x8d,0xb6,0x00,0x00,0x00,0x00}; /* leal 0L(%esi),%esi */
3018     static const uae_u8 f32_7[] =
3019     {0x8d,0xb4,0x26,0x00,0x00,0x00,0x00}; /* leal 0L(%esi,1),%esi */
3020     static const uae_u8 f32_8[] =
3021     {0x90, /* nop */
3022     0x8d,0xb4,0x26,0x00,0x00,0x00,0x00}; /* leal 0L(%esi,1),%esi */
3023     static const uae_u8 f32_9[] =
3024     {0x89,0xf6, /* movl %esi,%esi */
3025     0x8d,0xbc,0x27,0x00,0x00,0x00,0x00}; /* leal 0L(%edi,1),%edi */
3026     static const uae_u8 f32_10[] =
3027     {0x8d,0x76,0x00, /* leal 0(%esi),%esi */
3028     0x8d,0xbc,0x27,0x00,0x00,0x00,0x00}; /* leal 0L(%edi,1),%edi */
3029     static const uae_u8 f32_11[] =
3030     {0x8d,0x74,0x26,0x00, /* leal 0(%esi,1),%esi */
3031     0x8d,0xbc,0x27,0x00,0x00,0x00,0x00}; /* leal 0L(%edi,1),%edi */
3032     static const uae_u8 f32_12[] =
3033     {0x8d,0xb6,0x00,0x00,0x00,0x00, /* leal 0L(%esi),%esi */
3034     0x8d,0xbf,0x00,0x00,0x00,0x00}; /* leal 0L(%edi),%edi */
3035     static const uae_u8 f32_13[] =
3036     {0x8d,0xb6,0x00,0x00,0x00,0x00, /* leal 0L(%esi),%esi */
3037     0x8d,0xbc,0x27,0x00,0x00,0x00,0x00}; /* leal 0L(%edi,1),%edi */
3038     static const uae_u8 f32_14[] =
3039     {0x8d,0xb4,0x26,0x00,0x00,0x00,0x00, /* leal 0L(%esi,1),%esi */
3040     0x8d,0xbc,0x27,0x00,0x00,0x00,0x00}; /* leal 0L(%edi,1),%edi */
3041     static const uae_u8 f32_15[] =
3042     {0xeb,0x0d,0x90,0x90,0x90,0x90,0x90, /* jmp .+15; lotsa nops */
3043     0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90};
3044     static const uae_u8 f32_16[] =
3045     {0xeb,0x0d,0x90,0x90,0x90,0x90,0x90, /* jmp .+15; lotsa nops */
3046     0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90};
3047     static const uae_u8 *const f32_patt[] = {
3048     f32_1, f32_2, f32_3, f32_4, f32_5, f32_6, f32_7, f32_8,
3049     f32_9, f32_10, f32_11, f32_12, f32_13, f32_14, f32_15
3050     };
3051    
3052     int nloops = nbytes / 16;
3053     while (nloops-- > 0)
3054     emit_block(f32_16, sizeof(f32_16));
3055    
3056     nbytes %= 16;
3057     if (nbytes)
3058     emit_block(f32_patt[nbytes - 1], nbytes);
3059     }
3060    
3061 gbeauche 1.1
3062     /*************************************************************************
3063     * Flag handling, to and fro UAE flag register *
3064     *************************************************************************/
3065    
3066     #ifdef SAHF_SETO_PROFITABLE
3067    
3068     #define FLAG_NREG1 0 /* Set to -1 if any register will do */
3069    
3070     static __inline__ void raw_flags_to_reg(int r)
3071     {
3072     raw_lahf(0); /* Most flags in AH */
3073     //raw_setcc(r,0); /* V flag in AL */
3074     raw_setcc_m((uae_u32)live.state[FLAGTMP].mem,0);
3075    
3076     #if 1 /* Let's avoid those nasty partial register stalls */
3077     //raw_mov_b_mr((uae_u32)live.state[FLAGTMP].mem,r);
3078     raw_mov_b_mr(((uae_u32)live.state[FLAGTMP].mem)+1,r+4);
3079     //live.state[FLAGTMP].status=CLEAN;
3080     live.state[FLAGTMP].status=INMEM;
3081     live.state[FLAGTMP].realreg=-1;
3082     /* We just "evicted" FLAGTMP. */
3083     if (live.nat[r].nholds!=1) {
3084     /* Huh? */
3085     abort();
3086     }
3087     live.nat[r].nholds=0;
3088     #endif
3089     }
3090    
3091     #define FLAG_NREG2 0 /* Set to -1 if any register will do */
3092     static __inline__ void raw_reg_to_flags(int r)
3093     {
3094     raw_cmp_b_ri(r,-127); /* set V */
3095     raw_sahf(0);
3096     }
3097    
3098     #else
3099    
3100     #define FLAG_NREG1 -1 /* Set to -1 if any register will do */
3101     static __inline__ void raw_flags_to_reg(int r)
3102     {
3103     raw_pushfl();
3104     raw_pop_l_r(r);
3105     raw_mov_l_mr((uae_u32)live.state[FLAGTMP].mem,r);
3106     // live.state[FLAGTMP].status=CLEAN;
3107     live.state[FLAGTMP].status=INMEM;
3108     live.state[FLAGTMP].realreg=-1;
3109     /* We just "evicted" FLAGTMP. */
3110     if (live.nat[r].nholds!=1) {
3111     /* Huh? */
3112     abort();
3113     }
3114     live.nat[r].nholds=0;
3115     }
3116    
3117     #define FLAG_NREG2 -1 /* Set to -1 if any register will do */
3118     static __inline__ void raw_reg_to_flags(int r)
3119     {
3120     raw_push_l_r(r);
3121     raw_popfl();
3122     }
3123    
3124     #endif
3125    
3126     /* Apparently, there are enough instructions between flag store and
3127     flag reload to avoid the partial memory stall */
3128     static __inline__ void raw_load_flagreg(uae_u32 target, uae_u32 r)
3129     {
3130     #if 1
3131     raw_mov_l_rm(target,(uae_u32)live.state[r].mem);
3132     #else
3133     raw_mov_b_rm(target,(uae_u32)live.state[r].mem);
3134     raw_mov_b_rm(target+4,((uae_u32)live.state[r].mem)+1);
3135     #endif
3136     }
3137    
3138     /* FLAGX is byte sized, and we *do* write it at that size */
3139     static __inline__ void raw_load_flagx(uae_u32 target, uae_u32 r)
3140     {
3141     if (live.nat[target].canbyte)
3142     raw_mov_b_rm(target,(uae_u32)live.state[r].mem);
3143     else if (live.nat[target].canword)
3144     raw_mov_w_rm(target,(uae_u32)live.state[r].mem);
3145     else
3146     raw_mov_l_rm(target,(uae_u32)live.state[r].mem);
3147     }
3148    
3149 gbeauche 1.11 #define NATIVE_FLAG_Z 0x40
3150     static __inline__ void raw_flags_set_zero(int f, int r, int t)
3151     {
3152     // FIXME: this is really suboptimal
3153     raw_pushfl();
3154     raw_pop_l_r(f);
3155     raw_and_l_ri(f,~NATIVE_FLAG_Z);
3156     raw_test_l_rr(r,r);
3157     raw_mov_l_ri(r,0);
3158     raw_mov_l_ri(t,NATIVE_FLAG_Z);
3159     raw_cmov_l_rr(r,t,NATIVE_CC_EQ);
3160     raw_or_l(f,r);
3161     raw_push_l_r(f);
3162     raw_popfl();
3163     }
3164 gbeauche 1.1
3165     static __inline__ void raw_inc_sp(int off)
3166     {
3167 gbeauche 1.2 raw_add_l_ri(ESP_INDEX,off);
3168 gbeauche 1.1 }
3169    
3170     /*************************************************************************
3171     * Handling mistaken direct memory access *
3172     *************************************************************************/
3173    
3174     // gb-- I don't need that part for JIT Basilisk II
3175     #if defined(NATMEM_OFFSET) && 0
3176     #include <asm/sigcontext.h>
3177     #include <signal.h>
3178    
3179     #define SIG_READ 1
3180     #define SIG_WRITE 2
3181    
3182     static int in_handler=0;
3183     static uae_u8 veccode[256];
3184    
3185     static void vec(int x, struct sigcontext sc)
3186     {
3187     uae_u8* i=(uae_u8*)sc.eip;
3188     uae_u32 addr=sc.cr2;
3189     int r=-1;
3190     int size=4;
3191     int dir=-1;
3192     int len=0;
3193     int j;
3194    
3195     write_log("fault address is %08x at %08x\n",sc.cr2,sc.eip);
3196     if (!canbang)
3197     write_log("Not happy! Canbang is 0 in SIGSEGV handler!\n");
3198     if (in_handler)
3199     write_log("Argh --- Am already in a handler. Shouldn't happen!\n");
3200    
3201     if (canbang && i>=compiled_code && i<=current_compile_p) {
3202     if (*i==0x66) {
3203     i++;
3204     size=2;
3205     len++;
3206     }
3207    
3208     switch(i[0]) {
3209     case 0x8a:
3210     if ((i[1]&0xc0)==0x80) {
3211     r=(i[1]>>3)&7;
3212     dir=SIG_READ;
3213     size=1;
3214     len+=6;
3215     break;
3216     }
3217     break;
3218     case 0x88:
3219     if ((i[1]&0xc0)==0x80) {
3220     r=(i[1]>>3)&7;
3221     dir=SIG_WRITE;
3222     size=1;
3223     len+=6;
3224     break;
3225     }
3226     break;
3227     case 0x8b:
3228     if ((i[1]&0xc0)==0x80) {
3229     r=(i[1]>>3)&7;
3230     dir=SIG_READ;
3231     len+=6;
3232     break;
3233     }
3234     if ((i[1]&0xc0)==0x40) {
3235     r=(i[1]>>3)&7;
3236     dir=SIG_READ;
3237     len+=3;
3238     break;
3239     }
3240     break;
3241     case 0x89:
3242     if ((i[1]&0xc0)==0x80) {
3243     r=(i[1]>>3)&7;
3244     dir=SIG_WRITE;
3245     len+=6;
3246     break;
3247     }
3248     if ((i[1]&0xc0)==0x40) {
3249     r=(i[1]>>3)&7;
3250     dir=SIG_WRITE;
3251     len+=3;
3252     break;
3253     }
3254     break;
3255     }
3256     }
3257    
3258     if (r!=-1) {
3259     void* pr=NULL;
3260     write_log("register was %d, direction was %d, size was %d\n",r,dir,size);
3261    
3262     switch(r) {
3263     case 0: pr=&(sc.eax); break;
3264     case 1: pr=&(sc.ecx); break;
3265     case 2: pr=&(sc.edx); break;
3266     case 3: pr=&(sc.ebx); break;
3267     case 4: pr=(size>1)?NULL:(((uae_u8*)&(sc.eax))+1); break;
3268     case 5: pr=(size>1)?
3269     (void*)(&(sc.ebp)):
3270     (void*)(((uae_u8*)&(sc.ecx))+1); break;
3271     case 6: pr=(size>1)?
3272     (void*)(&(sc.esi)):
3273     (void*)(((uae_u8*)&(sc.edx))+1); break;
3274     case 7: pr=(size>1)?
3275     (void*)(&(sc.edi)):
3276     (void*)(((uae_u8*)&(sc.ebx))+1); break;
3277     default: abort();
3278     }
3279     if (pr) {
3280     blockinfo* bi;
3281    
3282     if (currprefs.comp_oldsegv) {
3283     addr-=NATMEM_OFFSET;
3284    
3285     if ((addr>=0x10000000 && addr<0x40000000) ||
3286     (addr>=0x50000000)) {
3287     write_log("Suspicious address in %x SEGV handler.\n",addr);
3288     }
3289     if (dir==SIG_READ) {
3290     switch(size) {
3291     case 1: *((uae_u8*)pr)=get_byte(addr); break;
3292     case 2: *((uae_u16*)pr)=get_word(addr); break;
3293     case 4: *((uae_u32*)pr)=get_long(addr); break;
3294     default: abort();
3295     }
3296     }
3297     else { /* write */
3298     switch(size) {
3299     case 1: put_byte(addr,*((uae_u8*)pr)); break;
3300     case 2: put_word(addr,*((uae_u16*)pr)); break;
3301     case 4: put_long(addr,*((uae_u32*)pr)); break;
3302     default: abort();
3303     }
3304     }
3305     write_log("Handled one access!\n");
3306     fflush(stdout);
3307     segvcount++;
3308     sc.eip+=len;
3309     }
3310     else {
3311     void* tmp=target;
3312     int i;
3313     uae_u8 vecbuf[5];
3314    
3315     addr-=NATMEM_OFFSET;
3316    
3317     if ((addr>=0x10000000 && addr<0x40000000) ||
3318     (addr>=0x50000000)) {
3319     write_log("Suspicious address in %x SEGV handler.\n",addr);
3320     }
3321    
3322     target=(uae_u8*)sc.eip;
3323     for (i=0;i<5;i++)
3324     vecbuf[i]=target[i];
3325     emit_byte(0xe9);
3326     emit_long((uae_u32)veccode-(uae_u32)target-4);
3327     write_log("Create jump to %p\n",veccode);
3328    
3329     write_log("Handled one access!\n");
3330     fflush(stdout);
3331     segvcount++;
3332    
3333     target=veccode;
3334    
3335     if (dir==SIG_READ) {
3336     switch(size) {
3337     case 1: raw_mov_b_ri(r,get_byte(addr)); break;
3338     case 2: raw_mov_w_ri(r,get_byte(addr)); break;
3339     case 4: raw_mov_l_ri(r,get_byte(addr)); break;
3340     default: abort();
3341     }
3342     }
3343     else { /* write */
3344     switch(size) {
3345     case 1: put_byte(addr,*((uae_u8*)pr)); break;
3346     case 2: put_word(addr,*((uae_u16*)pr)); break;
3347     case 4: put_long(addr,*((uae_u32*)pr)); break;
3348     default: abort();
3349     }
3350     }
3351     for (i=0;i<5;i++)
3352     raw_mov_b_mi(sc.eip+i,vecbuf[i]);
3353     raw_mov_l_mi((uae_u32)&in_handler,0);
3354     emit_byte(0xe9);
3355     emit_long(sc.eip+len-(uae_u32)target-4);
3356     in_handler=1;
3357     target=tmp;
3358     }
3359     bi=active;
3360     while (bi) {
3361     if (bi->handler &&
3362     (uae_u8*)bi->direct_handler<=i &&
3363     (uae_u8*)bi->nexthandler>i) {
3364     write_log("deleted trigger (%p<%p<%p) %p\n",
3365     bi->handler,
3366     i,
3367     bi->nexthandler,
3368     bi->pc_p);
3369     invalidate_block(bi);
3370     raise_in_cl_list(bi);
3371     set_special(0);
3372     return;
3373     }
3374     bi=bi->next;
3375     }
3376     /* Not found in the active list. Might be a rom routine that
3377     is in the dormant list */
3378     bi=dormant;
3379     while (bi) {
3380     if (bi->handler &&
3381     (uae_u8*)bi->direct_handler<=i &&
3382     (uae_u8*)bi->nexthandler>i) {
3383     write_log("deleted trigger (%p<%p<%p) %p\n",
3384     bi->handler,
3385     i,
3386     bi->nexthandler,
3387     bi->pc_p);
3388     invalidate_block(bi);
3389     raise_in_cl_list(bi);
3390     set_special(0);
3391     return;
3392     }
3393     bi=bi->next;
3394     }
3395     write_log("Huh? Could not find trigger!\n");
3396     return;
3397     }
3398     }
3399     write_log("Can't handle access!\n");
3400     for (j=0;j<10;j++) {
3401     write_log("instruction byte %2d is %02x\n",j,i[j]);
3402     }
3403     write_log("Please send the above info (starting at \"fault address\") to\n"
3404     "bmeyer@csse.monash.edu.au\n"
3405     "This shouldn't happen ;-)\n");
3406     fflush(stdout);
3407     signal(SIGSEGV,SIG_DFL); /* returning here will cause a "real" SEGV */
3408     }
3409     #endif
3410    
3411    
3412     /*************************************************************************
3413     * Checking for CPU features *
3414     *************************************************************************/
3415    
3416 gbeauche 1.3 struct cpuinfo_x86 {
3417     uae_u8 x86; // CPU family
3418     uae_u8 x86_vendor; // CPU vendor
3419     uae_u8 x86_processor; // CPU canonical processor type
3420     uae_u8 x86_brand_id; // CPU BrandID if supported, yield 0 otherwise
3421     uae_u32 x86_hwcap;
3422     uae_u8 x86_model;
3423     uae_u8 x86_mask;
3424     int cpuid_level; // Maximum supported CPUID level, -1=no CPUID
3425     char x86_vendor_id[16];
3426     };
3427     struct cpuinfo_x86 cpuinfo;
3428    
3429     enum {
3430     X86_VENDOR_INTEL = 0,
3431     X86_VENDOR_CYRIX = 1,
3432     X86_VENDOR_AMD = 2,
3433     X86_VENDOR_UMC = 3,
3434     X86_VENDOR_NEXGEN = 4,
3435     X86_VENDOR_CENTAUR = 5,
3436     X86_VENDOR_RISE = 6,
3437     X86_VENDOR_TRANSMETA = 7,
3438     X86_VENDOR_NSC = 8,
3439     X86_VENDOR_UNKNOWN = 0xff
3440     };
3441    
3442     enum {
3443     X86_PROCESSOR_I386, /* 80386 */
3444     X86_PROCESSOR_I486, /* 80486DX, 80486SX, 80486DX[24] */
3445     X86_PROCESSOR_PENTIUM,
3446     X86_PROCESSOR_PENTIUMPRO,
3447     X86_PROCESSOR_K6,
3448     X86_PROCESSOR_ATHLON,
3449     X86_PROCESSOR_PENTIUM4,
3450     X86_PROCESSOR_max
3451     };
3452    
3453     static const char * x86_processor_string_table[X86_PROCESSOR_max] = {
3454     "80386",
3455     "80486",
3456     "Pentium",
3457     "PentiumPro",
3458     "K6",
3459     "Athlon",
3460     "Pentium4"
3461     };
3462    
3463     static struct ptt {
3464     const int align_loop;
3465     const int align_loop_max_skip;
3466     const int align_jump;
3467     const int align_jump_max_skip;
3468     const int align_func;
3469     }
3470     x86_alignments[X86_PROCESSOR_max] = {
3471     { 4, 3, 4, 3, 4 },
3472     { 16, 15, 16, 15, 16 },
3473     { 16, 7, 16, 7, 16 },
3474     { 16, 15, 16, 7, 16 },
3475     { 32, 7, 32, 7, 32 },
3476 gbeauche 1.4 { 16, 7, 16, 7, 16 },
3477 gbeauche 1.3 { 0, 0, 0, 0, 0 }
3478     };
3479 gbeauche 1.1
3480 gbeauche 1.3 static void
3481     x86_get_cpu_vendor(struct cpuinfo_x86 *c)
3482 gbeauche 1.1 {
3483 gbeauche 1.3 char *v = c->x86_vendor_id;
3484    
3485     if (!strcmp(v, "GenuineIntel"))
3486     c->x86_vendor = X86_VENDOR_INTEL;
3487     else if (!strcmp(v, "AuthenticAMD"))
3488     c->x86_vendor = X86_VENDOR_AMD;
3489     else if (!strcmp(v, "CyrixInstead"))
3490     c->x86_vendor = X86_VENDOR_CYRIX;
3491     else if (!strcmp(v, "Geode by NSC"))
3492     c->x86_vendor = X86_VENDOR_NSC;
3493     else if (!strcmp(v, "UMC UMC UMC "))
3494     c->x86_vendor = X86_VENDOR_UMC;
3495     else if (!strcmp(v, "CentaurHauls"))
3496     c->x86_vendor = X86_VENDOR_CENTAUR;
3497     else if (!strcmp(v, "NexGenDriven"))
3498     c->x86_vendor = X86_VENDOR_NEXGEN;
3499     else if (!strcmp(v, "RiseRiseRise"))
3500     c->x86_vendor = X86_VENDOR_RISE;
3501     else if (!strcmp(v, "GenuineTMx86") ||
3502     !strcmp(v, "TransmetaCPU"))
3503     c->x86_vendor = X86_VENDOR_TRANSMETA;
3504     else
3505     c->x86_vendor = X86_VENDOR_UNKNOWN;
3506     }
3507 gbeauche 1.1
3508 gbeauche 1.3 static void
3509     cpuid(uae_u32 op, uae_u32 *eax, uae_u32 *ebx, uae_u32 *ecx, uae_u32 *edx)
3510     {
3511     static uae_u8 cpuid_space[256];
3512     uae_u8* tmp=get_target();
3513 gbeauche 1.1
3514 gbeauche 1.3 set_target(cpuid_space);
3515     raw_push_l_r(0); /* eax */
3516     raw_push_l_r(1); /* ecx */
3517     raw_push_l_r(2); /* edx */
3518     raw_push_l_r(3); /* ebx */
3519     raw_mov_l_rm(0,(uae_u32)&op);
3520     raw_cpuid(0);
3521     if (eax != NULL) raw_mov_l_mr((uae_u32)eax,0);
3522     if (ebx != NULL) raw_mov_l_mr((uae_u32)ebx,3);
3523     if (ecx != NULL) raw_mov_l_mr((uae_u32)ecx,1);
3524     if (edx != NULL) raw_mov_l_mr((uae_u32)edx,2);
3525     raw_pop_l_r(3);
3526     raw_pop_l_r(2);
3527     raw_pop_l_r(1);
3528     raw_pop_l_r(0);
3529     raw_ret();
3530     set_target(tmp);
3531 gbeauche 1.1
3532 gbeauche 1.3 ((cpuop_func*)cpuid_space)(0);
3533 gbeauche 1.1 }
3534    
3535 gbeauche 1.3 static void
3536     raw_init_cpu(void)
3537 gbeauche 1.1 {
3538 gbeauche 1.3 struct cpuinfo_x86 *c = &cpuinfo;
3539    
3540     /* Defaults */
3541     c->x86_vendor = X86_VENDOR_UNKNOWN;
3542     c->cpuid_level = -1; /* CPUID not detected */
3543     c->x86_model = c->x86_mask = 0; /* So far unknown... */
3544     c->x86_vendor_id[0] = '\0'; /* Unset */
3545     c->x86_hwcap = 0;
3546    
3547     /* Get vendor name */
3548     c->x86_vendor_id[12] = '\0';
3549     cpuid(0x00000000,
3550     (uae_u32 *)&c->cpuid_level,
3551     (uae_u32 *)&c->x86_vendor_id[0],
3552     (uae_u32 *)&c->x86_vendor_id[8],
3553     (uae_u32 *)&c->x86_vendor_id[4]);
3554     x86_get_cpu_vendor(c);
3555    
3556     /* Intel-defined flags: level 0x00000001 */
3557     c->x86_brand_id = 0;
3558     if ( c->cpuid_level >= 0x00000001 ) {
3559     uae_u32 tfms, brand_id;
3560     cpuid(0x00000001, &tfms, &brand_id, NULL, &c->x86_hwcap);
3561     c->x86 = (tfms >> 8) & 15;
3562     c->x86_model = (tfms >> 4) & 15;
3563     c->x86_brand_id = brand_id & 0xff;
3564     if ( (c->x86_vendor == X86_VENDOR_AMD) &&
3565     (c->x86 == 0xf)) {
3566     /* AMD Extended Family and Model Values */
3567     c->x86 += (tfms >> 20) & 0xff;
3568     c->x86_model += (tfms >> 12) & 0xf0;
3569     }
3570     c->x86_mask = tfms & 15;
3571     } else {
3572     /* Have CPUID level 0 only - unheard of */
3573     c->x86 = 4;
3574     }
3575    
3576     /* Canonicalize processor ID */
3577     c->x86_processor = X86_PROCESSOR_max;
3578     switch (c->x86) {
3579     case 3:
3580     c->x86_processor = X86_PROCESSOR_I386;
3581     break;
3582     case 4:
3583     c->x86_processor = X86_PROCESSOR_I486;
3584     break;
3585     case 5:
3586     if (c->x86_vendor == X86_VENDOR_AMD)
3587     c->x86_processor = X86_PROCESSOR_K6;
3588     else
3589     c->x86_processor = X86_PROCESSOR_PENTIUM;
3590     break;
3591     case 6:
3592     if (c->x86_vendor == X86_VENDOR_AMD)
3593     c->x86_processor = X86_PROCESSOR_ATHLON;
3594     else
3595     c->x86_processor = X86_PROCESSOR_PENTIUMPRO;
3596     break;
3597     case 15:
3598     if (c->x86_vendor == X86_VENDOR_INTEL) {
3599     /* Assume any BranID >= 8 and family == 15 yields a Pentium 4 */
3600     if (c->x86_brand_id >= 8)
3601     c->x86_processor = X86_PROCESSOR_PENTIUM4;
3602     }
3603     break;
3604     }
3605     if (c->x86_processor == X86_PROCESSOR_max) {
3606     fprintf(stderr, "Error: unknown processor type\n");
3607     fprintf(stderr, " Family : %d\n", c->x86);
3608     fprintf(stderr, " Model : %d\n", c->x86_model);
3609     fprintf(stderr, " Mask : %d\n", c->x86_mask);
3610     if (c->x86_brand_id)
3611     fprintf(stderr, " BrandID : %02x\n", c->x86_brand_id);
3612     abort();
3613     }
3614    
3615     /* Have CMOV support? */
3616     have_cmov = (c->x86_hwcap & (1 << 15)) && true;
3617    
3618     /* Can the host CPU suffer from partial register stalls? */
3619     have_rat_stall = (c->x86_vendor == X86_VENDOR_INTEL);
3620     #if 1
3621     /* It appears that partial register writes are a bad idea even on
3622 gbeauche 1.1 AMD K7 cores, even though they are not supposed to have the
3623     dreaded rat stall. Why? Anyway, that's why we lie about it ;-) */
3624 gbeauche 1.3 if (c->x86_processor == X86_PROCESSOR_ATHLON)
3625     have_rat_stall = true;
3626 gbeauche 1.1 #endif
3627 gbeauche 1.3
3628     /* Alignments */
3629     if (tune_alignment) {
3630     align_loops = x86_alignments[c->x86_processor].align_loop;
3631     align_jumps = x86_alignments[c->x86_processor].align_jump;
3632     }
3633    
3634     write_log("Max CPUID level=%d Processor is %s [%s]\n",
3635     c->cpuid_level, c->x86_vendor_id,
3636     x86_processor_string_table[c->x86_processor]);
3637 gbeauche 1.1 }
3638    
3639 gbeauche 1.10 static bool target_check_bsf(void)
3640     {
3641     bool mismatch = false;
3642     for (int g_ZF = 0; g_ZF <= 1; g_ZF++) {
3643     for (int g_CF = 0; g_CF <= 1; g_CF++) {
3644     for (int g_OF = 0; g_OF <= 1; g_OF++) {
3645     for (int g_SF = 0; g_SF <= 1; g_SF++) {
3646     for (int value = -1; value <= 1; value++) {
3647     int flags = (g_SF << 7) | (g_OF << 11) | (g_ZF << 6) | g_CF;
3648     int tmp = value;
3649     __asm__ __volatile__ ("push %0; popf; bsf %1,%1; pushf; pop %0"
3650 gbeauche 1.12 : "+r" (flags), "+r" (tmp) : : "cc");
3651 gbeauche 1.10 int OF = (flags >> 11) & 1;
3652     int SF = (flags >> 7) & 1;
3653     int ZF = (flags >> 6) & 1;
3654     int CF = flags & 1;
3655     tmp = (value == 0);
3656     if (ZF != tmp || SF != g_SF || OF != g_OF || CF != g_CF)
3657     mismatch = true;
3658     }
3659     }}}}
3660     if (mismatch)
3661     write_log("Target CPU defines all flags on BSF instruction\n");
3662     return !mismatch;
3663     }
3664    
3665 gbeauche 1.1
3666     /*************************************************************************
3667     * FPU stuff *
3668     *************************************************************************/
3669    
3670    
3671     static __inline__ void raw_fp_init(void)
3672     {
3673     int i;
3674    
3675     for (i=0;i<N_FREGS;i++)
3676     live.spos[i]=-2;
3677     live.tos=-1; /* Stack is empty */
3678     }
3679    
3680     static __inline__ void raw_fp_cleanup_drop(void)
3681     {
3682     #if 0
3683     /* using FINIT instead of popping all the entries.
3684     Seems to have side effects --- there is display corruption in
3685     Quake when this is used */
3686     if (live.tos>1) {
3687     emit_byte(0x9b);
3688     emit_byte(0xdb);
3689     emit_byte(0xe3);
3690     live.tos=-1;
3691     }
3692     #endif
3693     while (live.tos>=1) {
3694     emit_byte(0xde);
3695     emit_byte(0xd9);
3696     live.tos-=2;
3697     }
3698     while (live.tos>=0) {
3699     emit_byte(0xdd);
3700     emit_byte(0xd8);
3701     live.tos--;
3702     }
3703     raw_fp_init();
3704     }
3705    
3706     static __inline__ void make_tos(int r)
3707     {
3708     int p,q;
3709    
3710     if (live.spos[r]<0) { /* Register not yet on stack */
3711     emit_byte(0xd9);
3712     emit_byte(0xe8); /* Push '1' on the stack, just to grow it */
3713     live.tos++;
3714     live.spos[r]=live.tos;
3715     live.onstack[live.tos]=r;
3716     return;
3717     }
3718     /* Register is on stack */
3719     if (live.tos==live.spos[r])
3720     return;
3721     p=live.spos[r];
3722     q=live.onstack[live.tos];
3723    
3724     emit_byte(0xd9);
3725     emit_byte(0xc8+live.tos-live.spos[r]); /* exchange it with top of stack */
3726     live.onstack[live.tos]=r;
3727     live.spos[r]=live.tos;
3728     live.onstack[p]=q;
3729     live.spos[q]=p;
3730     }
3731    
3732     static __inline__ void make_tos2(int r, int r2)
3733     {
3734     int q;
3735    
3736     make_tos(r2); /* Put the reg that's supposed to end up in position2
3737     on top */
3738    
3739     if (live.spos[r]<0) { /* Register not yet on stack */
3740     make_tos(r); /* This will extend the stack */
3741     return;
3742     }
3743     /* Register is on stack */
3744     emit_byte(0xd9);
3745     emit_byte(0xc9); /* Move r2 into position 2 */
3746    
3747     q=live.onstack[live.tos-1];
3748     live.onstack[live.tos]=q;
3749     live.spos[q]=live.tos;
3750     live.onstack[live.tos-1]=r2;
3751     live.spos[r2]=live.tos-1;
3752    
3753     make_tos(r); /* And r into 1 */
3754     }
3755    
3756     static __inline__ int stackpos(int r)
3757     {
3758     if (live.spos[r]<0)
3759     abort();
3760     if (live.tos<live.spos[r]) {
3761     printf("Looking for spos for fnreg %d\n",r);
3762     abort();
3763     }
3764     return live.tos-live.spos[r];
3765     }
3766    
3767     static __inline__ void usereg(int r)
3768     {
3769     if (live.spos[r]<0)
3770     make_tos(r);
3771     }
3772    
3773     /* This is called with one FP value in a reg *above* tos, which it will
3774     pop off the stack if necessary */
3775     static __inline__ void tos_make(int r)
3776     {
3777     if (live.spos[r]<0) {
3778     live.tos++;
3779     live.spos[r]=live.tos;
3780     live.onstack[live.tos]=r;
3781     return;
3782     }
3783     emit_byte(0xdd);
3784     emit_byte(0xd8+(live.tos+1)-live.spos[r]); /* store top of stack in reg,
3785     and pop it*/
3786     }
3787    
3788    
3789     LOWFUNC(NONE,WRITE,2,raw_fmov_mr,(MEMW m, FR r))
3790     {
3791     make_tos(r);
3792     emit_byte(0xdd);
3793     emit_byte(0x15);
3794     emit_long(m);
3795     }
3796     LENDFUNC(NONE,WRITE,2,raw_fmov_mr,(MEMW m, FR r))
3797    
3798     LOWFUNC(NONE,WRITE,2,raw_fmov_mr_drop,(MEMW m, FR r))
3799     {
3800     make_tos(r);
3801     emit_byte(0xdd);
3802     emit_byte(0x1d);
3803     emit_long(m);
3804     live.onstack[live.tos]=-1;
3805     live.tos--;
3806     live.spos[r]=-2;
3807     }
3808     LENDFUNC(NONE,WRITE,2,raw_fmov_mr,(MEMW m, FR r))
3809    
3810     LOWFUNC(NONE,READ,2,raw_fmov_rm,(FW r, MEMR m))
3811     {
3812     emit_byte(0xdd);
3813     emit_byte(0x05);
3814     emit_long(m);
3815     tos_make(r);
3816     }
3817     LENDFUNC(NONE,READ,2,raw_fmov_rm,(FW r, MEMR m))
3818    
3819     LOWFUNC(NONE,READ,2,raw_fmovi_rm,(FW r, MEMR m))
3820     {
3821     emit_byte(0xdb);
3822     emit_byte(0x05);
3823     emit_long(m);
3824     tos_make(r);
3825     }
3826     LENDFUNC(NONE,READ,2,raw_fmovi_rm,(FW r, MEMR m))
3827    
3828     LOWFUNC(NONE,WRITE,2,raw_fmovi_mr,(MEMW m, FR r))
3829     {
3830     make_tos(r);
3831     emit_byte(0xdb);
3832     emit_byte(0x15);
3833     emit_long(m);
3834     }
3835     LENDFUNC(NONE,WRITE,2,raw_fmovi_mr,(MEMW m, FR r))
3836    
3837     LOWFUNC(NONE,READ,2,raw_fmovs_rm,(FW r, MEMR m))
3838     {
3839     emit_byte(0xd9);
3840     emit_byte(0x05);
3841     emit_long(m);
3842     tos_make(r);
3843     }
3844     LENDFUNC(NONE,READ,2,raw_fmovs_rm,(FW r, MEMR m))
3845    
3846     LOWFUNC(NONE,WRITE,2,raw_fmovs_mr,(MEMW m, FR r))
3847     {
3848     make_tos(r);
3849     emit_byte(0xd9);
3850     emit_byte(0x15);
3851     emit_long(m);
3852     }
3853     LENDFUNC(NONE,WRITE,2,raw_fmovs_mr,(MEMW m, FR r))
3854    
3855     LOWFUNC(NONE,WRITE,2,raw_fmov_ext_mr,(MEMW m, FR r))
3856     {
3857     int rs;
3858    
3859     /* Stupid x87 can't write a long double to mem without popping the
3860     stack! */
3861     usereg(r);
3862     rs=stackpos(r);
3863     emit_byte(0xd9); /* Get a copy to the top of stack */
3864     emit_byte(0xc0+rs);
3865    
3866     emit_byte(0xdb); /* store and pop it */
3867     emit_byte(0x3d);
3868     emit_long(m);
3869     }
3870     LENDFUNC(NONE,WRITE,2,raw_fmov_ext_mr,(MEMW m, FR r))
3871    
3872     LOWFUNC(NONE,WRITE,2,raw_fmov_ext_mr_drop,(MEMW m, FR r))
3873     {
3874     int rs;
3875    
3876     make_tos(r);
3877     emit_byte(0xdb); /* store and pop it */
3878     emit_byte(0x3d);
3879     emit_long(m);
3880     live.onstack[live.tos]=-1;
3881     live.tos--;
3882     live.spos[r]=-2;
3883     }
3884     LENDFUNC(NONE,WRITE,2,raw_fmov_ext_mr,(MEMW m, FR r))
3885    
3886     LOWFUNC(NONE,READ,2,raw_fmov_ext_rm,(FW r, MEMR m))
3887     {
3888     emit_byte(0xdb);
3889     emit_byte(0x2d);
3890     emit_long(m);
3891     tos_make(r);
3892     }
3893     LENDFUNC(NONE,READ,2,raw_fmov_ext_rm,(FW r, MEMR m))
3894    
3895     LOWFUNC(NONE,NONE,1,raw_fmov_pi,(FW r))
3896     {
3897     emit_byte(0xd9);
3898     emit_byte(0xeb);
3899     tos_make(r);
3900     }
3901     LENDFUNC(NONE,NONE,1,raw_fmov_pi,(FW r))
3902    
3903     LOWFUNC(NONE,NONE,1,raw_fmov_log10_2,(FW r))
3904     {
3905     emit_byte(0xd9);
3906     emit_byte(0xec);
3907     tos_make(r);
3908     }
3909     LENDFUNC(NONE,NONE,1,raw_fmov_log10_2,(FW r))
3910    
3911     LOWFUNC(NONE,NONE,1,raw_fmov_log2_e,(FW r))
3912     {
3913     emit_byte(0xd9);
3914     emit_byte(0xea);
3915     tos_make(r);
3916     }
3917     LENDFUNC(NONE,NONE,1,raw_fmov_log2_e,(FW r))
3918    
3919     LOWFUNC(NONE,NONE,1,raw_fmov_loge_2,(FW r))
3920     {
3921     emit_byte(0xd9);
3922     emit_byte(0xed);
3923     tos_make(r);
3924     }
3925     LENDFUNC(NONE,NONE,1,raw_fmov_loge_2,(FW r))
3926    
3927     LOWFUNC(NONE,NONE,1,raw_fmov_1,(FW r))
3928     {
3929     emit_byte(0xd9);
3930     emit_byte(0xe8);
3931     tos_make(r);
3932     }
3933     LENDFUNC(NONE,NONE,1,raw_fmov_1,(FW r))
3934    
3935     LOWFUNC(NONE,NONE,1,raw_fmov_0,(FW r))
3936     {
3937     emit_byte(0xd9);
3938     emit_byte(0xee);
3939     tos_make(r);
3940     }
3941     LENDFUNC(NONE,NONE,1,raw_fmov_0,(FW r))
3942    
3943     LOWFUNC(NONE,NONE,2,raw_fmov_rr,(FW d, FR s))
3944     {
3945     int ds;
3946    
3947     usereg(s);
3948     ds=stackpos(s);
3949     if (ds==0 && live.spos[d]>=0) {
3950     /* source is on top of stack, and we already have the dest */
3951     int dd=stackpos(d);
3952     emit_byte(0xdd);
3953     emit_byte(0xd0+dd);
3954     }
3955     else {
3956     emit_byte(0xd9);
3957     emit_byte(0xc0+ds); /* duplicate source on tos */
3958     tos_make(d); /* store to destination, pop if necessary */
3959     }
3960     }
3961     LENDFUNC(NONE,NONE,2,raw_fmov_rr,(FW d, FR s))
3962    
3963     LOWFUNC(NONE,READ,4,raw_fldcw_m_indexed,(R4 index, IMM base))
3964     {
3965     emit_byte(0xd9);
3966     emit_byte(0xa8+index);
3967     emit_long(base);
3968     }
3969     LENDFUNC(NONE,READ,4,raw_fldcw_m_indexed,(R4 index, IMM base))
3970    
3971    
3972     LOWFUNC(NONE,NONE,2,raw_fsqrt_rr,(FW d, FR s))
3973     {
3974     int ds;
3975    
3976     if (d!=s) {
3977     usereg(s);
3978     ds=stackpos(s);
3979     emit_byte(0xd9);
3980     emit_byte(0xc0+ds); /* duplicate source */
3981     emit_byte(0xd9);
3982     emit_byte(0xfa); /* take square root */
3983     tos_make(d); /* store to destination */
3984     }
3985     else {
3986     make_tos(d);
3987     emit_byte(0xd9);
3988     emit_byte(0xfa); /* take square root */
3989     }
3990     }
3991     LENDFUNC(NONE,NONE,2,raw_fsqrt_rr,(FW d, FR s))
3992    
3993     LOWFUNC(NONE,NONE,2,raw_fabs_rr,(FW d, FR s))
3994     {
3995     int ds;
3996    
3997     if (d!=s) {
3998     usereg(s);
3999     ds=stackpos(s);
4000     emit_byte(0xd9);
4001     emit_byte(0xc0+ds); /* duplicate source */
4002     emit_byte(0xd9);
4003     emit_byte(0xe1); /* take fabs */
4004     tos_make(d); /* store to destination */
4005     }
4006     else {
4007     make_tos(d);
4008     emit_byte(0xd9);
4009     emit_byte(0xe1); /* take fabs */
4010     }
4011     }
4012     LENDFUNC(NONE,NONE,2,raw_fabs_rr,(FW d, FR s))
4013    
4014     LOWFUNC(NONE,NONE,2,raw_frndint_rr,(FW d, FR s))
4015     {
4016     int ds;
4017    
4018     if (d!=s) {
4019     usereg(s);
4020     ds=stackpos(s);
4021     emit_byte(0xd9);
4022     emit_byte(0xc0+ds); /* duplicate source */
4023     emit_byte(0xd9);
4024     emit_byte(0xfc); /* take frndint */
4025     tos_make(d); /* store to destination */
4026     }
4027     else {
4028     make_tos(d);
4029     emit_byte(0xd9);
4030     emit_byte(0xfc); /* take frndint */
4031     }
4032     }
4033     LENDFUNC(NONE,NONE,2,raw_frndint_rr,(FW d, FR s))
4034    
4035     LOWFUNC(NONE,NONE,2,raw_fcos_rr,(FW d, FR s))
4036     {
4037     int ds;
4038    
4039     if (d!=s) {
4040     usereg(s);
4041     ds=stackpos(s);
4042     emit_byte(0xd9);
4043     emit_byte(0xc0+ds); /* duplicate source */
4044     emit_byte(0xd9);
4045     emit_byte(0xff); /* take cos */
4046     tos_make(d); /* store to destination */
4047     }
4048     else {
4049     make_tos(d);
4050     emit_byte(0xd9);
4051     emit_byte(0xff); /* take cos */
4052     }
4053     }
4054     LENDFUNC(NONE,NONE,2,raw_fcos_rr,(FW d, FR s))
4055    
4056     LOWFUNC(NONE,NONE,2,raw_fsin_rr,(FW d, FR s))
4057     {
4058     int ds;
4059    
4060     if (d!=s) {
4061     usereg(s);
4062     ds=stackpos(s);
4063     emit_byte(0xd9);
4064     emit_byte(0xc0+ds); /* duplicate source */
4065     emit_byte(0xd9);
4066     emit_byte(0xfe); /* take sin */
4067     tos_make(d); /* store to destination */
4068     }
4069     else {
4070     make_tos(d);
4071     emit_byte(0xd9);
4072     emit_byte(0xfe); /* take sin */
4073     }
4074     }
4075     LENDFUNC(NONE,NONE,2,raw_fsin_rr,(FW d, FR s))
4076    
4077     double one=1;
4078     LOWFUNC(NONE,NONE,2,raw_ftwotox_rr,(FW d, FR s))
4079     {
4080     int ds;
4081    
4082     usereg(s);
4083     ds=stackpos(s);
4084     emit_byte(0xd9);
4085     emit_byte(0xc0+ds); /* duplicate source */
4086    
4087     emit_byte(0xd9);
4088     emit_byte(0xc0); /* duplicate top of stack. Now up to 8 high */
4089     emit_byte(0xd9);
4090     emit_byte(0xfc); /* rndint */
4091     emit_byte(0xd9);
4092     emit_byte(0xc9); /* swap top two elements */
4093     emit_byte(0xd8);
4094     emit_byte(0xe1); /* subtract rounded from original */
4095     emit_byte(0xd9);
4096     emit_byte(0xf0); /* f2xm1 */
4097     emit_byte(0xdc);
4098     emit_byte(0x05);
4099     emit_long((uae_u32)&one); /* Add '1' without using extra stack space */
4100     emit_byte(0xd9);
4101     emit_byte(0xfd); /* and scale it */
4102     emit_byte(0xdd);
4103     emit_byte(0xd9); /* take he rounded value off */
4104     tos_make(d); /* store to destination */
4105     }
4106     LENDFUNC(NONE,NONE,2,raw_ftwotox_rr,(FW d, FR s))
4107    
4108     LOWFUNC(NONE,NONE,2,raw_fetox_rr,(FW d, FR s))
4109     {
4110     int ds;
4111    
4112     usereg(s);
4113     ds=stackpos(s);
4114     emit_byte(0xd9);
4115     emit_byte(0xc0+ds); /* duplicate source */
4116     emit_byte(0xd9);
4117     emit_byte(0xea); /* fldl2e */
4118     emit_byte(0xde);
4119     emit_byte(0xc9); /* fmulp --- multiply source by log2(e) */
4120    
4121     emit_byte(0xd9);
4122     emit_byte(0xc0); /* duplicate top of stack. Now up to 8 high */
4123     emit_byte(0xd9);
4124     emit_byte(0xfc); /* rndint */
4125     emit_byte(0xd9);
4126     emit_byte(0xc9); /* swap top two elements */
4127     emit_byte(0xd8);
4128     emit_byte(0xe1); /* subtract rounded from original */
4129     emit_byte(0xd9);
4130     emit_byte(0xf0); /* f2xm1 */
4131     emit_byte(0xdc);
4132     emit_byte(0x05);
4133     emit_long((uae_u32)&one); /* Add '1' without using extra stack space */
4134     emit_byte(0xd9);
4135     emit_byte(0xfd); /* and scale it */
4136     emit_byte(0xdd);
4137     emit_byte(0xd9); /* take he rounded value off */
4138     tos_make(d); /* store to destination */
4139     }
4140     LENDFUNC(NONE,NONE,2,raw_fetox_rr,(FW d, FR s))
4141    
4142     LOWFUNC(NONE,NONE,2,raw_flog2_rr,(FW d, FR s))
4143     {
4144     int ds;
4145    
4146     usereg(s);
4147     ds=stackpos(s);
4148     emit_byte(0xd9);
4149     emit_byte(0xc0+ds); /* duplicate source */
4150     emit_byte(0xd9);
4151     emit_byte(0xe8); /* push '1' */
4152     emit_byte(0xd9);
4153     emit_byte(0xc9); /* swap top two */
4154     emit_byte(0xd9);
4155     emit_byte(0xf1); /* take 1*log2(x) */
4156     tos_make(d); /* store to destination */
4157     }
4158     LENDFUNC(NONE,NONE,2,raw_flog2_rr,(FW d, FR s))
4159    
4160    
4161     LOWFUNC(NONE,NONE,2,raw_fneg_rr,(FW d, FR s))
4162     {
4163     int ds;
4164    
4165     if (d!=s) {
4166     usereg(s);
4167     ds=stackpos(s);
4168     emit_byte(0xd9);
4169     emit_byte(0xc0+ds); /* duplicate source */
4170     emit_byte(0xd9);
4171     emit_byte(0xe0); /* take fchs */
4172     tos_make(d); /* store to destination */
4173     }
4174     else {
4175     make_tos(d);
4176     emit_byte(0xd9);
4177     emit_byte(0xe0); /* take fchs */
4178     }
4179     }
4180     LENDFUNC(NONE,NONE,2,raw_fneg_rr,(FW d, FR s))
4181    
4182     LOWFUNC(NONE,NONE,2,raw_fadd_rr,(FRW d, FR s))
4183     {
4184     int ds;
4185    
4186     usereg(s);
4187     usereg(d);
4188    
4189     if (live.spos[s]==live.tos) {
4190     /* Source is on top of stack */
4191     ds=stackpos(d);
4192     emit_byte(0xdc);
4193     emit_byte(0xc0+ds); /* add source to dest*/
4194     }
4195     else {
4196     make_tos(d);
4197     ds=stackpos(s);
4198    
4199     emit_byte(0xd8);
4200     emit_byte(0xc0+ds); /* add source to dest*/
4201     }
4202     }
4203     LENDFUNC(NONE,NONE,2,raw_fadd_rr,(FRW d, FR s))
4204    
4205     LOWFUNC(NONE,NONE,2,raw_fsub_rr,(FRW d, FR s))
4206     {
4207     int ds;
4208    
4209     usereg(s);
4210     usereg(d);
4211    
4212     if (live.spos[s]==live.tos) {
4213     /* Source is on top of stack */
4214     ds=stackpos(d);
4215     emit_byte(0xdc);
4216     emit_byte(0xe8+ds); /* sub source from dest*/
4217     }
4218     else {
4219     make_tos(d);
4220     ds=stackpos(s);
4221    
4222     emit_byte(0xd8);
4223     emit_byte(0xe0+ds); /* sub src from dest */
4224     }
4225     }
4226     LENDFUNC(NONE,NONE,2,raw_fsub_rr,(FRW d, FR s))
4227    
4228     LOWFUNC(NONE,NONE,2,raw_fcmp_rr,(FR d, FR s))
4229     {
4230     int ds;
4231    
4232     usereg(s);
4233     usereg(d);
4234    
4235     make_tos(d);
4236     ds=stackpos(s);
4237    
4238     emit_byte(0xdd);
4239     emit_byte(0xe0+ds); /* cmp dest with source*/
4240     }
4241     LENDFUNC(NONE,NONE,2,raw_fcmp_rr,(FR d, FR s))
4242    
4243     LOWFUNC(NONE,NONE,2,raw_fmul_rr,(FRW d, FR s))
4244     {
4245     int ds;
4246    
4247     usereg(s);
4248     usereg(d);
4249    
4250     if (live.spos[s]==live.tos) {
4251     /* Source is on top of stack */
4252     ds=stackpos(d);
4253     emit_byte(0xdc);
4254     emit_byte(0xc8+ds); /* mul dest by source*/
4255     }
4256     else {
4257     make_tos(d);
4258     ds=stackpos(s);
4259    
4260     emit_byte(0xd8);
4261     emit_byte(0xc8+ds); /* mul dest by source*/
4262     }
4263     }
4264     LENDFUNC(NONE,NONE,2,raw_fmul_rr,(FRW d, FR s))
4265    
4266     LOWFUNC(NONE,NONE,2,raw_fdiv_rr,(FRW d, FR s))
4267     {
4268     int ds;
4269    
4270     usereg(s);
4271     usereg(d);
4272    
4273     if (live.spos[s]==live.tos) {
4274     /* Source is on top of stack */
4275     ds=stackpos(d);
4276     emit_byte(0xdc);
4277     emit_byte(0xf8+ds); /* div dest by source */
4278     }
4279     else {
4280     make_tos(d);
4281     ds=stackpos(s);
4282    
4283     emit_byte(0xd8);
4284     emit_byte(0xf0+ds); /* div dest by source*/
4285     }
4286     }
4287     LENDFUNC(NONE,NONE,2,raw_fdiv_rr,(FRW d, FR s))
4288    
4289     LOWFUNC(NONE,NONE,2,raw_frem_rr,(FRW d, FR s))
4290     {
4291     int ds;
4292    
4293     usereg(s);
4294     usereg(d);
4295    
4296     make_tos2(d,s);
4297     ds=stackpos(s);
4298    
4299     if (ds!=1) {
4300     printf("Failed horribly in raw_frem_rr! ds is %d\n",ds);
4301     abort();
4302     }
4303     emit_byte(0xd9);
4304     emit_byte(0xf8); /* take rem from dest by source */
4305     }
4306     LENDFUNC(NONE,NONE,2,raw_frem_rr,(FRW d, FR s))
4307    
4308     LOWFUNC(NONE,NONE,2,raw_frem1_rr,(FRW d, FR s))
4309     {
4310     int ds;
4311    
4312     usereg(s);
4313     usereg(d);
4314    
4315     make_tos2(d,s);
4316     ds=stackpos(s);
4317    
4318     if (ds!=1) {
4319     printf("Failed horribly in raw_frem1_rr! ds is %d\n",ds);
4320     abort();
4321     }
4322     emit_byte(0xd9);
4323     emit_byte(0xf5); /* take rem1 from dest by source */
4324     }
4325     LENDFUNC(NONE,NONE,2,raw_frem1_rr,(FRW d, FR s))
4326    
4327    
4328     LOWFUNC(NONE,NONE,1,raw_ftst_r,(FR r))
4329     {
4330     make_tos(r);
4331     emit_byte(0xd9); /* ftst */
4332     emit_byte(0xe4);
4333     }
4334     LENDFUNC(NONE,NONE,1,raw_ftst_r,(FR r))
4335    
4336     /* %eax register is clobbered if target processor doesn't support fucomi */
4337     #define FFLAG_NREG_CLOBBER_CONDITION !have_cmov
4338     #define FFLAG_NREG EAX_INDEX
4339    
4340     static __inline__ void raw_fflags_into_flags(int r)
4341     {
4342     int p;
4343    
4344     usereg(r);
4345     p=stackpos(r);
4346    
4347     emit_byte(0xd9);
4348     emit_byte(0xee); /* Push 0 */
4349     emit_byte(0xd9);
4350     emit_byte(0xc9+p); /* swap top two around */
4351     if (have_cmov) {
4352     // gb-- fucomi is for P6 cores only, not K6-2 then...
4353     emit_byte(0xdb);
4354     emit_byte(0xe9+p); /* fucomi them */
4355     }
4356     else {
4357     emit_byte(0xdd);
4358     emit_byte(0xe1+p); /* fucom them */
4359     emit_byte(0x9b);
4360     emit_byte(0xdf);
4361     emit_byte(0xe0); /* fstsw ax */
4362     raw_sahf(0); /* sahf */
4363     }
4364     emit_byte(0xdd);
4365     emit_byte(0xd9+p); /* store value back, and get rid of 0 */
4366     }