4 Byte Stackslots for i386 (native Calling Convention)
[cacao.git] / src / vm / jit / i386 / emitfuncs.c
1 /* vm/jit/i386/emitfuncs.c - i386 code emitter functions
2
3    Copyright (C) 1996-2005 R. Grafl, A. Krall, C. Kruegel, C. Oates,
4    R. Obermaisser, M. Platter, M. Probst, S. Ring, E. Steiner,
5    C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich, J. Wenninger,
6    Institut f. Computersprachen - TU Wien
7
8    This file is part of CACAO.
9
10    This program is free software; you can redistribute it and/or
11    modify it under the terms of the GNU General Public License as
12    published by the Free Software Foundation; either version 2, or (at
13    your option) any later version.
14
15    This program is distributed in the hope that it will be useful, but
16    WITHOUT ANY WARRANTY; without even the implied warranty of
17    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
18    General Public License for more details.
19
20    You should have received a copy of the GNU General Public License
21    along with this program; if not, write to the Free Software
22    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
23    02111-1307, USA.
24
25    Contact: cacao@complang.tuwien.ac.at
26
27    Authors: Christian Thalinger
28
29    $Id: emitfuncs.c 2356 2005-04-22 17:33:35Z christian $
30
31 */
32
33 #include "vm/statistics.h"
34 #include "vm/jit/jit.h"
35 #include "vm/jit/i386/emitfuncs.h"
36 #include "vm/jit/i386/codegen.h"
37 #include "vm/jit/i386/types.h"
38
39 #ifdef STATISTICS
40 #define COUNT(a) (a)++
41 #else
42 #define COUNT(a)
43 #endif
44
45
46 void i386_emit_ialu(codegendata *cd, s4 alu_op, stackptr src, instruction *iptr)
47 {
48         if (iptr->dst->flags & INMEMORY) {
49                 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
50                         if (src->regoff == iptr->dst->regoff) {
51                                 i386_mov_membase_reg(cd, REG_SP, src->prev->regoff * 4, REG_ITMP1);
52                                 i386_alu_reg_membase(cd, alu_op, REG_ITMP1, REG_SP, iptr->dst->regoff * 4);
53
54                         } else if (src->prev->regoff == iptr->dst->regoff) {
55                                 i386_mov_membase_reg(cd, REG_SP, src->regoff * 4, REG_ITMP1);
56                                 i386_alu_reg_membase(cd, alu_op, REG_ITMP1, REG_SP, iptr->dst->regoff * 4);
57
58                         } else {
59                                 i386_mov_membase_reg(cd, REG_SP, src->prev->regoff * 4, REG_ITMP1);
60                                 i386_alu_membase_reg(cd, alu_op, REG_SP, src->regoff * 4, REG_ITMP1);
61                                 i386_mov_reg_membase(cd, REG_ITMP1, REG_SP, iptr->dst->regoff * 4);
62                         }
63
64                 } else if ((src->flags & INMEMORY) && !(src->prev->flags & INMEMORY)) {
65                         if (src->regoff == iptr->dst->regoff) {
66                                 i386_alu_reg_membase(cd, alu_op, src->prev->regoff, REG_SP, iptr->dst->regoff * 4);
67
68                         } else {
69                                 i386_mov_membase_reg(cd, REG_SP, src->regoff * 4, REG_ITMP1);
70                                 i386_alu_reg_reg(cd, alu_op, src->prev->regoff, REG_ITMP1);
71                                 i386_mov_reg_membase(cd, REG_ITMP1, REG_SP, iptr->dst->regoff * 4);
72                         }
73
74                 } else if (!(src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
75                         if (src->prev->regoff == iptr->dst->regoff) {
76                                 i386_alu_reg_membase(cd, alu_op, src->regoff, REG_SP, iptr->dst->regoff * 4);
77                                                 
78                         } else {
79                                 i386_mov_membase_reg(cd, REG_SP, src->prev->regoff * 4, REG_ITMP1);
80                                 i386_alu_reg_reg(cd, alu_op, src->regoff, REG_ITMP1);
81                                 i386_mov_reg_membase(cd, REG_ITMP1, REG_SP, iptr->dst->regoff * 4);
82                         }
83
84                 } else {
85                         i386_mov_reg_membase(cd, src->prev->regoff, REG_SP, iptr->dst->regoff * 4);
86                         i386_alu_reg_membase(cd, alu_op, src->regoff, REG_SP, iptr->dst->regoff * 4);
87                 }
88
89         } else {
90                 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
91                         i386_mov_membase_reg(cd, REG_SP, src->prev->regoff * 4, iptr->dst->regoff);
92                         i386_alu_membase_reg(cd, alu_op, REG_SP, src->regoff * 4, iptr->dst->regoff);
93
94                 } else if ((src->flags & INMEMORY) && !(src->prev->flags & INMEMORY)) {
95                         if (src->prev->regoff != iptr->dst->regoff)
96                                 i386_mov_reg_reg(cd, src->prev->regoff, iptr->dst->regoff);
97
98                         i386_alu_membase_reg(cd, alu_op, REG_SP, src->regoff * 4, iptr->dst->regoff);
99
100                 } else if (!(src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
101                         if (src->regoff != iptr->dst->regoff)
102                                 i386_mov_reg_reg(cd, src->regoff, iptr->dst->regoff);
103
104                         i386_alu_membase_reg(cd, alu_op, REG_SP, src->prev->regoff * 4, iptr->dst->regoff);
105
106                 } else {
107                         if (src->regoff == iptr->dst->regoff) {
108                                 i386_alu_reg_reg(cd, alu_op, src->prev->regoff, iptr->dst->regoff);
109
110                         } else {
111                                 if (src->prev->regoff != iptr->dst->regoff)
112                                         i386_mov_reg_reg(cd, src->prev->regoff, iptr->dst->regoff);
113
114                                 i386_alu_reg_reg(cd, alu_op, src->regoff, iptr->dst->regoff);
115                         }
116                 }
117         }
118 }
119
120
121 void i386_emit_ialuconst(codegendata *cd, s4 alu_op, stackptr src, instruction *iptr)
122 {
123         if (iptr->dst->flags & INMEMORY) {
124                 if (src->flags & INMEMORY) {
125                         if (src->regoff == iptr->dst->regoff) {
126                                 i386_alu_imm_membase(cd, alu_op, iptr->val.i, REG_SP, iptr->dst->regoff * 4);
127
128                         } else {
129                                 i386_mov_membase_reg(cd, REG_SP, src->regoff * 4, REG_ITMP1);
130                                 i386_alu_imm_reg(cd, alu_op, iptr->val.i, REG_ITMP1);
131                                 i386_mov_reg_membase(cd, REG_ITMP1, REG_SP, iptr->dst->regoff * 4);
132                         }
133
134                 } else {
135                         i386_mov_reg_membase(cd, src->regoff, REG_SP, iptr->dst->regoff * 4);
136                         i386_alu_imm_membase(cd, alu_op, iptr->val.i, REG_SP, iptr->dst->regoff * 4);
137                 }
138
139         } else {
140                 if (src->flags & INMEMORY) {
141                         i386_mov_membase_reg(cd, REG_SP, src->regoff * 4, iptr->dst->regoff);
142                         i386_alu_imm_reg(cd, alu_op, iptr->val.i, iptr->dst->regoff);
143
144                 } else {
145                         if (src->regoff != iptr->dst->regoff)
146                                 i386_mov_reg_reg(cd, src->regoff, iptr->dst->regoff);
147
148                         /* `inc reg' is slower on p4's (regarding to ia32 optimization    */
149                         /* reference manual and benchmarks) and as fast on athlon's.      */
150                         i386_alu_imm_reg(cd, alu_op, iptr->val.i, iptr->dst->regoff);
151                 }
152         }
153 }
154
155
156 void i386_emit_lalu(codegendata *cd, s4 alu_op, stackptr src, instruction *iptr)
157 {
158         if (iptr->dst->flags & INMEMORY) {
159                 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
160                         if (src->regoff == iptr->dst->regoff) {
161                                 i386_mov_membase_reg(cd, REG_SP, src->prev->regoff * 4, REG_ITMP1);
162                                 i386_alu_reg_membase(cd, alu_op, REG_ITMP1, REG_SP, iptr->dst->regoff * 4);
163                                 i386_mov_membase_reg(cd, REG_SP, src->prev->regoff * 4 + 4, REG_ITMP1);
164                                 i386_alu_reg_membase(cd, alu_op, REG_ITMP1, REG_SP, iptr->dst->regoff * 4 + 4);
165
166                         } else if (src->prev->regoff == iptr->dst->regoff) {
167                                 i386_mov_membase_reg(cd, REG_SP, src->regoff * 4, REG_ITMP1);
168                                 i386_alu_reg_membase(cd, alu_op, REG_ITMP1, REG_SP, iptr->dst->regoff * 4);
169                                 i386_mov_membase_reg(cd, REG_SP, src->regoff * 4 + 4, REG_ITMP1);
170                                 i386_alu_reg_membase(cd, alu_op, REG_ITMP1, REG_SP, iptr->dst->regoff * 4 + 4);
171
172                         } else {
173                                 i386_mov_membase_reg(cd, REG_SP, src->prev->regoff * 4, REG_ITMP1);
174                                 i386_alu_membase_reg(cd, alu_op, REG_SP, src->regoff * 4, REG_ITMP1);
175                                 i386_mov_reg_membase(cd, REG_ITMP1, REG_SP, iptr->dst->regoff * 4);
176                                 i386_mov_membase_reg(cd, REG_SP, src->prev->regoff * 4 + 4, REG_ITMP1);
177                                 i386_alu_membase_reg(cd, alu_op, REG_SP, src->regoff * 4 + 4, REG_ITMP1);
178                                 i386_mov_reg_membase(cd, REG_ITMP1, REG_SP, iptr->dst->regoff * 4 + 4);
179                         }
180                 }
181         }
182 }
183
184
185 void i386_emit_laluconst(codegendata *cd, s4 alu_op, stackptr src, instruction *iptr)
186 {
187         if (iptr->dst->flags & INMEMORY) {
188                 if (src->flags & INMEMORY) {
189                         if (src->regoff == iptr->dst->regoff) {
190                                 i386_alu_imm_membase(cd, alu_op, iptr->val.l, REG_SP, iptr->dst->regoff * 4);
191                                 i386_alu_imm_membase(cd, alu_op, iptr->val.l >> 32, REG_SP, iptr->dst->regoff * 4 + 4);
192
193                         } else {
194                                 i386_mov_membase_reg(cd, REG_SP, src->regoff * 4, REG_ITMP1);
195                                 i386_alu_imm_reg(cd, alu_op, iptr->val.l, REG_ITMP1);
196                                 i386_mov_reg_membase(cd, REG_ITMP1, REG_SP, iptr->dst->regoff * 4);
197                                 i386_mov_membase_reg(cd, REG_SP, src->regoff * 4 + 4, REG_ITMP1);
198                                 i386_alu_imm_reg(cd, alu_op, iptr->val.l >> 32, REG_ITMP1);
199                                 i386_mov_reg_membase(cd, REG_ITMP1, REG_SP, iptr->dst->regoff * 4 + 4);
200                         }
201                 }
202         }
203 }
204
205
206 void i386_emit_ishift(codegendata *cd, s4 shift_op, stackptr src, instruction *iptr)
207 {
208         if (iptr->dst->flags & INMEMORY) {
209                 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
210                         if (src->prev->regoff == iptr->dst->regoff) {
211                                 i386_mov_membase_reg(cd, REG_SP, src->regoff * 4, ECX);
212                                 i386_shift_membase(cd, shift_op, REG_SP, iptr->dst->regoff * 4);
213
214                         } else {
215                                 i386_mov_membase_reg(cd, REG_SP, src->regoff * 4, ECX);
216                                 i386_mov_membase_reg(cd, REG_SP, src->prev->regoff * 4, REG_ITMP1);
217                                 i386_shift_reg(cd, shift_op, REG_ITMP1);
218                                 i386_mov_reg_membase(cd, REG_ITMP1, REG_SP, iptr->dst->regoff * 4);
219                         }
220
221                 } else if ((src->flags & INMEMORY) && !(src->prev->flags & INMEMORY)) {
222                         i386_mov_membase_reg(cd, REG_SP, src->regoff * 4, ECX);
223                         i386_mov_reg_membase(cd, src->prev->regoff, REG_SP, iptr->dst->regoff * 4);
224                         i386_shift_membase(cd, shift_op, REG_SP, iptr->dst->regoff * 4);
225
226                 } else if (!(src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
227                         if (src->prev->regoff == iptr->dst->regoff) {
228                                 if (src->regoff != ECX)
229                                         i386_mov_reg_reg(cd, src->regoff, ECX);
230
231                                 i386_shift_membase(cd, shift_op, REG_SP, iptr->dst->regoff * 4);
232
233                         } else {        
234                                 if (src->regoff != ECX)
235                                         i386_mov_reg_reg(cd, src->regoff, ECX);
236
237                                 i386_mov_membase_reg(cd, REG_SP, src->prev->regoff * 4, REG_ITMP1);
238                                 i386_shift_reg(cd, shift_op, REG_ITMP1);
239                                 i386_mov_reg_membase(cd, REG_ITMP1, REG_SP, iptr->dst->regoff * 4);
240                         }
241
242                 } else {
243                         if (src->regoff != ECX)
244                                 i386_mov_reg_reg(cd, src->regoff, ECX);
245
246                         i386_mov_reg_membase(cd, src->prev->regoff, REG_SP, iptr->dst->regoff * 4);
247                         i386_shift_membase(cd, shift_op, REG_SP, iptr->dst->regoff * 4);
248                 }
249
250         } else {
251                 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
252                         i386_mov_membase_reg(cd, REG_SP, src->regoff * 4, ECX);
253                         i386_mov_membase_reg(cd, REG_SP, src->prev->regoff * 4, iptr->dst->regoff);
254                         i386_shift_reg(cd, shift_op, iptr->dst->regoff);
255
256                 } else if ((src->flags & INMEMORY) && !(src->prev->flags & INMEMORY)) {
257                         i386_mov_membase_reg(cd, REG_SP, src->regoff * 4, ECX);
258
259                         if (src->prev->regoff != iptr->dst->regoff)
260                                 i386_mov_reg_reg(cd, src->prev->regoff, iptr->dst->regoff);
261
262                         i386_shift_reg(cd, shift_op, iptr->dst->regoff);
263
264                 } else if (!(src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
265                         if (src->regoff != ECX)
266                                 i386_mov_reg_reg(cd, src->regoff, ECX);
267
268                         i386_mov_membase_reg(cd, REG_SP, src->prev->regoff * 4, iptr->dst->regoff);
269                         i386_shift_reg(cd, shift_op, iptr->dst->regoff);
270
271                 } else {
272                         if (src->regoff != ECX)
273                                 i386_mov_reg_reg(cd, src->regoff, ECX);
274
275                         if (src->prev->regoff != iptr->dst->regoff)
276                                 i386_mov_reg_reg(cd, src->prev->regoff, iptr->dst->regoff);
277
278                         i386_shift_reg(cd, shift_op, iptr->dst->regoff);
279                 }
280         }
281 }
282
283
284 void i386_emit_ishiftconst(codegendata *cd, s4 shift_op, stackptr src, instruction *iptr)
285 {
286         if ((src->flags & INMEMORY) && (iptr->dst->flags & INMEMORY)) {
287                 if (src->regoff == iptr->dst->regoff) {
288                         i386_shift_imm_membase(cd, shift_op, iptr->val.i, REG_SP, iptr->dst->regoff * 4);
289
290                 } else {
291                         i386_mov_membase_reg(cd, REG_SP, src->regoff * 4, REG_ITMP1);
292                         i386_shift_imm_reg(cd, shift_op, iptr->val.i, REG_ITMP1);
293                         i386_mov_reg_membase(cd, REG_ITMP1, REG_SP, iptr->dst->regoff * 4);
294                 }
295
296         } else if ((src->flags & INMEMORY) && !(iptr->dst->flags & INMEMORY)) {
297                 i386_mov_membase_reg(cd, REG_SP, src->regoff * 4, iptr->dst->regoff);
298                 i386_shift_imm_reg(cd, shift_op, iptr->val.i, iptr->dst->regoff);
299                                 
300         } else if (!(src->flags & INMEMORY) && (iptr->dst->flags & INMEMORY)) {
301                 i386_mov_reg_membase(cd, src->regoff, REG_SP, iptr->dst->regoff * 4);
302                 i386_shift_imm_membase(cd, shift_op, iptr->val.i, REG_SP, iptr->dst->regoff * 4);
303
304         } else {
305                 if (src->regoff != iptr->dst->regoff)
306                         i386_mov_reg_reg(cd, src->regoff, iptr->dst->regoff);
307
308                 i386_shift_imm_reg(cd, shift_op, iptr->val.i, iptr->dst->regoff);
309         }
310 }
311
312
313 void i386_emit_ifcc_iconst(codegendata *cd, s4 if_op, stackptr src, instruction *iptr)
314 {
315         if (iptr->dst->flags & INMEMORY) {
316                 s4 offset = 0;
317
318                 if (src->flags & INMEMORY) {
319                         i386_alu_imm_membase(cd, I386_CMP, 0, REG_SP, src->regoff * 4);
320
321                 } else {
322                         i386_test_reg_reg(cd, src->regoff, src->regoff);
323                 }
324
325                 offset += 7;
326                 CALCOFFSETBYTES(offset, REG_SP, iptr->dst->regoff * 4);
327         
328                 i386_jcc(cd, if_op, offset + (iptr[1].opc == ICMD_ELSE_ICONST) ? 5 + offset : 0);
329                 i386_mov_imm_membase(cd, iptr->val.i, REG_SP, iptr->dst->regoff * 4);
330
331                 if (iptr[1].opc == ICMD_ELSE_ICONST) {
332                         i386_jmp_imm(cd, offset);
333                         i386_mov_imm_membase(cd, iptr[1].val.i, REG_SP, iptr->dst->regoff * 4);
334                 }
335
336         } else {
337                 if (src->flags & INMEMORY) {
338                         i386_alu_imm_membase(cd, I386_CMP, 0, REG_SP, src->regoff * 4);
339
340                 } else {
341                         i386_test_reg_reg(cd, src->regoff, src->regoff);
342                 }
343
344                 i386_jcc(cd, if_op, (iptr[1].opc == ICMD_ELSE_ICONST) ? 10 : 5);
345                 i386_mov_imm_reg(cd, iptr->val.i, iptr->dst->regoff);
346
347                 if (iptr[1].opc == ICMD_ELSE_ICONST) {
348                         i386_jmp_imm(cd, 5);
349                         i386_mov_imm_reg(cd, iptr[1].val.i, iptr->dst->regoff);
350                 }
351         }
352 }
353
354
355
356 /*
357  * mov ops
358  */
359 void i386_mov_reg_reg(codegendata *cd, s4 reg, s4 dreg)
360 {
361         COUNT(count_mov_reg_reg);
362         *(cd->mcodeptr++) = 0x89;
363         i386_emit_reg((reg),(dreg));
364 }
365
366
367 void i386_mov_imm_reg(codegendata *cd, s4 imm, s4 reg)
368 {
369         *(cd->mcodeptr++) = 0xb8 + ((reg) & 0x07);
370         i386_emit_imm32((imm));
371 }
372
373
374 void i386_movb_imm_reg(codegendata *cd, s4 imm, s4 reg)
375 {
376         *(cd->mcodeptr++) = 0xc6;
377         i386_emit_reg(0,(reg));
378         i386_emit_imm8((imm));
379 }
380
381
382 void i386_mov_membase_reg(codegendata *cd, s4 basereg, s4 disp, s4 reg)
383 {
384         COUNT(count_mov_mem_reg);
385         *(cd->mcodeptr++) = 0x8b;
386         i386_emit_membase((basereg),(disp),(reg));
387 }
388
389
390 /*
391  * this one is for INVOKEVIRTUAL/INVOKEINTERFACE to have a
392  * constant membase immediate length of 32bit
393  */
394 void i386_mov_membase32_reg(codegendata *cd, s4 basereg, s4 disp, s4 reg)
395 {
396         COUNT(count_mov_mem_reg);
397         *(cd->mcodeptr++) = 0x8b;
398         i386_emit_membase32((basereg),(disp),(reg));
399 }
400
401
402 void i386_mov_reg_membase(codegendata *cd, s4 reg, s4 basereg, s4 disp)
403 {
404         COUNT(count_mov_reg_mem);
405         *(cd->mcodeptr++) = 0x89;
406         i386_emit_membase((basereg),(disp),(reg));
407 }
408
409
410 void i386_mov_reg_membase32(codegendata *cd, s4 reg, s4 basereg, s4 disp)
411 {
412         COUNT(count_mov_reg_mem);
413         *(cd->mcodeptr++) = 0x89;
414         i386_emit_membase32((basereg),(disp),(reg));
415 }
416
417
418 void i386_mov_memindex_reg(codegendata *cd, s4 disp, s4 basereg, s4 indexreg, s4 scale, s4 reg)
419 {
420         COUNT(count_mov_mem_reg);
421         *(cd->mcodeptr++) = 0x8b;
422         i386_emit_memindex((reg),(disp),(basereg),(indexreg),(scale));
423 }
424
425
426 void i386_mov_reg_memindex(codegendata *cd, s4 reg, s4 disp, s4 basereg, s4 indexreg, s4 scale)
427 {
428         COUNT(count_mov_reg_mem);
429         *(cd->mcodeptr++) = 0x89;
430         i386_emit_memindex((reg),(disp),(basereg),(indexreg),(scale));
431 }
432
433
434 void i386_movw_reg_memindex(codegendata *cd, s4 reg, s4 disp, s4 basereg, s4 indexreg, s4 scale)
435 {
436         COUNT(count_mov_reg_mem);
437         *(cd->mcodeptr++) = 0x66;
438         *(cd->mcodeptr++) = 0x89;
439         i386_emit_memindex((reg),(disp),(basereg),(indexreg),(scale));
440 }
441
442
443 void i386_movb_reg_memindex(codegendata *cd, s4 reg, s4 disp, s4 basereg, s4 indexreg, s4 scale)
444 {
445         COUNT(count_mov_reg_mem);
446         *(cd->mcodeptr++) = 0x88;
447         i386_emit_memindex((reg),(disp),(basereg),(indexreg),(scale));
448 }
449
450
451 void i386_mov_reg_mem(codegendata *cd, s4 reg, s4 mem)
452 {
453         COUNT(count_mov_reg_mem);
454         *(cd->mcodeptr++) = 0x89;
455         i386_emit_mem((reg),(mem));
456 }
457
458
459 void i386_mov_mem_reg(codegendata *cd, s4 mem, s4 dreg)
460 {
461         COUNT(count_mov_mem_reg);
462         *(cd->mcodeptr++) = 0x8b;
463         i386_emit_mem((dreg),(mem));
464 }
465
466
467 void i386_mov_imm_mem(codegendata *cd, s4 imm, s4 mem)
468 {
469         *(cd->mcodeptr++) = 0xc7;
470         i386_emit_mem(0, mem);
471         i386_emit_imm32(imm);
472 }
473
474
475 void i386_mov_imm_membase(codegendata *cd, s4 imm, s4 basereg, s4 disp)
476 {
477         *(cd->mcodeptr++) = 0xc7;
478         i386_emit_membase((basereg),(disp),0);
479         i386_emit_imm32((imm));
480 }
481
482
483 void i386_mov_imm_membase32(codegendata *cd, s4 imm, s4 basereg, s4 disp)
484 {
485         *(cd->mcodeptr++) = 0xc7;
486         i386_emit_membase32((basereg),(disp),0);
487         i386_emit_imm32((imm));
488 }
489
490
491 void i386_movb_imm_membase(codegendata *cd, s4 imm, s4 basereg, s4 disp)
492 {
493         *(cd->mcodeptr++) = 0xc6;
494         i386_emit_membase((basereg),(disp),0);
495         i386_emit_imm8((imm));
496 }
497
498
499 void i386_movsbl_memindex_reg(codegendata *cd, s4 disp, s4 basereg, s4 indexreg, s4 scale, s4 reg)
500 {
501         COUNT(count_mov_mem_reg);
502         *(cd->mcodeptr++) = 0x0f;
503         *(cd->mcodeptr++) = 0xbe;
504         i386_emit_memindex((reg),(disp),(basereg),(indexreg),(scale));
505 }
506
507
508 void i386_movswl_memindex_reg(codegendata *cd, s4 disp, s4 basereg, s4 indexreg, s4 scale, s4 reg)
509 {
510         COUNT(count_mov_mem_reg);
511         *(cd->mcodeptr++) = 0x0f;
512         *(cd->mcodeptr++) = 0xbf;
513         i386_emit_memindex((reg),(disp),(basereg),(indexreg),(scale));
514 }
515
516
517 void i386_movzwl_memindex_reg(codegendata *cd, s4 disp, s4 basereg, s4 indexreg, s4 scale, s4 reg)
518 {
519         COUNT(count_mov_mem_reg);
520         *(cd->mcodeptr++) = 0x0f;
521         *(cd->mcodeptr++) = 0xb7;
522         i386_emit_memindex((reg),(disp),(basereg),(indexreg),(scale));
523 }
524
525
526 void i386_mov_imm_memindex(codegendata *cd, s4 imm, s4 disp, s4 basereg, s4 indexreg, s4 scale)
527 {
528         *(cd->mcodeptr++) = 0xc7;
529         i386_emit_memindex(0,(disp),(basereg),(indexreg),(scale));
530         i386_emit_imm32((imm));
531 }
532
533
534 void i386_movw_imm_memindex(codegendata *cd, s4 imm, s4 disp, s4 basereg, s4 indexreg, s4 scale)
535 {
536         *(cd->mcodeptr++) = 0x66;
537         *(cd->mcodeptr++) = 0xc7;
538         i386_emit_memindex(0,(disp),(basereg),(indexreg),(scale));
539         i386_emit_imm16((imm));
540 }
541
542
543 void i386_movb_imm_memindex(codegendata *cd, s4 imm, s4 disp, s4 basereg, s4 indexreg, s4 scale)
544 {
545         *(cd->mcodeptr++) = 0xc6;
546         i386_emit_memindex(0,(disp),(basereg),(indexreg),(scale));
547         i386_emit_imm8((imm));
548 }
549
550
551 /*
552  * alu operations
553  */
554 void i386_alu_reg_reg(codegendata *cd, s4 opc, s4 reg, s4 dreg)
555 {
556         *(cd->mcodeptr++) = (((u1) (opc)) << 3) + 1;
557         i386_emit_reg((reg),(dreg));
558 }
559
560
561 void i386_alu_reg_membase(codegendata *cd, s4 opc, s4 reg, s4 basereg, s4 disp)
562 {
563         *(cd->mcodeptr++) = (((u1) (opc)) << 3) + 1;
564         i386_emit_membase((basereg),(disp),(reg));
565 }
566
567
568 void i386_alu_membase_reg(codegendata *cd, s4 opc, s4 basereg, s4 disp, s4 reg)
569 {
570         *(cd->mcodeptr++) = (((u1) (opc)) << 3) + 3;
571         i386_emit_membase((basereg),(disp),(reg));
572 }
573
574
575 void i386_alu_imm_reg(codegendata *cd, s4 opc, s4 imm, s4 dreg)
576 {
577         if (i386_is_imm8(imm)) { 
578                 *(cd->mcodeptr++) = 0x83;
579                 i386_emit_reg((opc),(dreg));
580                 i386_emit_imm8((imm));
581         } else { 
582                 *(cd->mcodeptr++) = 0x81;
583                 i386_emit_reg((opc),(dreg));
584                 i386_emit_imm32((imm));
585         } 
586 }
587
588
589 void i386_alu_imm32_reg(codegendata *cd, s4 opc, s4 imm, s4 dreg)
590 {
591         *(cd->mcodeptr++) = 0x81;
592         i386_emit_reg((opc),(dreg));
593         i386_emit_imm32((imm));
594 }
595
596
597 void i386_alu_imm_membase(codegendata *cd, s4 opc, s4 imm, s4 basereg, s4 disp)
598 {
599         if (i386_is_imm8(imm)) { 
600                 *(cd->mcodeptr++) = 0x83;
601                 i386_emit_membase((basereg),(disp),(opc));
602                 i386_emit_imm8((imm));
603         } else { 
604                 *(cd->mcodeptr++) = 0x81;
605                 i386_emit_membase((basereg),(disp),(opc));
606                 i386_emit_imm32((imm));
607         } 
608 }
609
610
611 void i386_test_reg_reg(codegendata *cd, s4 reg, s4 dreg)
612 {
613         *(cd->mcodeptr++) = 0x85;
614         i386_emit_reg((reg),(dreg));
615 }
616
617
618 void i386_test_imm_reg(codegendata *cd, s4 imm, s4 reg)
619 {
620         *(cd->mcodeptr++) = 0xf7;
621         i386_emit_reg(0,(reg));
622         i386_emit_imm32((imm));
623 }
624
625
626
627 /*
628  * inc, dec operations
629  */
630 void i386_dec_mem(codegendata *cd, s4 mem)
631 {
632         *(cd->mcodeptr++) = 0xff;
633         i386_emit_mem(1,(mem));
634 }
635
636
637 void i386_cltd(codegendata *cd)
638 {
639         *(cd->mcodeptr++) = 0x99;
640 }
641
642
643 void i386_imul_reg_reg(codegendata *cd, s4 reg, s4 dreg)
644 {
645         *(cd->mcodeptr++) = 0x0f;
646         *(cd->mcodeptr++) = 0xaf;
647         i386_emit_reg((dreg),(reg));
648 }
649
650
651 void i386_imul_membase_reg(codegendata *cd, s4 basereg, s4 disp, s4 dreg)
652 {
653         *(cd->mcodeptr++) = 0x0f;
654         *(cd->mcodeptr++) = 0xaf;
655         i386_emit_membase((basereg),(disp),(dreg));
656 }
657
658
659 void i386_imul_imm_reg(codegendata *cd, s4 imm, s4 dreg)
660 {
661         if (i386_is_imm8((imm))) { 
662                 *(cd->mcodeptr++) = 0x6b;
663                 i386_emit_reg(0,(dreg));
664                 i386_emit_imm8((imm));
665         } else { 
666                 *(cd->mcodeptr++) = 0x69;
667                 i386_emit_reg(0,(dreg));
668                 i386_emit_imm32((imm));
669         } 
670 }
671
672
673 void i386_imul_imm_reg_reg(codegendata *cd, s4 imm, s4 reg, s4 dreg)
674 {
675         if (i386_is_imm8((imm))) { 
676                 *(cd->mcodeptr++) = 0x6b;
677                 i386_emit_reg((dreg),(reg));
678                 i386_emit_imm8((imm));
679         } else { 
680                 *(cd->mcodeptr++) = 0x69;
681                 i386_emit_reg((dreg),(reg));
682                 i386_emit_imm32((imm));
683         } 
684 }
685
686
687 void i386_imul_imm_membase_reg(codegendata *cd, s4 imm, s4 basereg, s4 disp, s4 dreg)
688 {
689         if (i386_is_imm8((imm))) {
690                 *(cd->mcodeptr++) = 0x6b;
691                 i386_emit_membase((basereg),(disp),(dreg));
692                 i386_emit_imm8((imm));
693         } else {
694                 *(cd->mcodeptr++) = 0x69;
695                 i386_emit_membase((basereg),(disp),(dreg));
696                 i386_emit_imm32((imm));
697         }
698 }
699
700
701 void i386_mul_membase(codegendata *cd, s4 basereg, s4 disp)
702 {
703         *(cd->mcodeptr++) = 0xf7;
704         i386_emit_membase((basereg),(disp),4);
705 }
706
707
708 void i386_idiv_reg(codegendata *cd, s4 reg)
709 {
710         *(cd->mcodeptr++) = 0xf7;
711         i386_emit_reg(7,(reg));
712 }
713
714
715 void i386_ret(codegendata *cd)
716 {
717         *(cd->mcodeptr++) = 0xc3;
718 }
719
720
721
722 /*
723  * shift ops
724  */
725 void i386_shift_reg(codegendata *cd, s4 opc, s4 reg)
726 {
727         *(cd->mcodeptr++) = 0xd3;
728         i386_emit_reg((opc),(reg));
729 }
730
731
732 void i386_shift_membase(codegendata *cd, s4 opc, s4 basereg, s4 disp)
733 {
734         *(cd->mcodeptr++) = 0xd3;
735         i386_emit_membase((basereg),(disp),(opc));
736 }
737
738
739 void i386_shift_imm_reg(codegendata *cd, s4 opc, s4 imm, s4 dreg)
740 {
741         if ((imm) == 1) {
742                 *(cd->mcodeptr++) = 0xd1;
743                 i386_emit_reg((opc),(dreg));
744         } else {
745                 *(cd->mcodeptr++) = 0xc1;
746                 i386_emit_reg((opc),(dreg));
747                 i386_emit_imm8((imm));
748         }
749 }
750
751
752 void i386_shift_imm_membase(codegendata *cd, s4 opc, s4 imm, s4 basereg, s4 disp)
753 {
754         if ((imm) == 1) {
755                 *(cd->mcodeptr++) = 0xd1;
756                 i386_emit_membase((basereg),(disp),(opc));
757         } else {
758                 *(cd->mcodeptr++) = 0xc1;
759                 i386_emit_membase((basereg),(disp),(opc));
760                 i386_emit_imm8((imm));
761         }
762 }
763
764
765 void i386_shld_reg_reg(codegendata *cd, s4 reg, s4 dreg)
766 {
767         *(cd->mcodeptr++) = 0x0f;
768         *(cd->mcodeptr++) = 0xa5;
769         i386_emit_reg((reg),(dreg));
770 }
771
772
773 void i386_shld_imm_reg_reg(codegendata *cd, s4 imm, s4 reg, s4 dreg)
774 {
775         *(cd->mcodeptr++) = 0x0f;
776         *(cd->mcodeptr++) = 0xa4;
777         i386_emit_reg((reg),(dreg));
778         i386_emit_imm8((imm));
779 }
780
781
782 void i386_shld_reg_membase(codegendata *cd, s4 reg, s4 basereg, s4 disp)
783 {
784         *(cd->mcodeptr++) = 0x0f;
785         *(cd->mcodeptr++) = 0xa5;
786         i386_emit_membase((basereg),(disp),(reg));
787 }
788
789
790 void i386_shrd_reg_reg(codegendata *cd, s4 reg, s4 dreg)
791 {
792         *(cd->mcodeptr++) = 0x0f;
793         *(cd->mcodeptr++) = 0xad;
794         i386_emit_reg((reg),(dreg));
795 }
796
797
798 void i386_shrd_imm_reg_reg(codegendata *cd, s4 imm, s4 reg, s4 dreg)
799 {
800         *(cd->mcodeptr++) = 0x0f;
801         *(cd->mcodeptr++) = 0xac;
802         i386_emit_reg((reg),(dreg));
803         i386_emit_imm8((imm));
804 }
805
806
807 void i386_shrd_reg_membase(codegendata *cd, s4 reg, s4 basereg, s4 disp)
808 {
809         *(cd->mcodeptr++) = 0x0f;
810         *(cd->mcodeptr++) = 0xad;
811         i386_emit_membase((basereg),(disp),(reg));
812 }
813
814
815
816 /*
817  * jump operations
818  */
819 void i386_jmp_imm(codegendata *cd, s4 imm)
820 {
821         *(cd->mcodeptr++) = 0xe9;
822         i386_emit_imm32((imm));
823 }
824
825
826 void i386_jmp_reg(codegendata *cd, s4 reg)
827 {
828         *(cd->mcodeptr++) = 0xff;
829         i386_emit_reg(4,(reg));
830 }
831
832
833 void i386_jcc(codegendata *cd, s4 opc, s4 imm)
834 {
835         *(cd->mcodeptr++) = 0x0f;
836         *(cd->mcodeptr++) =  0x80 + (u1) (opc);
837         i386_emit_imm32((imm));
838 }
839
840
841
842 /*
843  * conditional set operations
844  */
845 void i386_setcc_reg(codegendata *cd, s4 opc, s4 reg)
846 {
847         *(cd->mcodeptr++) = 0x0f;
848         *(cd->mcodeptr++) = 0x90 + (u1) (opc);
849         i386_emit_reg(0,(reg));
850 }
851
852
853 void i386_setcc_membase(codegendata *cd, s4 opc, s4 basereg, s4 disp)
854 {
855         *(cd->mcodeptr++) = 0x0f;
856         *(cd->mcodeptr++) =  0x90 + (u1) (opc);
857         i386_emit_membase((basereg),(disp),0);
858 }
859
860
861 void i386_xadd_reg_mem(codegendata *cd, s4 reg, s4 mem)
862 {
863         *(cd->mcodeptr++) = 0x0f;
864         *(cd->mcodeptr++) = 0xc1;
865         i386_emit_mem((reg),(mem));
866 }
867
868
869 void i386_neg_reg(codegendata *cd, s4 reg)
870 {
871         *(cd->mcodeptr++) = 0xf7;
872         i386_emit_reg(3,(reg));
873 }
874
875
876 void i386_neg_membase(codegendata *cd, s4 basereg, s4 disp)
877 {
878         *(cd->mcodeptr++) = 0xf7;
879         i386_emit_membase((basereg),(disp),3);
880 }
881
882
883
884 void i386_push_imm(codegendata *cd, s4 imm)
885 {
886         *(cd->mcodeptr++) = 0x68;
887         i386_emit_imm32((imm));
888 }
889
890
891 void i386_pop_reg(codegendata *cd, s4 reg)
892 {
893         *(cd->mcodeptr++) = 0x58 + (0x07 & (u1) (reg));
894 }
895
896
897 void i386_push_reg(codegendata *cd, s4 reg)
898 {
899         *(cd->mcodeptr++) = 0x50 + (0x07 & (u1) (reg));
900 }
901
902
903 void i386_nop(codegendata *cd)
904 {
905         *(cd->mcodeptr++) = 0x90;
906 }
907
908
909 void i386_lock(codegendata *cd)
910 {
911         *(cd->mcodeptr++) = 0xf0;
912 }
913
914
915 /*
916  * call instructions
917  */
918 void i386_call_reg(codegendata *cd, s4 reg)
919 {
920         *(cd->mcodeptr++) = 0xff;
921         i386_emit_reg(2,(reg));
922 }
923
924
925 void i386_call_imm(codegendata *cd, s4 imm)
926 {
927         *(cd->mcodeptr++) = 0xe8;
928         i386_emit_imm32((imm));
929 }
930
931
932 void i386_call_mem(codegendata *cd, s4 mem)
933 {
934         *(cd->mcodeptr++) = 0xff;
935         i386_emit_mem(2,(mem));
936 }
937
938
939
940 /*
941  * floating point instructions
942  */
943 void i386_fld1(codegendata *cd)
944 {
945         *(cd->mcodeptr++) = 0xd9;
946         *(cd->mcodeptr++) = 0xe8;
947 }
948
949
950 void i386_fldz(codegendata *cd)
951 {
952         *(cd->mcodeptr++) = 0xd9;
953         *(cd->mcodeptr++) = 0xee;
954 }
955
956
957 void i386_fld_reg(codegendata *cd, s4 reg)
958 {
959         *(cd->mcodeptr++) = 0xd9;
960         *(cd->mcodeptr++) = 0xc0 + (0x07 & (u1) (reg));
961 }
962
963
964 void i386_flds_membase(codegendata *cd, s4 basereg, s4 disp)
965 {
966         *(cd->mcodeptr++) = 0xd9;
967         i386_emit_membase((basereg),(disp),0);
968 }
969
970
971 void i386_flds_membase32(codegendata *cd, s4 basereg, s4 disp)
972 {
973         *(cd->mcodeptr++) = 0xd9;
974         i386_emit_membase32((basereg),(disp),0);
975 }
976
977
978 void i386_fldl_membase(codegendata *cd, s4 basereg, s4 disp)
979 {
980         *(cd->mcodeptr++) = 0xdd;
981         i386_emit_membase((basereg),(disp),0);
982 }
983
984
985 void i386_fldl_membase32(codegendata *cd, s4 basereg, s4 disp)
986 {
987         *(cd->mcodeptr++) = 0xdd;
988         i386_emit_membase32((basereg),(disp),0);
989 }
990
991
992 void i386_fldt_membase(codegendata *cd, s4 basereg, s4 disp)
993 {
994         *(cd->mcodeptr++) = 0xdb;
995         i386_emit_membase((basereg),(disp),5);
996 }
997
998
999 void i386_flds_memindex(codegendata *cd, s4 disp, s4 basereg, s4 indexreg, s4 scale)
1000 {
1001         *(cd->mcodeptr++) = 0xd9;
1002         i386_emit_memindex(0,(disp),(basereg),(indexreg),(scale));
1003 }
1004
1005
1006 void i386_fldl_memindex(codegendata *cd, s4 disp, s4 basereg, s4 indexreg, s4 scale)
1007 {
1008         *(cd->mcodeptr++) = 0xdd;
1009         i386_emit_memindex(0,(disp),(basereg),(indexreg),(scale));
1010 }
1011
1012
1013 void i386_flds_mem(codegendata *cd, s4 mem)
1014 {
1015         *(cd->mcodeptr++) = 0xd9;
1016         i386_emit_mem(0,(mem));
1017 }
1018
1019
1020 void i386_fldl_mem(codegendata *cd, s4 mem)
1021 {
1022         *(cd->mcodeptr++) = 0xdd;
1023         i386_emit_mem(0,(mem));
1024 }
1025
1026
1027 void i386_fildl_membase(codegendata *cd, s4 basereg, s4 disp)
1028 {
1029         *(cd->mcodeptr++) = 0xdb;
1030         i386_emit_membase((basereg),(disp),0);
1031 }
1032
1033
1034 void i386_fildll_membase(codegendata *cd, s4 basereg, s4 disp)
1035 {
1036         *(cd->mcodeptr++) = 0xdf;
1037         i386_emit_membase((basereg),(disp),5);
1038 }
1039
1040
1041 void i386_fst_reg(codegendata *cd, s4 reg)
1042 {
1043         *(cd->mcodeptr++) = 0xdd;
1044         *(cd->mcodeptr++) = 0xd0 + (0x07 & (u1) (reg));
1045 }
1046
1047
1048 void i386_fsts_membase(codegendata *cd, s4 basereg, s4 disp)
1049 {
1050         *(cd->mcodeptr++) = 0xd9;
1051         i386_emit_membase((basereg),(disp),2);
1052 }
1053
1054
1055 void i386_fstl_membase(codegendata *cd, s4 basereg, s4 disp)
1056 {
1057         *(cd->mcodeptr++) = 0xdd;
1058         i386_emit_membase((basereg),(disp),2);
1059 }
1060
1061
1062 void i386_fsts_memindex(codegendata *cd, s4 disp, s4 basereg, s4 indexreg, s4 scale)
1063 {
1064         *(cd->mcodeptr++) = 0xd9;
1065         i386_emit_memindex(2,(disp),(basereg),(indexreg),(scale));
1066 }
1067
1068
1069 void i386_fstl_memindex(codegendata *cd, s4 disp, s4 basereg, s4 indexreg, s4 scale)
1070 {
1071         *(cd->mcodeptr++) = 0xdd;
1072         i386_emit_memindex(2,(disp),(basereg),(indexreg),(scale));
1073 }
1074
1075
1076 void i386_fstp_reg(codegendata *cd, s4 reg)
1077 {
1078         *(cd->mcodeptr++) = 0xdd;
1079         *(cd->mcodeptr++) = 0xd8 + (0x07 & (u1) (reg));
1080 }
1081
1082
1083 void i386_fstps_membase(codegendata *cd, s4 basereg, s4 disp)
1084 {
1085         *(cd->mcodeptr++) = 0xd9;
1086         i386_emit_membase((basereg),(disp),3);
1087 }
1088
1089
1090 void i386_fstps_membase32(codegendata *cd, s4 basereg, s4 disp)
1091 {
1092         *(cd->mcodeptr++) = 0xd9;
1093         i386_emit_membase32((basereg),(disp),3);
1094 }
1095
1096
1097 void i386_fstpl_membase(codegendata *cd, s4 basereg, s4 disp)
1098 {
1099         *(cd->mcodeptr++) = 0xdd;
1100         i386_emit_membase((basereg),(disp),3);
1101 }
1102
1103
1104 void i386_fstpl_membase32(codegendata *cd, s4 basereg, s4 disp)
1105 {
1106         *(cd->mcodeptr++) = 0xdd;
1107         i386_emit_membase32((basereg),(disp),3);
1108 }
1109
1110
1111 void i386_fstpt_membase(codegendata *cd, s4 basereg, s4 disp)
1112 {
1113         *(cd->mcodeptr++) = 0xdb;
1114         i386_emit_membase((basereg),(disp),7);
1115 }
1116
1117
1118 void i386_fstps_memindex(codegendata *cd, s4 disp, s4 basereg, s4 indexreg, s4 scale)
1119 {
1120         *(cd->mcodeptr++) = 0xd9;
1121         i386_emit_memindex(3,(disp),(basereg),(indexreg),(scale));
1122 }
1123
1124
1125 void i386_fstpl_memindex(codegendata *cd, s4 disp, s4 basereg, s4 indexreg, s4 scale)
1126 {
1127         *(cd->mcodeptr++) = 0xdd;
1128         i386_emit_memindex(3,(disp),(basereg),(indexreg),(scale));
1129 }
1130
1131
1132 void i386_fstps_mem(codegendata *cd, s4 mem)
1133 {
1134         *(cd->mcodeptr++) = 0xd9;
1135         i386_emit_mem(3,(mem));
1136 }
1137
1138
1139 void i386_fstpl_mem(codegendata *cd, s4 mem)
1140 {
1141         *(cd->mcodeptr++) = 0xdd;
1142         i386_emit_mem(3,(mem));
1143 }
1144
1145
1146 void i386_fistl_membase(codegendata *cd, s4 basereg, s4 disp)
1147 {
1148         *(cd->mcodeptr++) = 0xdb;
1149         i386_emit_membase((basereg),(disp),2);
1150 }
1151
1152
1153 void i386_fistpl_membase(codegendata *cd, s4 basereg, s4 disp)
1154 {
1155         *(cd->mcodeptr++) = 0xdb;
1156         i386_emit_membase((basereg),(disp),3);
1157 }
1158
1159
1160 void i386_fistpll_membase(codegendata *cd, s4 basereg, s4 disp)
1161 {
1162         *(cd->mcodeptr++) = 0xdf;
1163         i386_emit_membase((basereg),(disp),7);
1164 }
1165
1166
1167 void i386_fchs(codegendata *cd)
1168 {
1169         *(cd->mcodeptr++) = 0xd9;
1170         *(cd->mcodeptr++) = 0xe0;
1171 }
1172
1173
1174 void i386_faddp(codegendata *cd)
1175 {
1176         *(cd->mcodeptr++) = 0xde;
1177         *(cd->mcodeptr++) = 0xc1;
1178 }
1179
1180
1181 void i386_fadd_reg_st(codegendata *cd, s4 reg)
1182 {
1183         *(cd->mcodeptr++) = 0xd8;
1184         *(cd->mcodeptr++) = 0xc0 + (0x0f & (u1) (reg));
1185 }
1186
1187
1188 void i386_fadd_st_reg(codegendata *cd, s4 reg)
1189 {
1190         *(cd->mcodeptr++) = 0xdc;
1191         *(cd->mcodeptr++) = 0xc0 + (0x0f & (u1) (reg));
1192 }
1193
1194
1195 void i386_faddp_st_reg(codegendata *cd, s4 reg)
1196 {
1197         *(cd->mcodeptr++) = 0xde;
1198         *(cd->mcodeptr++) = 0xc0 + (0x0f & (u1) (reg));
1199 }
1200
1201
1202 void i386_fadds_membase(codegendata *cd, s4 basereg, s4 disp)
1203 {
1204         *(cd->mcodeptr++) = 0xd8;
1205         i386_emit_membase((basereg),(disp),0);
1206 }
1207
1208
1209 void i386_faddl_membase(codegendata *cd, s4 basereg, s4 disp)
1210 {
1211         *(cd->mcodeptr++) = 0xdc;
1212         i386_emit_membase((basereg),(disp),0);
1213 }
1214
1215
1216 void i386_fsub_reg_st(codegendata *cd, s4 reg)
1217 {
1218         *(cd->mcodeptr++) = 0xd8;
1219         *(cd->mcodeptr++) = 0xe0 + (0x07 & (u1) (reg));
1220 }
1221
1222
1223 void i386_fsub_st_reg(codegendata *cd, s4 reg)
1224 {
1225         *(cd->mcodeptr++) = 0xdc;
1226         *(cd->mcodeptr++) = 0xe8 + (0x07 & (u1) (reg));
1227 }
1228
1229
1230 void i386_fsubp_st_reg(codegendata *cd, s4 reg)
1231 {
1232         *(cd->mcodeptr++) = 0xde;
1233         *(cd->mcodeptr++) = 0xe8 + (0x07 & (u1) (reg));
1234 }
1235
1236
1237 void i386_fsubp(codegendata *cd)
1238 {
1239         *(cd->mcodeptr++) = 0xde;
1240         *(cd->mcodeptr++) = 0xe9;
1241 }
1242
1243
1244 void i386_fsubs_membase(codegendata *cd, s4 basereg, s4 disp)
1245 {
1246         *(cd->mcodeptr++) = 0xd8;
1247         i386_emit_membase((basereg),(disp),4);
1248 }
1249
1250
1251 void i386_fsubl_membase(codegendata *cd, s4 basereg, s4 disp)
1252 {
1253         *(cd->mcodeptr++) = 0xdc;
1254         i386_emit_membase((basereg),(disp),4);
1255 }
1256
1257
1258 void i386_fmul_reg_st(codegendata *cd, s4 reg)
1259 {
1260         *(cd->mcodeptr++) = 0xd8;
1261         *(cd->mcodeptr++) = 0xc8 + (0x07 & (u1) (reg));
1262 }
1263
1264
1265 void i386_fmul_st_reg(codegendata *cd, s4 reg)
1266 {
1267         *(cd->mcodeptr++) = 0xdc;
1268         *(cd->mcodeptr++) = 0xc8 + (0x07 & (u1) (reg));
1269 }
1270
1271
1272 void i386_fmulp(codegendata *cd)
1273 {
1274         *(cd->mcodeptr++) = 0xde;
1275         *(cd->mcodeptr++) = 0xc9;
1276 }
1277
1278
1279 void i386_fmulp_st_reg(codegendata *cd, s4 reg)
1280 {
1281         *(cd->mcodeptr++) = 0xde;
1282         *(cd->mcodeptr++) = 0xc8 + (0x07 & (u1) (reg));
1283 }
1284
1285
1286 void i386_fmuls_membase(codegendata *cd, s4 basereg, s4 disp)
1287 {
1288         *(cd->mcodeptr++) = 0xd8;
1289         i386_emit_membase((basereg),(disp),1);
1290 }
1291
1292
1293 void i386_fmull_membase(codegendata *cd, s4 basereg, s4 disp)
1294 {
1295         *(cd->mcodeptr++) = 0xdc;
1296         i386_emit_membase((basereg),(disp),1);
1297 }
1298
1299
1300 void i386_fdiv_reg_st(codegendata *cd, s4 reg)
1301 {
1302         *(cd->mcodeptr++) = 0xd8;
1303         *(cd->mcodeptr++) = 0xf0 + (0x07 & (u1) (reg));
1304 }
1305
1306
1307 void i386_fdiv_st_reg(codegendata *cd, s4 reg)
1308 {
1309         *(cd->mcodeptr++) = 0xdc;
1310         *(cd->mcodeptr++) = 0xf8 + (0x07 & (u1) (reg));
1311 }
1312
1313
1314 void i386_fdivp(codegendata *cd)
1315 {
1316         *(cd->mcodeptr++) = 0xde;
1317         *(cd->mcodeptr++) = 0xf9;
1318 }
1319
1320
1321 void i386_fdivp_st_reg(codegendata *cd, s4 reg)
1322 {
1323         *(cd->mcodeptr++) = 0xde;
1324         *(cd->mcodeptr++) = 0xf8 + (0x07 & (u1) (reg));
1325 }
1326
1327
1328 void i386_fxch(codegendata *cd)
1329 {
1330         *(cd->mcodeptr++) = 0xd9;
1331         *(cd->mcodeptr++) = 0xc9;
1332 }
1333
1334
1335 void i386_fxch_reg(codegendata *cd, s4 reg)
1336 {
1337         *(cd->mcodeptr++) = 0xd9;
1338         *(cd->mcodeptr++) = 0xc8 + (0x07 & (reg));
1339 }
1340
1341
1342 void i386_fprem(codegendata *cd)
1343 {
1344         *(cd->mcodeptr++) = 0xd9;
1345         *(cd->mcodeptr++) = 0xf8;
1346 }
1347
1348
1349 void i386_fprem1(codegendata *cd)
1350 {
1351         *(cd->mcodeptr++) = 0xd9;
1352         *(cd->mcodeptr++) = 0xf5;
1353 }
1354
1355
1356 void i386_fucom(codegendata *cd)
1357 {
1358         *(cd->mcodeptr++) = 0xdd;
1359         *(cd->mcodeptr++) = 0xe1;
1360 }
1361
1362
1363 void i386_fucom_reg(codegendata *cd, s4 reg)
1364 {
1365         *(cd->mcodeptr++) = 0xdd;
1366         *(cd->mcodeptr++) = 0xe0 + (0x07 & (u1) (reg));
1367 }
1368
1369
1370 void i386_fucomp_reg(codegendata *cd, s4 reg)
1371 {
1372         *(cd->mcodeptr++) = 0xdd;
1373         *(cd->mcodeptr++) = 0xe8 + (0x07 & (u1) (reg));
1374 }
1375
1376
1377 void i386_fucompp(codegendata *cd)
1378 {
1379         *(cd->mcodeptr++) = 0xda;
1380         *(cd->mcodeptr++) = 0xe9;
1381 }
1382
1383
1384 void i386_fnstsw(codegendata *cd)
1385 {
1386         *(cd->mcodeptr++) = 0xdf;
1387         *(cd->mcodeptr++) = 0xe0;
1388 }
1389
1390
1391 void i386_sahf(codegendata *cd)
1392 {
1393         *(cd->mcodeptr++) = 0x9e;
1394 }
1395
1396
1397 void i386_finit(codegendata *cd)
1398 {
1399         *(cd->mcodeptr++) = 0x9b;
1400         *(cd->mcodeptr++) = 0xdb;
1401         *(cd->mcodeptr++) = 0xe3;
1402 }
1403
1404
1405 void i386_fldcw_mem(codegendata *cd, s4 mem)
1406 {
1407         *(cd->mcodeptr++) = 0xd9;
1408         i386_emit_mem(5,(mem));
1409 }
1410
1411
1412 void i386_fldcw_membase(codegendata *cd, s4 basereg, s4 disp)
1413 {
1414         *(cd->mcodeptr++) = 0xd9;
1415         i386_emit_membase((basereg),(disp),5);
1416 }
1417
1418
1419 void i386_wait(codegendata *cd)
1420 {
1421         *(cd->mcodeptr++) = 0x9b;
1422 }
1423
1424
1425 void i386_ffree_reg(codegendata *cd, s4 reg)
1426 {
1427         *(cd->mcodeptr++) = 0xdd;
1428         *(cd->mcodeptr++) = 0xc0 + (0x07 & (u1) (reg));
1429 }
1430
1431
1432 void i386_fdecstp(codegendata *cd)
1433 {
1434         *(cd->mcodeptr++) = 0xd9;
1435         *(cd->mcodeptr++) = 0xf6;
1436 }
1437
1438
1439 void i386_fincstp(codegendata *cd)
1440 {
1441         *(cd->mcodeptr++) = 0xd9;
1442         *(cd->mcodeptr++) = 0xf7;
1443 }
1444
1445
1446 /*
1447  * These are local overrides for various environment variables in Emacs.
1448  * Please do not remove this and leave it at the end of the file, where
1449  * Emacs will automagically detect them.
1450  * ---------------------------------------------------------------------
1451  * Local variables:
1452  * mode: c
1453  * indent-tabs-mode: t
1454  * c-basic-offset: 4
1455  * tab-width: 4
1456  * End:
1457  */