Merged r5531 and r5532, ported to unified_variables:
[cacao.git] / src / vm / jit / i386 / emit.c
1 /* src/vm/jit/i386/emit.c - i386 code emitter functions
2
3    Copyright (C) 1996-2005, 2006 R. Grafl, A. Krall, C. Kruegel,
4    C. Oates, R. Obermaisser, M. Platter, M. Probst, S. Ring,
5    E. Steiner, C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich,
6    J. Wenninger, 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., 51 Franklin Street, Fifth Floor, Boston, MA
23    02110-1301, USA.
24
25    Contact: cacao@cacaojvm.org
26
27    Authors: Christian Thalinger
28
29    Changes:
30
31    $Id: emit.c 5562 2006-09-28 20:13:20Z edwin $
32
33 */
34
35
36 #include "config.h"
37
38 #include <assert.h>
39
40 #include "vm/types.h"
41
42 #include "vm/jit/i386/codegen.h"
43 #include "vm/jit/i386/emit.h"
44 #include "vm/jit/i386/md-abi.h"
45
46 #if defined(ENABLE_THREADS)
47 # include "threads/native/lock.h"
48 #endif
49
50 #include "vm/builtin.h"
51 #include "vm/statistics.h"
52 #include "vm/jit/asmpart.h"
53 #include "vm/jit/dseg.h"
54 #include "vm/jit/emit-common.h"
55 #include "vm/jit/jit.h"
56 #include "vm/jit/replace.h"
57
58
59 /* emit_load ******************************************************************
60
61    Emits a possible load of an operand.
62
63 *******************************************************************************/
64
65 inline s4 emit_load(jitdata *jd, instruction *iptr, varinfo *src, s4 tempreg)
66 {
67         codegendata  *cd;
68         s4            disp;
69         s4            reg;
70
71         /* get required compiler data */
72
73         cd = jd->cd;
74
75         if (IS_INMEMORY(src->flags)) {
76                 COUNT_SPILLS;
77
78                 disp = src->vv.regoff * 4;
79
80                 if (IS_FLT_DBL_TYPE(src->type)) {
81                         if (IS_2_WORD_TYPE(src->type))
82                                 M_DLD(tempreg, REG_SP, disp);
83                         else
84                                 M_FLD(tempreg, REG_SP, disp);
85                 }
86                 else {
87                         if (IS_2_WORD_TYPE(src->type))
88                                 M_LLD(tempreg, REG_SP, disp);
89                         else
90                                 M_ILD(tempreg, REG_SP, disp);
91                 }
92
93                 reg = tempreg;
94         }
95         else
96                 reg = src->vv.regoff;
97
98         return reg;
99 }
100
101
102 /* emit_load_low ************************************************************
103
104    Emits a possible load of the low 32-bits of an operand.
105
106 *******************************************************************************/
107
108 inline s4 emit_load_low(jitdata *jd, instruction *iptr, varinfo *src,s4 tempreg)
109 {
110         codegendata  *cd;
111         s4            disp;
112         s4            reg;
113
114         assert(src->type == TYPE_LNG);
115
116         /* get required compiler data */
117
118         cd = jd->cd;
119
120
121         if (IS_INMEMORY(src->flags)) {
122                 COUNT_SPILLS;
123
124                 disp = src->vv.regoff * 4;
125
126                 M_ILD(tempreg, REG_SP, disp);
127
128                 reg = tempreg;
129         }
130         else
131                 reg = GET_LOW_REG(src->vv.regoff);
132
133         return reg;
134 }
135
136
137 /* emit_load_high ***********************************************************
138
139    Emits a possible load of the high 32-bits of an operand.
140
141 *******************************************************************************/
142
143 inline s4 emit_load_high(jitdata *jd, instruction *iptr,varinfo *src,s4 tempreg)
144 {
145         codegendata  *cd;
146         s4            disp;
147         s4            reg;
148
149         /* get required compiler data */
150
151         assert(src->type == TYPE_LNG);
152
153         cd = jd->cd;
154
155         if (IS_INMEMORY(src->flags)) {
156                 COUNT_SPILLS;
157
158                 disp = src->vv.regoff * 4;
159
160                 M_ILD(tempreg, REG_SP, disp + 4);
161
162                 reg = tempreg;
163         }
164         else
165                 reg = GET_HIGH_REG(src->vv.regoff);
166
167         return reg;
168 }
169
170
171 /* emit_store ******************************************************************
172
173    Emits a possible store of the destination operand.
174
175 *******************************************************************************/
176
177 inline void emit_store(jitdata *jd, instruction *iptr, varinfo *dst, s4 d)
178 {
179         codegendata  *cd;
180
181         /* get required compiler data */
182
183         cd = jd->cd;
184
185         if (IS_INMEMORY(dst->flags)) {
186                 COUNT_SPILLS;
187
188                 if (IS_FLT_DBL_TYPE(dst->type)) {
189                         if (IS_2_WORD_TYPE(dst->type))
190                                 M_DST(d, REG_SP, dst->vv.regoff * 4);
191                         else
192                                 M_FST(d, REG_SP, dst->vv.regoff * 4);
193                 }
194                 else {
195                         if (IS_2_WORD_TYPE(dst->type))
196                                 M_LST(d, REG_SP, dst->vv.regoff * 4);
197                         else
198                                 M_IST(d, REG_SP, dst->vv.regoff * 4);
199                 }
200         }
201 }
202
203
204 /* emit_store_low **************************************************************
205
206    Emits a possible store of the low 32-bits of the destination
207    operand.
208
209 *******************************************************************************/
210
211 inline void emit_store_low(jitdata *jd, instruction *iptr, varinfo *dst, s4 d)
212 {
213         codegendata  *cd;
214
215         assert(dst->type == TYPE_LNG);
216
217         /* get required compiler data */
218
219         cd = jd->cd;
220
221         if (IS_INMEMORY(dst->flags)) {
222                 COUNT_SPILLS;
223                 M_IST(GET_LOW_REG(d), REG_SP, dst->vv.regoff * 4);
224         }
225 }
226
227
228 /* emit_store_high *************************************************************
229
230    Emits a possible store of the high 32-bits of the destination
231    operand.
232
233 *******************************************************************************/
234
235 inline void emit_store_high(jitdata *jd, instruction *iptr, varinfo *dst, s4 d)
236 {
237         codegendata  *cd;
238
239         assert(dst->type == TYPE_LNG);
240
241         /* get required compiler data */
242
243         cd = jd->cd;
244
245         if (IS_INMEMORY(dst->flags)) {
246                 COUNT_SPILLS;
247                 M_IST(GET_HIGH_REG(d), REG_SP, dst->vv.regoff * 4 + 4);
248         }
249 }
250
251
252 /* emit_copy *******************************************************************
253
254    Generates a register/memory to register/memory copy.
255
256 *******************************************************************************/
257
258 void emit_copy(jitdata *jd, instruction *iptr, varinfo *src, varinfo *dst)
259 {
260         codegendata  *cd;
261         s4            s1, d;
262
263         /* get required compiler data */
264
265         cd = jd->cd;
266
267         if ((src->vv.regoff != dst->vv.regoff) ||
268                 ((src->flags ^ dst->flags) & INMEMORY)) {
269
270                 /* If one of the variables resides in memory, we can eliminate
271                    the register move from/to the temporary register with the
272                    order of getting the destination register and the load. */
273
274                 if (IS_INMEMORY(src->flags)) {
275                         if (IS_LNG_TYPE(src->type))
276                                 d = codegen_reg_of_var(iptr->opc, dst, REG_ITMP12_PACKED);
277                         else
278                                 d = codegen_reg_of_var(iptr->opc, dst, REG_ITMP1);
279
280                         s1 = emit_load(jd, iptr, src, d);
281                 }
282                 else {
283                         if (IS_LNG_TYPE(src->type))
284                                 s1 = emit_load(jd, iptr, src, REG_ITMP12_PACKED);
285                         else
286                                 s1 = emit_load(jd, iptr, src, REG_ITMP1);
287
288                         d = codegen_reg_of_var(iptr->opc, dst, s1);
289                 }
290
291                 if (s1 != d) {
292                         if (IS_FLT_DBL_TYPE(src->type)) {
293 /*                              M_FMOV(s1, d); */
294                         } else {
295                                 if (IS_2_WORD_TYPE(src->type))
296                                         M_LNGMOVE(s1, d);
297                                 else
298                     M_MOV(s1, d);
299                         }
300                 }
301
302                 emit_store(jd, iptr, dst, d);
303         }
304 }
305
306
307 /* emit_exception_stubs ********************************************************
308
309    Generates the code for the exception stubs.
310
311 *******************************************************************************/
312
313 void emit_exception_stubs(jitdata *jd)
314 {
315         codegendata  *cd;
316         registerdata *rd;
317         exceptionref *eref;
318         s4            targetdisp;
319
320         /* get required compiler data */
321
322         cd = jd->cd;
323         rd = jd->rd;
324
325         /* generate exception stubs */
326
327         targetdisp = 0;
328
329         for (eref = cd->exceptionrefs; eref != NULL; eref = eref->next) {
330                 gen_resolvebranch(cd->mcodebase + eref->branchpos,
331                                                   eref->branchpos,
332                                                   cd->mcodeptr - cd->mcodebase);
333
334                 MCODECHECK(512);
335
336                 /* Check if the exception is an
337                    ArrayIndexOutOfBoundsException.  If so, move index register
338                    into REG_ITMP1. */
339
340                 if (eref->reg != -1)
341                         M_INTMOVE(eref->reg, REG_ITMP1);
342
343                 /* calcuate exception address */
344
345                 M_MOV_IMM(0, REG_ITMP2_XPC);
346                 dseg_adddata(cd);
347                 M_AADD_IMM32(eref->branchpos - 6, REG_ITMP2_XPC);
348
349                 /* move function to call into REG_ITMP3 */
350
351                 M_MOV_IMM(eref->function, REG_ITMP3);
352
353                 if (targetdisp == 0) {
354                         targetdisp = cd->mcodeptr - cd->mcodebase;
355
356                         M_ASUB_IMM(5 * 4, REG_SP);
357
358                         /* first store REG_ITMP1 so we can use it */
359
360                         M_AST(REG_ITMP1, REG_SP, 4 * 4);                    /* for AIOOBE */
361
362                         M_AST_IMM(0, REG_SP, 0 * 4);
363                         dseg_adddata(cd);
364                         M_MOV(REG_SP, REG_ITMP1);
365                         M_AADD_IMM(5 * 4, REG_ITMP1);
366                         M_AST(REG_ITMP1, REG_SP, 1 * 4);
367                         M_ALD(REG_ITMP1, REG_SP, (5 + cd->stackframesize) * 4);
368                         M_AST(REG_ITMP1, REG_SP, 2 * 4);
369                         M_AST(REG_ITMP2_XPC, REG_SP, 3 * 4);
370
371                         M_CALL(REG_ITMP3);
372
373                         M_ALD(REG_ITMP2_XPC, REG_SP, 3 * 4);
374                         M_AADD_IMM(5 * 4, REG_SP);
375
376                         M_MOV_IMM(asm_handle_exception, REG_ITMP3);
377                         M_JMP(REG_ITMP3);
378                 }
379                 else {
380                         M_JMP_IMM((cd->mcodebase + targetdisp) -
381                                           (cd->mcodeptr + PATCHER_CALL_SIZE));
382                 }
383         }
384 }
385
386
387 /* emit_patcher_stubs **********************************************************
388
389    Generates the code for the patcher stubs.
390
391 *******************************************************************************/
392
393 void emit_patcher_stubs(jitdata *jd)
394 {
395         codegendata *cd;
396         patchref    *pref;
397         u8           mcode;
398         u1          *savedmcodeptr;
399         u1          *tmpmcodeptr;
400         s4           targetdisp;
401         s4           disp;
402
403         /* get required compiler data */
404
405         cd = jd->cd;
406
407         /* generate code patching stub call code */
408
409         targetdisp = 0;
410
411         for (pref = cd->patchrefs; pref != NULL; pref = pref->next) {
412                 /* check code segment size */
413
414                 MCODECHECK(512);
415
416                 /* Get machine code which is patched back in later. A
417                    `call rel32' is 5 bytes long. */
418
419                 savedmcodeptr = cd->mcodebase + pref->branchpos;
420                 mcode = *((u8 *) savedmcodeptr);
421
422                 /* patch in `call rel32' to call the following code */
423
424                 tmpmcodeptr  = cd->mcodeptr;    /* save current mcodeptr              */
425                 cd->mcodeptr = savedmcodeptr;   /* set mcodeptr to patch position     */
426
427                 M_CALL_IMM(tmpmcodeptr - (savedmcodeptr + PATCHER_CALL_SIZE));
428
429                 cd->mcodeptr = tmpmcodeptr;     /* restore the current mcodeptr       */
430
431                 /* save REG_ITMP3 */
432
433                 M_PUSH(REG_ITMP3);
434
435                 /* move pointer to java_objectheader onto stack */
436
437 #if defined(ENABLE_THREADS)
438                 (void) dseg_addaddress(cd, NULL);                          /* flcword */
439                 (void) dseg_addaddress(cd, lock_get_initial_lock_word());
440                 disp = dseg_addaddress(cd, NULL);                          /* vftbl   */
441
442                 M_MOV_IMM(0, REG_ITMP3);
443                 dseg_adddata(cd);
444                 M_AADD_IMM(disp, REG_ITMP3);
445                 M_PUSH(REG_ITMP3);
446 #else
447                 M_PUSH_IMM(0);
448 #endif
449
450                 /* move machine code bytes and classinfo pointer into registers */
451
452                 M_PUSH_IMM(mcode >> 32);
453                 M_PUSH_IMM(mcode);
454                 M_PUSH_IMM(pref->ref);
455                 M_PUSH_IMM(pref->patcher);
456
457                 if (targetdisp == 0) {
458                         targetdisp = cd->mcodeptr - cd->mcodebase;
459
460                         M_MOV_IMM(asm_patcher_wrapper, REG_ITMP3);
461                         M_JMP(REG_ITMP3);
462                 }
463                 else {
464                         M_JMP_IMM((cd->mcodebase + targetdisp) -
465                                           (cd->mcodeptr + PATCHER_CALL_SIZE));
466                 }
467         }
468 }
469
470
471 /* emit_replacement_stubs ******************************************************
472
473    Generates the code for the replacement stubs.
474
475 *******************************************************************************/
476
477 void emit_replacement_stubs(jitdata *jd)
478 {
479         codegendata *cd;
480         codeinfo    *code;
481         rplpoint    *rplp;
482         s4           disp;
483         s4           i;
484
485         /* get required compiler data */
486
487         cd   = jd->cd;
488         code = jd->code;
489
490         rplp = code->rplpoints;
491
492         for (i = 0; i < code->rplpointcount; ++i, ++rplp) {
493                 /* check code segment size */
494
495                 MCODECHECK(512);
496
497                 /* note start of stub code */
498
499                 rplp->outcode = (u1 *) (ptrint) (cd->mcodeptr - cd->mcodebase);
500
501                 /* make machine code for patching */
502
503                 disp = (ptrint) (rplp->outcode - rplp->pc) - 5;
504
505                 rplp->mcode = 0xe9 | ((u8) disp << 8);
506
507                 /* push address of `rplpoint` struct */
508                         
509                 M_PUSH_IMM(rplp);
510
511                 /* jump to replacement function */
512
513                 M_PUSH_IMM(asm_replacement_out);
514                 M_RET;
515         }
516 }
517         
518
519 /* emit_verbosecall_enter ******************************************************
520
521    Generates the code for the call trace.
522
523 *******************************************************************************/
524
525 #if !defined(NDEBUG)
526 void emit_verbosecall_enter(jitdata *jd)
527 {
528         methodinfo   *m;
529         codegendata  *cd;
530         registerdata *rd;
531         methoddesc   *md;
532         s4            disp;
533         s4            i, t;
534
535         /* get required compiler data */
536
537         m  = jd->m;
538         cd = jd->cd;
539         rd = jd->rd;
540
541         md = m->parseddesc;
542
543         /* mark trace code */
544
545         M_NOP;
546
547         /* methodinfo* + arguments + return address */
548
549         disp = TRACE_ARGS_NUM * 8 + 4 + INT_TMP_CNT * 4 +
550                 cd->stackframesize * 4 + 4;
551
552         M_ASUB_IMM(TRACE_ARGS_NUM * 8 + 4 + INT_TMP_CNT * 4, REG_SP);
553
554         /* save temporary registers for leaf methods */
555
556         for (i = 0; i < INT_TMP_CNT; i++)
557                 M_IST(rd->tmpintregs[i], REG_SP, TRACE_ARGS_NUM * 8 + 4 + i * 4);
558
559         for (i = 0; i < md->paramcount && i < TRACE_ARGS_NUM; i++) {
560                 t = md->paramtypes[i].type;
561
562                 if (IS_INT_LNG_TYPE(t)) {
563                         if (IS_2_WORD_TYPE(t)) {
564                                 M_LLD(REG_ITMP12_PACKED, REG_SP, disp);
565                                 M_LST(REG_ITMP12_PACKED, REG_SP, i * 8);
566                         }
567                         else if (IS_ADR_TYPE(t)) {
568                                 M_ALD(REG_ITMP1, REG_SP, disp);
569                                 M_AST(REG_ITMP1, REG_SP, i * 8);
570                                 M_IST_IMM(0, REG_SP, i * 8 + 4);
571                         }
572                         else {
573                                 M_ILD(EAX, REG_SP, disp);
574                                 emit_cltd(cd);
575                                 M_LST(EAX_EDX_PACKED, REG_SP, i * 8);
576                         }
577                 }
578                 else {
579                         if (IS_2_WORD_TYPE(t)) {
580                                 M_DLD(REG_NULL, REG_SP, disp);
581                                 M_DST(REG_NULL, REG_SP, i * 8);
582                         }
583                         else {
584                                 M_FLD(REG_NULL, REG_SP, disp);
585                                 M_FST(REG_NULL, REG_SP, i * 8);
586                                 M_IST_IMM(0, REG_SP, i * 8 + 4);
587                         }
588                 }
589
590                 disp += (IS_2_WORD_TYPE(t)) ? 8 : 4;
591         }
592         
593         M_AST_IMM(m, REG_SP, TRACE_ARGS_NUM * 8);
594
595         M_MOV_IMM(builtin_trace_args, REG_ITMP1);
596         M_CALL(REG_ITMP1);
597
598         /* restore temporary registers for leaf methods */
599
600         for (i = 0; i < INT_TMP_CNT; i++)
601                 M_ILD(rd->tmpintregs[i], REG_SP, TRACE_ARGS_NUM * 8 + 4 + i * 4);
602
603         M_AADD_IMM(TRACE_ARGS_NUM * 8 + 4 + INT_TMP_CNT * 4, REG_SP);
604
605         /* mark trace code */
606
607         M_NOP;
608 }
609 #endif /* !defined(NDEBUG) */
610
611
612 /* emit_verbosecall_exit *******************************************************
613
614    Generates the code for the call trace.
615
616 *******************************************************************************/
617
618 #if !defined(NDEBUG)
619 void emit_verbosecall_exit(jitdata *jd)
620 {
621         methodinfo   *m;
622         codegendata  *cd;
623         registerdata *rd;
624
625         /* get required compiler data */
626
627         m  = jd->m;
628         cd = jd->cd;
629         rd = jd->rd;
630
631         /* mark trace code */
632
633         M_NOP;
634
635         M_ASUB_IMM(4 + 8 + 8 + 4 + 8, REG_SP);  /* +8: keep stack 16-byte aligned */
636
637         M_AST_IMM(m, REG_SP, 0 * 4);
638
639         M_LST(REG_RESULT_PACKED, REG_SP, 1 * 4);
640
641         M_DSTNP(REG_NULL, REG_SP, 1 * 4 + 1 * 8);
642         M_FSTNP(REG_NULL, REG_SP, 1 * 4 + 2 * 8);
643
644         M_MOV_IMM(builtin_displaymethodstop, REG_ITMP1);
645         M_CALL(REG_ITMP1);
646
647         M_LLD(REG_RESULT_PACKED, REG_SP, 1 * 4);
648
649         M_AADD_IMM(4 + 8 + 8 + 4 + 8, REG_SP);
650
651         /* mark trace code */
652
653         M_NOP;
654 }
655 #endif /* !defined(NDEBUG) */
656
657
658 /* code generation functions **************************************************/
659
660 static void emit_membase(codegendata *cd, s4 basereg, s4 disp, s4 dreg)
661 {
662         if (basereg == ESP) {
663                 if (disp == 0) {
664                         emit_address_byte(0, dreg, ESP);
665                         emit_address_byte(0, ESP, ESP);
666                 }
667                 else if (IS_IMM8(disp)) {
668                         emit_address_byte(1, dreg, ESP);
669                         emit_address_byte(0, ESP, ESP);
670                         emit_imm8(disp);
671                 }
672                 else {
673                         emit_address_byte(2, dreg, ESP);
674                         emit_address_byte(0, ESP, ESP);
675                         emit_imm32(disp);
676                 }
677         }
678         else if ((disp == 0) && (basereg != EBP)) {
679                 emit_address_byte(0, dreg, basereg);
680         }
681         else if (IS_IMM8(disp)) {
682                 emit_address_byte(1, dreg, basereg);
683                 emit_imm8(disp);
684         }
685         else {
686                 emit_address_byte(2, dreg, basereg);
687                 emit_imm32(disp);
688         }
689 }
690
691
692 static void emit_membase32(codegendata *cd, s4 basereg, s4 disp, s4 dreg)
693 {
694         if (basereg == ESP) {
695                 emit_address_byte(2, dreg, ESP);
696                 emit_address_byte(0, ESP, ESP);
697                 emit_imm32(disp);
698         }
699         else {
700                 emit_address_byte(2, dreg, basereg);
701                 emit_imm32(disp);
702         }
703 }
704
705
706 static void emit_memindex(codegendata *cd, s4 reg, s4 disp, s4 basereg, s4 indexreg, s4 scale)
707 {
708         if (basereg == -1) {
709                 emit_address_byte(0, reg, 4);
710                 emit_address_byte(scale, indexreg, 5);
711                 emit_imm32(disp);
712         }
713         else if ((disp == 0) && (basereg != EBP)) {
714                 emit_address_byte(0, reg, 4);
715                 emit_address_byte(scale, indexreg, basereg);
716         }
717         else if (IS_IMM8(disp)) {
718                 emit_address_byte(1, reg, 4);
719                 emit_address_byte(scale, indexreg, basereg);
720                 emit_imm8(disp);
721         }
722         else {
723                 emit_address_byte(2, reg, 4);
724                 emit_address_byte(scale, indexreg, basereg);
725                 emit_imm32(disp);
726         }
727 }
728
729
730 /* low-level code emitter functions *******************************************/
731
732 void emit_mov_reg_reg(codegendata *cd, s4 reg, s4 dreg)
733 {
734         COUNT(count_mov_reg_reg);
735         *(cd->mcodeptr++) = 0x89;
736         emit_reg((reg),(dreg));
737 }
738
739
740 void emit_mov_imm_reg(codegendata *cd, s4 imm, s4 reg)
741 {
742         *(cd->mcodeptr++) = 0xb8 + ((reg) & 0x07);
743         emit_imm32((imm));
744 }
745
746
747 void emit_movb_imm_reg(codegendata *cd, s4 imm, s4 reg)
748 {
749         *(cd->mcodeptr++) = 0xc6;
750         emit_reg(0,(reg));
751         emit_imm8((imm));
752 }
753
754
755 void emit_mov_membase_reg(codegendata *cd, s4 basereg, s4 disp, s4 reg)
756 {
757         COUNT(count_mov_mem_reg);
758         *(cd->mcodeptr++) = 0x8b;
759         emit_membase(cd, (basereg),(disp),(reg));
760 }
761
762
763 /*
764  * this one is for INVOKEVIRTUAL/INVOKEINTERFACE to have a
765  * constant membase immediate length of 32bit
766  */
767 void emit_mov_membase32_reg(codegendata *cd, s4 basereg, s4 disp, s4 reg)
768 {
769         COUNT(count_mov_mem_reg);
770         *(cd->mcodeptr++) = 0x8b;
771         emit_membase32(cd, (basereg),(disp),(reg));
772 }
773
774
775 void emit_mov_reg_membase(codegendata *cd, s4 reg, s4 basereg, s4 disp)
776 {
777         COUNT(count_mov_reg_mem);
778         *(cd->mcodeptr++) = 0x89;
779         emit_membase(cd, (basereg),(disp),(reg));
780 }
781
782
783 void emit_mov_reg_membase32(codegendata *cd, s4 reg, s4 basereg, s4 disp)
784 {
785         COUNT(count_mov_reg_mem);
786         *(cd->mcodeptr++) = 0x89;
787         emit_membase32(cd, (basereg),(disp),(reg));
788 }
789
790
791 void emit_mov_memindex_reg(codegendata *cd, s4 disp, s4 basereg, s4 indexreg, s4 scale, s4 reg)
792 {
793         COUNT(count_mov_mem_reg);
794         *(cd->mcodeptr++) = 0x8b;
795         emit_memindex(cd, (reg),(disp),(basereg),(indexreg),(scale));
796 }
797
798
799 void emit_mov_reg_memindex(codegendata *cd, s4 reg, s4 disp, s4 basereg, s4 indexreg, s4 scale)
800 {
801         COUNT(count_mov_reg_mem);
802         *(cd->mcodeptr++) = 0x89;
803         emit_memindex(cd, (reg),(disp),(basereg),(indexreg),(scale));
804 }
805
806
807 void emit_movw_reg_memindex(codegendata *cd, s4 reg, s4 disp, s4 basereg, s4 indexreg, s4 scale)
808 {
809         COUNT(count_mov_reg_mem);
810         *(cd->mcodeptr++) = 0x66;
811         *(cd->mcodeptr++) = 0x89;
812         emit_memindex(cd, (reg),(disp),(basereg),(indexreg),(scale));
813 }
814
815
816 void emit_movb_reg_memindex(codegendata *cd, s4 reg, s4 disp, s4 basereg, s4 indexreg, s4 scale)
817 {
818         COUNT(count_mov_reg_mem);
819         *(cd->mcodeptr++) = 0x88;
820         emit_memindex(cd, (reg),(disp),(basereg),(indexreg),(scale));
821 }
822
823
824 void emit_mov_reg_mem(codegendata *cd, s4 reg, s4 mem)
825 {
826         COUNT(count_mov_reg_mem);
827         *(cd->mcodeptr++) = 0x89;
828         emit_mem((reg),(mem));
829 }
830
831
832 void emit_mov_mem_reg(codegendata *cd, s4 mem, s4 dreg)
833 {
834         COUNT(count_mov_mem_reg);
835         *(cd->mcodeptr++) = 0x8b;
836         emit_mem((dreg),(mem));
837 }
838
839
840 void emit_mov_imm_mem(codegendata *cd, s4 imm, s4 mem)
841 {
842         *(cd->mcodeptr++) = 0xc7;
843         emit_mem(0, mem);
844         emit_imm32(imm);
845 }
846
847
848 void emit_mov_imm_membase(codegendata *cd, s4 imm, s4 basereg, s4 disp)
849 {
850         *(cd->mcodeptr++) = 0xc7;
851         emit_membase(cd, (basereg),(disp),0);
852         emit_imm32((imm));
853 }
854
855
856 void emit_mov_imm_membase32(codegendata *cd, s4 imm, s4 basereg, s4 disp)
857 {
858         *(cd->mcodeptr++) = 0xc7;
859         emit_membase32(cd, (basereg),(disp),0);
860         emit_imm32((imm));
861 }
862
863
864 void emit_movb_imm_membase(codegendata *cd, s4 imm, s4 basereg, s4 disp)
865 {
866         *(cd->mcodeptr++) = 0xc6;
867         emit_membase(cd, (basereg),(disp),0);
868         emit_imm8((imm));
869 }
870
871
872 void emit_movsbl_memindex_reg(codegendata *cd, s4 disp, s4 basereg, s4 indexreg, s4 scale, s4 reg)
873 {
874         COUNT(count_mov_mem_reg);
875         *(cd->mcodeptr++) = 0x0f;
876         *(cd->mcodeptr++) = 0xbe;
877         emit_memindex(cd, (reg),(disp),(basereg),(indexreg),(scale));
878 }
879
880
881 void emit_movswl_reg_reg(codegendata *cd, s4 a, s4 b)
882 {
883         *(cd->mcodeptr++) = 0x0f;
884         *(cd->mcodeptr++) = 0xbf;
885         emit_reg((b),(a));
886 }
887
888
889 void emit_movswl_memindex_reg(codegendata *cd, s4 disp, s4 basereg, s4 indexreg, s4 scale, s4 reg)
890 {
891         COUNT(count_mov_mem_reg);
892         *(cd->mcodeptr++) = 0x0f;
893         *(cd->mcodeptr++) = 0xbf;
894         emit_memindex(cd, (reg),(disp),(basereg),(indexreg),(scale));
895 }
896
897
898 void emit_movzwl_reg_reg(codegendata *cd, s4 a, s4 b)
899 {
900         *(cd->mcodeptr++) = 0x0f;
901         *(cd->mcodeptr++) = 0xb7;
902         emit_reg((b),(a));
903 }
904
905
906 void emit_movzwl_memindex_reg(codegendata *cd, s4 disp, s4 basereg, s4 indexreg, s4 scale, s4 reg)
907 {
908         COUNT(count_mov_mem_reg);
909         *(cd->mcodeptr++) = 0x0f;
910         *(cd->mcodeptr++) = 0xb7;
911         emit_memindex(cd, (reg),(disp),(basereg),(indexreg),(scale));
912 }
913
914
915 void emit_mov_imm_memindex(codegendata *cd, s4 imm, s4 disp, s4 basereg, s4 indexreg, s4 scale)
916 {
917         *(cd->mcodeptr++) = 0xc7;
918         emit_memindex(cd, 0,(disp),(basereg),(indexreg),(scale));
919         emit_imm32((imm));
920 }
921
922
923 void emit_movw_imm_memindex(codegendata *cd, s4 imm, s4 disp, s4 basereg, s4 indexreg, s4 scale)
924 {
925         *(cd->mcodeptr++) = 0x66;
926         *(cd->mcodeptr++) = 0xc7;
927         emit_memindex(cd, 0,(disp),(basereg),(indexreg),(scale));
928         emit_imm16((imm));
929 }
930
931
932 void emit_movb_imm_memindex(codegendata *cd, s4 imm, s4 disp, s4 basereg, s4 indexreg, s4 scale)
933 {
934         *(cd->mcodeptr++) = 0xc6;
935         emit_memindex(cd, 0,(disp),(basereg),(indexreg),(scale));
936         emit_imm8((imm));
937 }
938
939
940 /*
941  * alu operations
942  */
943 void emit_alu_reg_reg(codegendata *cd, s4 opc, s4 reg, s4 dreg)
944 {
945         *(cd->mcodeptr++) = (((u1) (opc)) << 3) + 1;
946         emit_reg((reg),(dreg));
947 }
948
949
950 void emit_alu_reg_membase(codegendata *cd, s4 opc, s4 reg, s4 basereg, s4 disp)
951 {
952         *(cd->mcodeptr++) = (((u1) (opc)) << 3) + 1;
953         emit_membase(cd, (basereg),(disp),(reg));
954 }
955
956
957 void emit_alu_membase_reg(codegendata *cd, s4 opc, s4 basereg, s4 disp, s4 reg)
958 {
959         *(cd->mcodeptr++) = (((u1) (opc)) << 3) + 3;
960         emit_membase(cd, (basereg),(disp),(reg));
961 }
962
963
964 void emit_alu_imm_reg(codegendata *cd, s4 opc, s4 imm, s4 dreg)
965 {
966         if (IS_IMM8(imm)) { 
967                 *(cd->mcodeptr++) = 0x83;
968                 emit_reg((opc),(dreg));
969                 emit_imm8((imm));
970         } else { 
971                 *(cd->mcodeptr++) = 0x81;
972                 emit_reg((opc),(dreg));
973                 emit_imm32((imm));
974         } 
975 }
976
977
978 void emit_alu_imm32_reg(codegendata *cd, s4 opc, s4 imm, s4 dreg)
979 {
980         *(cd->mcodeptr++) = 0x81;
981         emit_reg((opc),(dreg));
982         emit_imm32((imm));
983 }
984
985
986 void emit_alu_imm_membase(codegendata *cd, s4 opc, s4 imm, s4 basereg, s4 disp)
987 {
988         if (IS_IMM8(imm)) { 
989                 *(cd->mcodeptr++) = 0x83;
990                 emit_membase(cd, (basereg),(disp),(opc));
991                 emit_imm8((imm));
992         } else { 
993                 *(cd->mcodeptr++) = 0x81;
994                 emit_membase(cd, (basereg),(disp),(opc));
995                 emit_imm32((imm));
996         } 
997 }
998
999
1000 void emit_test_reg_reg(codegendata *cd, s4 reg, s4 dreg)
1001 {
1002         *(cd->mcodeptr++) = 0x85;
1003         emit_reg((reg),(dreg));
1004 }
1005
1006
1007 void emit_test_imm_reg(codegendata *cd, s4 imm, s4 reg)
1008 {
1009         *(cd->mcodeptr++) = 0xf7;
1010         emit_reg(0,(reg));
1011         emit_imm32((imm));
1012 }
1013
1014
1015
1016 /*
1017  * inc, dec operations
1018  */
1019 void emit_dec_mem(codegendata *cd, s4 mem)
1020 {
1021         *(cd->mcodeptr++) = 0xff;
1022         emit_mem(1,(mem));
1023 }
1024
1025
1026 void emit_cltd(codegendata *cd)
1027 {
1028         *(cd->mcodeptr++) = 0x99;
1029 }
1030
1031
1032 void emit_imul_reg_reg(codegendata *cd, s4 reg, s4 dreg)
1033 {
1034         *(cd->mcodeptr++) = 0x0f;
1035         *(cd->mcodeptr++) = 0xaf;
1036         emit_reg((dreg),(reg));
1037 }
1038
1039
1040 void emit_imul_membase_reg(codegendata *cd, s4 basereg, s4 disp, s4 dreg)
1041 {
1042         *(cd->mcodeptr++) = 0x0f;
1043         *(cd->mcodeptr++) = 0xaf;
1044         emit_membase(cd, (basereg),(disp),(dreg));
1045 }
1046
1047
1048 void emit_imul_imm_reg(codegendata *cd, s4 imm, s4 dreg)
1049 {
1050         if (IS_IMM8((imm))) { 
1051                 *(cd->mcodeptr++) = 0x6b;
1052                 emit_reg(0,(dreg));
1053                 emit_imm8((imm));
1054         } else { 
1055                 *(cd->mcodeptr++) = 0x69;
1056                 emit_reg(0,(dreg));
1057                 emit_imm32((imm));
1058         } 
1059 }
1060
1061
1062 void emit_imul_imm_reg_reg(codegendata *cd, s4 imm, s4 reg, s4 dreg)
1063 {
1064         if (IS_IMM8((imm))) { 
1065                 *(cd->mcodeptr++) = 0x6b;
1066                 emit_reg((dreg),(reg));
1067                 emit_imm8((imm));
1068         } else { 
1069                 *(cd->mcodeptr++) = 0x69;
1070                 emit_reg((dreg),(reg));
1071                 emit_imm32((imm));
1072         } 
1073 }
1074
1075
1076 void emit_imul_imm_membase_reg(codegendata *cd, s4 imm, s4 basereg, s4 disp, s4 dreg)
1077 {
1078         if (IS_IMM8((imm))) {
1079                 *(cd->mcodeptr++) = 0x6b;
1080                 emit_membase(cd, (basereg),(disp),(dreg));
1081                 emit_imm8((imm));
1082         } else {
1083                 *(cd->mcodeptr++) = 0x69;
1084                 emit_membase(cd, (basereg),(disp),(dreg));
1085                 emit_imm32((imm));
1086         }
1087 }
1088
1089
1090 void emit_mul_reg(codegendata *cd, s4 reg)
1091 {
1092         *(cd->mcodeptr++) = 0xf7;
1093         emit_reg(4, reg);
1094 }
1095
1096
1097 void emit_mul_membase(codegendata *cd, s4 basereg, s4 disp)
1098 {
1099         *(cd->mcodeptr++) = 0xf7;
1100         emit_membase(cd, (basereg),(disp),4);
1101 }
1102
1103
1104 void emit_idiv_reg(codegendata *cd, s4 reg)
1105 {
1106         *(cd->mcodeptr++) = 0xf7;
1107         emit_reg(7,(reg));
1108 }
1109
1110
1111 void emit_ret(codegendata *cd)
1112 {
1113         *(cd->mcodeptr++) = 0xc3;
1114 }
1115
1116
1117
1118 /*
1119  * shift ops
1120  */
1121 void emit_shift_reg(codegendata *cd, s4 opc, s4 reg)
1122 {
1123         *(cd->mcodeptr++) = 0xd3;
1124         emit_reg((opc),(reg));
1125 }
1126
1127
1128 void emit_shift_imm_reg(codegendata *cd, s4 opc, s4 imm, s4 dreg)
1129 {
1130         if ((imm) == 1) {
1131                 *(cd->mcodeptr++) = 0xd1;
1132                 emit_reg((opc),(dreg));
1133         } else {
1134                 *(cd->mcodeptr++) = 0xc1;
1135                 emit_reg((opc),(dreg));
1136                 emit_imm8((imm));
1137         }
1138 }
1139
1140
1141 void emit_shld_reg_reg(codegendata *cd, s4 reg, s4 dreg)
1142 {
1143         *(cd->mcodeptr++) = 0x0f;
1144         *(cd->mcodeptr++) = 0xa5;
1145         emit_reg((reg),(dreg));
1146 }
1147
1148
1149 void emit_shld_imm_reg_reg(codegendata *cd, s4 imm, s4 reg, s4 dreg)
1150 {
1151         *(cd->mcodeptr++) = 0x0f;
1152         *(cd->mcodeptr++) = 0xa4;
1153         emit_reg((reg),(dreg));
1154         emit_imm8((imm));
1155 }
1156
1157
1158 void emit_shld_reg_membase(codegendata *cd, s4 reg, s4 basereg, s4 disp)
1159 {
1160         *(cd->mcodeptr++) = 0x0f;
1161         *(cd->mcodeptr++) = 0xa5;
1162         emit_membase(cd, (basereg),(disp),(reg));
1163 }
1164
1165
1166 void emit_shrd_reg_reg(codegendata *cd, s4 reg, s4 dreg)
1167 {
1168         *(cd->mcodeptr++) = 0x0f;
1169         *(cd->mcodeptr++) = 0xad;
1170         emit_reg((reg),(dreg));
1171 }
1172
1173
1174 void emit_shrd_imm_reg_reg(codegendata *cd, s4 imm, s4 reg, s4 dreg)
1175 {
1176         *(cd->mcodeptr++) = 0x0f;
1177         *(cd->mcodeptr++) = 0xac;
1178         emit_reg((reg),(dreg));
1179         emit_imm8((imm));
1180 }
1181
1182
1183 void emit_shrd_reg_membase(codegendata *cd, s4 reg, s4 basereg, s4 disp)
1184 {
1185         *(cd->mcodeptr++) = 0x0f;
1186         *(cd->mcodeptr++) = 0xad;
1187         emit_membase(cd, (basereg),(disp),(reg));
1188 }
1189
1190
1191
1192 /*
1193  * jump operations
1194  */
1195 void emit_jmp_imm(codegendata *cd, s4 imm)
1196 {
1197         *(cd->mcodeptr++) = 0xe9;
1198         emit_imm32((imm));
1199 }
1200
1201
1202 void emit_jmp_reg(codegendata *cd, s4 reg)
1203 {
1204         *(cd->mcodeptr++) = 0xff;
1205         emit_reg(4,(reg));
1206 }
1207
1208
1209 void emit_jcc(codegendata *cd, s4 opc, s4 imm)
1210 {
1211         *(cd->mcodeptr++) = 0x0f;
1212         *(cd->mcodeptr++) =  0x80 + (u1) (opc);
1213         emit_imm32((imm));
1214 }
1215
1216
1217
1218 /*
1219  * conditional set operations
1220  */
1221 void emit_setcc_reg(codegendata *cd, s4 opc, s4 reg)
1222 {
1223         *(cd->mcodeptr++) = 0x0f;
1224         *(cd->mcodeptr++) = 0x90 + (u1) (opc);
1225         emit_reg(0,(reg));
1226 }
1227
1228
1229 void emit_setcc_membase(codegendata *cd, s4 opc, s4 basereg, s4 disp)
1230 {
1231         *(cd->mcodeptr++) = 0x0f;
1232         *(cd->mcodeptr++) =  0x90 + (u1) (opc);
1233         emit_membase(cd, (basereg),(disp),0);
1234 }
1235
1236
1237 void emit_xadd_reg_mem(codegendata *cd, s4 reg, s4 mem)
1238 {
1239         *(cd->mcodeptr++) = 0x0f;
1240         *(cd->mcodeptr++) = 0xc1;
1241         emit_mem((reg),(mem));
1242 }
1243
1244
1245 void emit_neg_reg(codegendata *cd, s4 reg)
1246 {
1247         *(cd->mcodeptr++) = 0xf7;
1248         emit_reg(3,(reg));
1249 }
1250
1251
1252
1253 void emit_push_imm(codegendata *cd, s4 imm)
1254 {
1255         *(cd->mcodeptr++) = 0x68;
1256         emit_imm32((imm));
1257 }
1258
1259
1260 void emit_pop_reg(codegendata *cd, s4 reg)
1261 {
1262         *(cd->mcodeptr++) = 0x58 + (0x07 & (u1) (reg));
1263 }
1264
1265
1266 void emit_push_reg(codegendata *cd, s4 reg)
1267 {
1268         *(cd->mcodeptr++) = 0x50 + (0x07 & (u1) (reg));
1269 }
1270
1271
1272 void emit_nop(codegendata *cd)
1273 {
1274         *(cd->mcodeptr++) = 0x90;
1275 }
1276
1277
1278 void emit_lock(codegendata *cd)
1279 {
1280         *(cd->mcodeptr++) = 0xf0;
1281 }
1282
1283
1284 /*
1285  * call instructions
1286  */
1287 void emit_call_reg(codegendata *cd, s4 reg)
1288 {
1289         *(cd->mcodeptr++) = 0xff;
1290         emit_reg(2,(reg));
1291 }
1292
1293
1294 void emit_call_imm(codegendata *cd, s4 imm)
1295 {
1296         *(cd->mcodeptr++) = 0xe8;
1297         emit_imm32((imm));
1298 }
1299
1300
1301
1302 /*
1303  * floating point instructions
1304  */
1305 void emit_fld1(codegendata *cd)
1306 {
1307         *(cd->mcodeptr++) = 0xd9;
1308         *(cd->mcodeptr++) = 0xe8;
1309 }
1310
1311
1312 void emit_fldz(codegendata *cd)
1313 {
1314         *(cd->mcodeptr++) = 0xd9;
1315         *(cd->mcodeptr++) = 0xee;
1316 }
1317
1318
1319 void emit_fld_reg(codegendata *cd, s4 reg)
1320 {
1321         *(cd->mcodeptr++) = 0xd9;
1322         *(cd->mcodeptr++) = 0xc0 + (0x07 & (u1) (reg));
1323 }
1324
1325
1326 void emit_flds_membase(codegendata *cd, s4 basereg, s4 disp)
1327 {
1328         *(cd->mcodeptr++) = 0xd9;
1329         emit_membase(cd, (basereg),(disp),0);
1330 }
1331
1332
1333 void emit_flds_membase32(codegendata *cd, s4 basereg, s4 disp)
1334 {
1335         *(cd->mcodeptr++) = 0xd9;
1336         emit_membase32(cd, (basereg),(disp),0);
1337 }
1338
1339
1340 void emit_fldl_membase(codegendata *cd, s4 basereg, s4 disp)
1341 {
1342         *(cd->mcodeptr++) = 0xdd;
1343         emit_membase(cd, (basereg),(disp),0);
1344 }
1345
1346
1347 void emit_fldl_membase32(codegendata *cd, s4 basereg, s4 disp)
1348 {
1349         *(cd->mcodeptr++) = 0xdd;
1350         emit_membase32(cd, (basereg),(disp),0);
1351 }
1352
1353
1354 void emit_fldt_membase(codegendata *cd, s4 basereg, s4 disp)
1355 {
1356         *(cd->mcodeptr++) = 0xdb;
1357         emit_membase(cd, (basereg),(disp),5);
1358 }
1359
1360
1361 void emit_flds_memindex(codegendata *cd, s4 disp, s4 basereg, s4 indexreg, s4 scale)
1362 {
1363         *(cd->mcodeptr++) = 0xd9;
1364         emit_memindex(cd, 0,(disp),(basereg),(indexreg),(scale));
1365 }
1366
1367
1368 void emit_fldl_memindex(codegendata *cd, s4 disp, s4 basereg, s4 indexreg, s4 scale)
1369 {
1370         *(cd->mcodeptr++) = 0xdd;
1371         emit_memindex(cd, 0,(disp),(basereg),(indexreg),(scale));
1372 }
1373
1374
1375 void emit_flds_mem(codegendata *cd, s4 mem)
1376 {
1377         *(cd->mcodeptr++) = 0xd9;
1378         emit_mem(0,(mem));
1379 }
1380
1381
1382 void emit_fldl_mem(codegendata *cd, s4 mem)
1383 {
1384         *(cd->mcodeptr++) = 0xdd;
1385         emit_mem(0,(mem));
1386 }
1387
1388
1389 void emit_fildl_membase(codegendata *cd, s4 basereg, s4 disp)
1390 {
1391         *(cd->mcodeptr++) = 0xdb;
1392         emit_membase(cd, (basereg),(disp),0);
1393 }
1394
1395
1396 void emit_fildll_membase(codegendata *cd, s4 basereg, s4 disp)
1397 {
1398         *(cd->mcodeptr++) = 0xdf;
1399         emit_membase(cd, (basereg),(disp),5);
1400 }
1401
1402
1403 void emit_fst_reg(codegendata *cd, s4 reg)
1404 {
1405         *(cd->mcodeptr++) = 0xdd;
1406         *(cd->mcodeptr++) = 0xd0 + (0x07 & (u1) (reg));
1407 }
1408
1409
1410 void emit_fsts_membase(codegendata *cd, s4 basereg, s4 disp)
1411 {
1412         *(cd->mcodeptr++) = 0xd9;
1413         emit_membase(cd, (basereg),(disp),2);
1414 }
1415
1416
1417 void emit_fstl_membase(codegendata *cd, s4 basereg, s4 disp)
1418 {
1419         *(cd->mcodeptr++) = 0xdd;
1420         emit_membase(cd, (basereg),(disp),2);
1421 }
1422
1423
1424 void emit_fsts_memindex(codegendata *cd, s4 disp, s4 basereg, s4 indexreg, s4 scale)
1425 {
1426         *(cd->mcodeptr++) = 0xd9;
1427         emit_memindex(cd, 2,(disp),(basereg),(indexreg),(scale));
1428 }
1429
1430
1431 void emit_fstl_memindex(codegendata *cd, s4 disp, s4 basereg, s4 indexreg, s4 scale)
1432 {
1433         *(cd->mcodeptr++) = 0xdd;
1434         emit_memindex(cd, 2,(disp),(basereg),(indexreg),(scale));
1435 }
1436
1437
1438 void emit_fstp_reg(codegendata *cd, s4 reg)
1439 {
1440         *(cd->mcodeptr++) = 0xdd;
1441         *(cd->mcodeptr++) = 0xd8 + (0x07 & (u1) (reg));
1442 }
1443
1444
1445 void emit_fstps_membase(codegendata *cd, s4 basereg, s4 disp)
1446 {
1447         *(cd->mcodeptr++) = 0xd9;
1448         emit_membase(cd, (basereg),(disp),3);
1449 }
1450
1451
1452 void emit_fstps_membase32(codegendata *cd, s4 basereg, s4 disp)
1453 {
1454         *(cd->mcodeptr++) = 0xd9;
1455         emit_membase32(cd, (basereg),(disp),3);
1456 }
1457
1458
1459 void emit_fstpl_membase(codegendata *cd, s4 basereg, s4 disp)
1460 {
1461         *(cd->mcodeptr++) = 0xdd;
1462         emit_membase(cd, (basereg),(disp),3);
1463 }
1464
1465
1466 void emit_fstpl_membase32(codegendata *cd, s4 basereg, s4 disp)
1467 {
1468         *(cd->mcodeptr++) = 0xdd;
1469         emit_membase32(cd, (basereg),(disp),3);
1470 }
1471
1472
1473 void emit_fstpt_membase(codegendata *cd, s4 basereg, s4 disp)
1474 {
1475         *(cd->mcodeptr++) = 0xdb;
1476         emit_membase(cd, (basereg),(disp),7);
1477 }
1478
1479
1480 void emit_fstps_memindex(codegendata *cd, s4 disp, s4 basereg, s4 indexreg, s4 scale)
1481 {
1482         *(cd->mcodeptr++) = 0xd9;
1483         emit_memindex(cd, 3,(disp),(basereg),(indexreg),(scale));
1484 }
1485
1486
1487 void emit_fstpl_memindex(codegendata *cd, s4 disp, s4 basereg, s4 indexreg, s4 scale)
1488 {
1489         *(cd->mcodeptr++) = 0xdd;
1490         emit_memindex(cd, 3,(disp),(basereg),(indexreg),(scale));
1491 }
1492
1493
1494 void emit_fstps_mem(codegendata *cd, s4 mem)
1495 {
1496         *(cd->mcodeptr++) = 0xd9;
1497         emit_mem(3,(mem));
1498 }
1499
1500
1501 void emit_fstpl_mem(codegendata *cd, s4 mem)
1502 {
1503         *(cd->mcodeptr++) = 0xdd;
1504         emit_mem(3,(mem));
1505 }
1506
1507
1508 void emit_fistl_membase(codegendata *cd, s4 basereg, s4 disp)
1509 {
1510         *(cd->mcodeptr++) = 0xdb;
1511         emit_membase(cd, (basereg),(disp),2);
1512 }
1513
1514
1515 void emit_fistpl_membase(codegendata *cd, s4 basereg, s4 disp)
1516 {
1517         *(cd->mcodeptr++) = 0xdb;
1518         emit_membase(cd, (basereg),(disp),3);
1519 }
1520
1521
1522 void emit_fistpll_membase(codegendata *cd, s4 basereg, s4 disp)
1523 {
1524         *(cd->mcodeptr++) = 0xdf;
1525         emit_membase(cd, (basereg),(disp),7);
1526 }
1527
1528
1529 void emit_fchs(codegendata *cd)
1530 {
1531         *(cd->mcodeptr++) = 0xd9;
1532         *(cd->mcodeptr++) = 0xe0;
1533 }
1534
1535
1536 void emit_faddp(codegendata *cd)
1537 {
1538         *(cd->mcodeptr++) = 0xde;
1539         *(cd->mcodeptr++) = 0xc1;
1540 }
1541
1542
1543 void emit_fadd_reg_st(codegendata *cd, s4 reg)
1544 {
1545         *(cd->mcodeptr++) = 0xd8;
1546         *(cd->mcodeptr++) = 0xc0 + (0x0f & (u1) (reg));
1547 }
1548
1549
1550 void emit_fadd_st_reg(codegendata *cd, s4 reg)
1551 {
1552         *(cd->mcodeptr++) = 0xdc;
1553         *(cd->mcodeptr++) = 0xc0 + (0x0f & (u1) (reg));
1554 }
1555
1556
1557 void emit_faddp_st_reg(codegendata *cd, s4 reg)
1558 {
1559         *(cd->mcodeptr++) = 0xde;
1560         *(cd->mcodeptr++) = 0xc0 + (0x0f & (u1) (reg));
1561 }
1562
1563
1564 void emit_fadds_membase(codegendata *cd, s4 basereg, s4 disp)
1565 {
1566         *(cd->mcodeptr++) = 0xd8;
1567         emit_membase(cd, (basereg),(disp),0);
1568 }
1569
1570
1571 void emit_faddl_membase(codegendata *cd, s4 basereg, s4 disp)
1572 {
1573         *(cd->mcodeptr++) = 0xdc;
1574         emit_membase(cd, (basereg),(disp),0);
1575 }
1576
1577
1578 void emit_fsub_reg_st(codegendata *cd, s4 reg)
1579 {
1580         *(cd->mcodeptr++) = 0xd8;
1581         *(cd->mcodeptr++) = 0xe0 + (0x07 & (u1) (reg));
1582 }
1583
1584
1585 void emit_fsub_st_reg(codegendata *cd, s4 reg)
1586 {
1587         *(cd->mcodeptr++) = 0xdc;
1588         *(cd->mcodeptr++) = 0xe8 + (0x07 & (u1) (reg));
1589 }
1590
1591
1592 void emit_fsubp_st_reg(codegendata *cd, s4 reg)
1593 {
1594         *(cd->mcodeptr++) = 0xde;
1595         *(cd->mcodeptr++) = 0xe8 + (0x07 & (u1) (reg));
1596 }
1597
1598
1599 void emit_fsubp(codegendata *cd)
1600 {
1601         *(cd->mcodeptr++) = 0xde;
1602         *(cd->mcodeptr++) = 0xe9;
1603 }
1604
1605
1606 void emit_fsubs_membase(codegendata *cd, s4 basereg, s4 disp)
1607 {
1608         *(cd->mcodeptr++) = 0xd8;
1609         emit_membase(cd, (basereg),(disp),4);
1610 }
1611
1612
1613 void emit_fsubl_membase(codegendata *cd, s4 basereg, s4 disp)
1614 {
1615         *(cd->mcodeptr++) = 0xdc;
1616         emit_membase(cd, (basereg),(disp),4);
1617 }
1618
1619
1620 void emit_fmul_reg_st(codegendata *cd, s4 reg)
1621 {
1622         *(cd->mcodeptr++) = 0xd8;
1623         *(cd->mcodeptr++) = 0xc8 + (0x07 & (u1) (reg));
1624 }
1625
1626
1627 void emit_fmul_st_reg(codegendata *cd, s4 reg)
1628 {
1629         *(cd->mcodeptr++) = 0xdc;
1630         *(cd->mcodeptr++) = 0xc8 + (0x07 & (u1) (reg));
1631 }
1632
1633
1634 void emit_fmulp(codegendata *cd)
1635 {
1636         *(cd->mcodeptr++) = 0xde;
1637         *(cd->mcodeptr++) = 0xc9;
1638 }
1639
1640
1641 void emit_fmulp_st_reg(codegendata *cd, s4 reg)
1642 {
1643         *(cd->mcodeptr++) = 0xde;
1644         *(cd->mcodeptr++) = 0xc8 + (0x07 & (u1) (reg));
1645 }
1646
1647
1648 void emit_fmuls_membase(codegendata *cd, s4 basereg, s4 disp)
1649 {
1650         *(cd->mcodeptr++) = 0xd8;
1651         emit_membase(cd, (basereg),(disp),1);
1652 }
1653
1654
1655 void emit_fmull_membase(codegendata *cd, s4 basereg, s4 disp)
1656 {
1657         *(cd->mcodeptr++) = 0xdc;
1658         emit_membase(cd, (basereg),(disp),1);
1659 }
1660
1661
1662 void emit_fdiv_reg_st(codegendata *cd, s4 reg)
1663 {
1664         *(cd->mcodeptr++) = 0xd8;
1665         *(cd->mcodeptr++) = 0xf0 + (0x07 & (u1) (reg));
1666 }
1667
1668
1669 void emit_fdiv_st_reg(codegendata *cd, s4 reg)
1670 {
1671         *(cd->mcodeptr++) = 0xdc;
1672         *(cd->mcodeptr++) = 0xf8 + (0x07 & (u1) (reg));
1673 }
1674
1675
1676 void emit_fdivp(codegendata *cd)
1677 {
1678         *(cd->mcodeptr++) = 0xde;
1679         *(cd->mcodeptr++) = 0xf9;
1680 }
1681
1682
1683 void emit_fdivp_st_reg(codegendata *cd, s4 reg)
1684 {
1685         *(cd->mcodeptr++) = 0xde;
1686         *(cd->mcodeptr++) = 0xf8 + (0x07 & (u1) (reg));
1687 }
1688
1689
1690 void emit_fxch(codegendata *cd)
1691 {
1692         *(cd->mcodeptr++) = 0xd9;
1693         *(cd->mcodeptr++) = 0xc9;
1694 }
1695
1696
1697 void emit_fxch_reg(codegendata *cd, s4 reg)
1698 {
1699         *(cd->mcodeptr++) = 0xd9;
1700         *(cd->mcodeptr++) = 0xc8 + (0x07 & (reg));
1701 }
1702
1703
1704 void emit_fprem(codegendata *cd)
1705 {
1706         *(cd->mcodeptr++) = 0xd9;
1707         *(cd->mcodeptr++) = 0xf8;
1708 }
1709
1710
1711 void emit_fprem1(codegendata *cd)
1712 {
1713         *(cd->mcodeptr++) = 0xd9;
1714         *(cd->mcodeptr++) = 0xf5;
1715 }
1716
1717
1718 void emit_fucom(codegendata *cd)
1719 {
1720         *(cd->mcodeptr++) = 0xdd;
1721         *(cd->mcodeptr++) = 0xe1;
1722 }
1723
1724
1725 void emit_fucom_reg(codegendata *cd, s4 reg)
1726 {
1727         *(cd->mcodeptr++) = 0xdd;
1728         *(cd->mcodeptr++) = 0xe0 + (0x07 & (u1) (reg));
1729 }
1730
1731
1732 void emit_fucomp_reg(codegendata *cd, s4 reg)
1733 {
1734         *(cd->mcodeptr++) = 0xdd;
1735         *(cd->mcodeptr++) = 0xe8 + (0x07 & (u1) (reg));
1736 }
1737
1738
1739 void emit_fucompp(codegendata *cd)
1740 {
1741         *(cd->mcodeptr++) = 0xda;
1742         *(cd->mcodeptr++) = 0xe9;
1743 }
1744
1745
1746 void emit_fnstsw(codegendata *cd)
1747 {
1748         *(cd->mcodeptr++) = 0xdf;
1749         *(cd->mcodeptr++) = 0xe0;
1750 }
1751
1752
1753 void emit_sahf(codegendata *cd)
1754 {
1755         *(cd->mcodeptr++) = 0x9e;
1756 }
1757
1758
1759 void emit_finit(codegendata *cd)
1760 {
1761         *(cd->mcodeptr++) = 0x9b;
1762         *(cd->mcodeptr++) = 0xdb;
1763         *(cd->mcodeptr++) = 0xe3;
1764 }
1765
1766
1767 void emit_fldcw_mem(codegendata *cd, s4 mem)
1768 {
1769         *(cd->mcodeptr++) = 0xd9;
1770         emit_mem(5,(mem));
1771 }
1772
1773
1774 void emit_fldcw_membase(codegendata *cd, s4 basereg, s4 disp)
1775 {
1776         *(cd->mcodeptr++) = 0xd9;
1777         emit_membase(cd, (basereg),(disp),5);
1778 }
1779
1780
1781 void emit_wait(codegendata *cd)
1782 {
1783         *(cd->mcodeptr++) = 0x9b;
1784 }
1785
1786
1787 void emit_ffree_reg(codegendata *cd, s4 reg)
1788 {
1789         *(cd->mcodeptr++) = 0xdd;
1790         *(cd->mcodeptr++) = 0xc0 + (0x07 & (u1) (reg));
1791 }
1792
1793
1794 void emit_fdecstp(codegendata *cd)
1795 {
1796         *(cd->mcodeptr++) = 0xd9;
1797         *(cd->mcodeptr++) = 0xf6;
1798 }
1799
1800
1801 void emit_fincstp(codegendata *cd)
1802 {
1803         *(cd->mcodeptr++) = 0xd9;
1804         *(cd->mcodeptr++) = 0xf7;
1805 }
1806
1807
1808 /*
1809  * These are local overrides for various environment variables in Emacs.
1810  * Please do not remove this and leave it at the end of the file, where
1811  * Emacs will automagically detect them.
1812  * ---------------------------------------------------------------------
1813  * Local variables:
1814  * mode: c
1815  * indent-tabs-mode: t
1816  * c-basic-offset: 4
1817  * tab-width: 4
1818  * End:
1819  */