Merge from subtype.
[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, 2007, 2008
4    CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
5
6    This file is part of CACAO.
7
8    This program is free software; you can redistribute it and/or
9    modify it under the terms of the GNU General Public License as
10    published by the Free Software Foundation; either version 2, or (at
11    your option) any later version.
12
13    This program is distributed in the hope that it will be useful, but
14    WITHOUT ANY WARRANTY; without even the implied warranty of
15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16    General Public License for more details.
17
18    You should have received a copy of the GNU General Public License
19    along with this program; if not, write to the Free Software
20    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
21    02110-1301, USA.
22
23 */
24
25
26 #include "config.h"
27
28 #include <assert.h>
29
30 #include "vm/types.h"
31
32 #include "vm/jit/i386/codegen.h"
33 #include "vm/jit/i386/emit.h"
34 #include "vm/jit/i386/md-abi.h"
35
36 #include "mm/memory.h"
37
38 #include "threads/lock.hpp"
39
40 #include "vm/options.h"
41 #include "vm/statistics.h"
42
43 #include "vm/jit/abi.h"
44 #include "vm/jit/asmpart.h"
45 #include "vm/jit/dseg.h"
46 #include "vm/jit/emit-common.hpp"
47 #include "vm/jit/jit.hpp"
48 #include "vm/jit/patcher-common.hpp"
49 #include "vm/jit/replace.hpp"
50 #include "vm/jit/trace.hpp"
51 #include "vm/jit/trap.h"
52
53
54 /* emit_load ******************************************************************
55
56    Emits a possible load of an operand.
57
58 *******************************************************************************/
59
60 inline s4 emit_load(jitdata *jd, instruction *iptr, varinfo *src, s4 tempreg)
61 {
62         codegendata  *cd;
63         s4            disp;
64         s4            reg;
65
66         /* get required compiler data */
67
68         cd = jd->cd;
69
70         if (IS_INMEMORY(src->flags)) {
71                 COUNT_SPILLS;
72
73                 disp = src->vv.regoff;
74
75                 switch (src->type) {
76                 case TYPE_INT:
77                 case TYPE_ADR:
78                         M_ILD(tempreg, REG_SP, disp);
79                         break;
80                 case TYPE_LNG:
81                         M_LLD(tempreg, REG_SP, disp);
82                         break;
83                 case TYPE_FLT:
84                         M_FLD(tempreg, REG_SP, disp);
85                         break;
86                 case TYPE_DBL:
87                         M_DLD(tempreg, REG_SP, disp);
88                         break;
89                 default:
90                         vm_abort("emit_load: unknown type %d", src->type);
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;
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;
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         s4            disp;
181
182         /* get required compiler data */
183
184         cd = jd->cd;
185
186         if (IS_INMEMORY(dst->flags)) {
187                 COUNT_SPILLS;
188
189                 disp = dst->vv.regoff;
190
191                 switch (dst->type) {
192                 case TYPE_INT:
193                 case TYPE_ADR:
194                         M_IST(d, REG_SP, disp);
195                         break;
196                 case TYPE_LNG:
197                         M_LST(d, REG_SP, disp);
198                         break;
199                 case TYPE_FLT:
200                         M_FST(d, REG_SP, disp);
201                         break;
202                 case TYPE_DBL:
203                         M_DST(d, REG_SP, disp);
204                         break;
205                 default:
206                         vm_abort("emit_store: unknown type %d", dst->type);
207                 }
208         }
209 }
210
211
212 /* emit_store_low **************************************************************
213
214    Emits a possible store of the low 32-bits of the destination
215    operand.
216
217 *******************************************************************************/
218
219 inline void emit_store_low(jitdata *jd, instruction *iptr, varinfo *dst, s4 d)
220 {
221         codegendata  *cd;
222
223         assert(dst->type == TYPE_LNG);
224
225         /* get required compiler data */
226
227         cd = jd->cd;
228
229         if (IS_INMEMORY(dst->flags)) {
230                 COUNT_SPILLS;
231                 M_IST(GET_LOW_REG(d), REG_SP, dst->vv.regoff);
232         }
233 }
234
235
236 /* emit_store_high *************************************************************
237
238    Emits a possible store of the high 32-bits of the destination
239    operand.
240
241 *******************************************************************************/
242
243 inline void emit_store_high(jitdata *jd, instruction *iptr, varinfo *dst, s4 d)
244 {
245         codegendata  *cd;
246
247         assert(dst->type == TYPE_LNG);
248
249         /* get required compiler data */
250
251         cd = jd->cd;
252
253         if (IS_INMEMORY(dst->flags)) {
254                 COUNT_SPILLS;
255                 M_IST(GET_HIGH_REG(d), REG_SP, dst->vv.regoff + 4);
256         }
257 }
258
259
260 /* emit_copy *******************************************************************
261
262    Generates a register/memory to register/memory copy.
263
264 *******************************************************************************/
265
266 void emit_copy(jitdata *jd, instruction *iptr)
267 {
268         codegendata *cd;
269         varinfo     *src;
270         varinfo     *dst;
271         s4           s1, d;
272
273         /* get required compiler data */
274
275         cd = jd->cd;
276
277         /* get source and destination variables */
278
279         src = VAROP(iptr->s1);
280         dst = VAROP(iptr->dst);
281
282         if ((src->vv.regoff != dst->vv.regoff) ||
283                 ((src->flags ^ dst->flags) & INMEMORY)) {
284
285                 if ((src->type == TYPE_RET) || (dst->type == TYPE_RET)) {
286                         /* emit nothing, as the value won't be used anyway */
287                         return;
288                 }
289
290                 /* If one of the variables resides in memory, we can eliminate
291                    the register move from/to the temporary register with the
292                    order of getting the destination register and the load. */
293
294                 if (IS_INMEMORY(src->flags)) {
295                         if (IS_LNG_TYPE(src->type))
296                                 d = codegen_reg_of_var(iptr->opc, dst, REG_ITMP12_PACKED);
297                         else
298                                 d = codegen_reg_of_var(iptr->opc, dst, REG_ITMP1);
299
300                         s1 = emit_load(jd, iptr, src, d);
301                 }
302                 else {
303                         if (IS_LNG_TYPE(src->type))
304                                 s1 = emit_load(jd, iptr, src, REG_ITMP12_PACKED);
305                         else
306                                 s1 = emit_load(jd, iptr, src, REG_ITMP1);
307
308                         d = codegen_reg_of_var(iptr->opc, dst, s1);
309                 }
310
311                 if (s1 != d) {
312                         switch (src->type) {
313                         case TYPE_INT:
314                         case TYPE_ADR:
315                                 M_MOV(s1, d);
316                                 break;
317                         case TYPE_LNG:
318                                 M_LNGMOVE(s1, d);
319                                 break;
320                         case TYPE_FLT:
321                         case TYPE_DBL:
322 /*                              M_FMOV(s1, d); */
323                                 break;
324                         default:
325                                 vm_abort("emit_copy: unknown type %d", src->type);
326                         }
327                 }
328
329                 emit_store(jd, iptr, dst, d);
330         }
331 }
332
333
334 /* emit_branch *****************************************************************
335
336    Emits the code for conditional and unconditional branchs.
337
338 *******************************************************************************/
339
340 void emit_branch(codegendata *cd, s4 disp, s4 condition, s4 reg, u4 options)
341 {
342         s4 branchdisp;
343
344         /* ATTENTION: a displacement overflow cannot happen */
345
346         /* check which branch to generate */
347
348         if (condition == BRANCH_UNCONDITIONAL) {
349
350                 /* calculate the different displacements */
351
352                 branchdisp = disp - BRANCH_UNCONDITIONAL_SIZE;
353
354                 M_JMP_IMM(branchdisp);
355         }
356         else {
357                 /* calculate the different displacements */
358
359                 branchdisp = disp - BRANCH_CONDITIONAL_SIZE;
360
361                 switch (condition) {
362                 case BRANCH_EQ:
363                         M_BEQ(branchdisp);
364                         break;
365                 case BRANCH_NE:
366                         M_BNE(branchdisp);
367                         break;
368                 case BRANCH_LT:
369                         M_BLT(branchdisp);
370                         break;
371                 case BRANCH_GE:
372                         M_BGE(branchdisp);
373                         break;
374                 case BRANCH_GT:
375                         M_BGT(branchdisp);
376                         break;
377                 case BRANCH_LE:
378                         M_BLE(branchdisp);
379                         break;
380                 case BRANCH_ULT:
381                         M_BB(branchdisp);
382                         break;
383                 case BRANCH_ULE:
384                         M_BBE(branchdisp);
385                         break;
386                 case BRANCH_UGE:
387                         M_BAE(branchdisp);
388                         break;
389                 case BRANCH_UGT:
390                         M_BA(branchdisp);
391                         break;
392                 default:
393                         vm_abort("emit_branch: unknown condition %d", condition);
394                 }
395         }
396 }
397
398
399 /* emit_arithmetic_check *******************************************************
400
401    Emit an ArithmeticException check.
402
403 *******************************************************************************/
404
405 void emit_arithmetic_check(codegendata *cd, instruction *iptr, s4 reg)
406 {
407         if (INSTRUCTION_MUST_CHECK(iptr)) {
408                 M_TEST(reg);
409                 M_BNE(6);
410                 M_ALD_MEM(reg, TRAP_ArithmeticException);
411         }
412 }
413
414
415 /* emit_arrayindexoutofbounds_check ********************************************
416
417    Emit a ArrayIndexOutOfBoundsException check.
418
419 *******************************************************************************/
420
421 void emit_arrayindexoutofbounds_check(codegendata *cd, instruction *iptr, s4 s1, s4 s2)
422 {
423         if (INSTRUCTION_MUST_CHECK(iptr)) {
424         M_ILD(REG_ITMP3, s1, OFFSET(java_array_t, size));
425         M_CMP(REG_ITMP3, s2);
426         M_BB(6);
427                 M_ALD_MEM(s2, TRAP_ArrayIndexOutOfBoundsException);
428         }
429 }
430
431
432 /* emit_arraystore_check *******************************************************
433
434    Emit an ArrayStoreException check.
435
436 *******************************************************************************/
437
438 void emit_arraystore_check(codegendata *cd, instruction *iptr)
439 {
440         if (INSTRUCTION_MUST_CHECK(iptr)) {
441                 M_TEST(REG_RESULT);
442                 M_BNE(6);
443                 M_ALD_MEM(REG_RESULT, TRAP_ArrayStoreException);
444         }
445 }
446
447
448 /* emit_classcast_check ********************************************************
449
450    Emit a ClassCastException check.
451
452 *******************************************************************************/
453
454 void emit_classcast_check(codegendata *cd, instruction *iptr, s4 condition, s4 reg, s4 s1)
455 {
456         if (INSTRUCTION_MUST_CHECK(iptr)) {
457                 switch (condition) {
458                 case BRANCH_LE:
459                         M_BGT(6);
460                         break;
461                 case BRANCH_GE:
462                         M_BLT(6);
463                         break;
464                 case BRANCH_EQ:
465                         M_BNE(6);
466                         break;
467                 case BRANCH_NE:
468                         M_BEQ(6);
469                         break;
470                 case BRANCH_ULE:
471                         M_BBE(6);
472                         break;
473                 default:
474                         vm_abort("emit_classcast_check: unknown condition %d", condition);
475                 }
476                 M_ALD_MEM(s1, TRAP_ClassCastException);
477         }
478 }
479
480
481 /* emit_nullpointer_check ******************************************************
482
483    Emit a NullPointerException check.
484
485 *******************************************************************************/
486
487 void emit_nullpointer_check(codegendata *cd, instruction *iptr, s4 reg)
488 {
489         if (INSTRUCTION_MUST_CHECK(iptr)) {
490                 M_TEST(reg);
491                 M_BNE(6);
492                 M_ALD_MEM(reg, TRAP_NullPointerException);
493         }
494 }
495
496
497 /* emit_exception_check ********************************************************
498
499    Emit an Exception check.
500
501 *******************************************************************************/
502
503 void emit_exception_check(codegendata *cd, instruction *iptr)
504 {
505         if (INSTRUCTION_MUST_CHECK(iptr)) {
506                 M_TEST(REG_RESULT);
507                 M_BNE(6);
508                 M_ALD_MEM(REG_RESULT, TRAP_CHECK_EXCEPTION);
509         }
510 }
511
512
513 /* emit_trap_compiler **********************************************************
514
515    Emit a trap instruction which calls the JIT compiler.
516
517 *******************************************************************************/
518
519 void emit_trap_compiler(codegendata *cd)
520 {
521         M_ALD_MEM(REG_METHODPTR, TRAP_COMPILER);
522 }
523
524 /* emit_trap_countdown *********************************************************
525
526    Emit a countdown trap.
527
528    counter....absolute address of the counter variable
529
530 *******************************************************************************/
531
532 void emit_trap_countdown(codegendata *cd, s4 *counter)
533 {
534         M_ISUB_IMM_MEMABS(1, (s4) counter);
535         M_BNS(6);
536         M_ALD_MEM(REG_METHODPTR, TRAP_COUNTDOWN);
537 }
538
539 /* emit_trap *******************************************************************
540
541    Emit a trap instruction and return the original machine code.
542
543 *******************************************************************************/
544
545 uint32_t emit_trap(codegendata *cd)
546 {
547         uint16_t mcode;
548
549         /* Get machine code which is patched back in later. The
550            trap is 2 bytes long. */
551
552         mcode = *((uint16_t *) cd->mcodeptr);
553
554 #if 0
555         /* XXX this breaks GDB, so we disable it for now */
556         *(cd->mcodeptr++) = 0xcc;
557         M_INT3;
558 #else
559         M_UD2;
560 #endif
561
562         return (uint32_t) mcode;
563 }
564
565
566 /* emit_verbosecall_enter ******************************************************
567
568    Generates the code for the call trace.
569
570 *******************************************************************************/
571
572 #if !defined(NDEBUG)
573 void emit_verbosecall_enter(jitdata *jd)
574 {
575         methodinfo   *m;
576         codeinfo     *code;
577         codegendata  *cd;
578         registerdata *rd;
579         methoddesc   *md;
580         int32_t       stackframesize;
581         int           i;
582         int           align_off;             /* offset for alignment compensation */
583
584         if (!JITDATA_HAS_FLAG_VERBOSECALL(jd))
585                 return;
586
587         /* get required compiler data */
588
589         m    = jd->m;
590         code = jd->code;
591         cd   = jd->cd;
592         rd   = jd->rd;
593
594         md = m->parseddesc;
595
596         /* mark trace code */
597
598         M_NOP;
599
600         /* keep stack 16-byte aligned */
601
602         stackframesize = 2 + TMP_CNT;
603         ALIGN_2(stackframesize);
604
605         M_ASUB_IMM(stackframesize * 8, REG_SP);
606
607         /* save temporary registers for leaf methods */
608
609         if (code_is_leafmethod(code)) {
610                 for (i = 0; i < INT_TMP_CNT; i++)
611                         M_IST(rd->tmpintregs[i], REG_SP, (2 + i) * 8);
612         }
613
614         /* no argument registers to save */
615
616         align_off = cd->stackframesize ? 4 : 0;
617         M_AST_IMM(m, REG_SP, 0 * 4);
618         M_AST_IMM(0, REG_SP, 1 * 4);
619         M_AST(REG_SP, REG_SP, 2 * 4);
620         M_IADD_IMM_MEMBASE(stackframesize * 8 + cd->stackframesize * 8 + 4 + align_off, REG_SP, 2 * 4);
621         M_MOV_IMM(trace_java_call_enter, REG_ITMP1);
622         M_CALL(REG_ITMP1);
623
624         /* no argument registers to restore */
625
626         /* restore temporary registers for leaf methods */
627
628         if (code_is_leafmethod(code)) {
629                 for (i = 0; i < INT_TMP_CNT; i++)
630                         M_ILD(rd->tmpintregs[i], REG_SP, (2 + i) * 8);
631         }
632
633         M_AADD_IMM(stackframesize * 8, REG_SP);
634
635         /* mark trace code */
636
637         M_NOP;
638 }
639 #endif /* !defined(NDEBUG) */
640
641
642 /* emit_verbosecall_exit *******************************************************
643
644    Generates the code for the call trace.
645
646 *******************************************************************************/
647
648 #if !defined(NDEBUG)
649 void emit_verbosecall_exit(jitdata *jd)
650 {
651         methodinfo   *m;
652         codegendata  *cd;
653         registerdata *rd;
654         methoddesc   *md;
655
656         if (!JITDATA_HAS_FLAG_VERBOSECALL(jd))
657                 return;
658
659         /* get required compiler data */
660
661         m  = jd->m;
662         cd = jd->cd;
663         rd = jd->rd;
664
665         md = m->parseddesc;
666
667         /* mark trace code */
668
669         M_NOP;
670
671         /* keep stack 16-byte aligned */
672
673         M_ASUB_IMM(4 + 4 + 8, REG_SP);
674
675         /* save return value */
676
677         switch (md->returntype.type) {
678         case TYPE_ADR:
679         case TYPE_INT:
680                 M_IST(REG_RESULT, REG_SP, 2 * 4);
681                 break;
682         case TYPE_LNG:
683                 M_LST(REG_RESULT_PACKED, REG_SP, 2 * 4);
684                 break;
685         case TYPE_FLT:
686                 M_FSTNP(REG_NULL, REG_SP, 2 * 4);
687                 break;
688         case TYPE_DBL:
689                 M_DSTNP(REG_NULL, REG_SP, 2 * 4);
690                 break;
691         }
692
693         M_AST_IMM(m, REG_SP, 0 * 4);
694         M_AST(REG_SP, REG_SP, 1 * 4);
695         M_IADD_IMM_MEMBASE(2 * 4, REG_SP, 1 * 4);
696         M_MOV_IMM(trace_java_call_exit, REG_ITMP1);
697         M_CALL(REG_ITMP1);
698
699         /* restore return value */
700
701         switch (md->returntype.type) {
702         case TYPE_ADR:
703         case TYPE_INT:
704                 M_ILD(REG_RESULT, REG_SP, 2 * 4);
705                 break;
706         case TYPE_LNG:
707                 M_LLD(REG_RESULT_PACKED, REG_SP, 2 * 4);
708                 break;
709         }
710
711         M_AADD_IMM(4 + 4 + 8, REG_SP);
712
713         /* mark trace code */
714
715         M_NOP;
716 }
717 #endif /* !defined(NDEBUG) */
718
719
720 /* code generation functions **************************************************/
721
722 static void emit_membase(codegendata *cd, s4 basereg, s4 disp, s4 dreg)
723 {
724         if (basereg == ESP) {
725                 if (disp == 0) {
726                         emit_address_byte(0, dreg, ESP);
727                         emit_address_byte(0, ESP, ESP);
728                 }
729                 else if (IS_IMM8(disp)) {
730                         emit_address_byte(1, dreg, ESP);
731                         emit_address_byte(0, ESP, ESP);
732                         emit_imm8(disp);
733                 }
734                 else {
735                         emit_address_byte(2, dreg, ESP);
736                         emit_address_byte(0, ESP, ESP);
737                         emit_imm32(disp);
738                 }
739         }
740         else if ((disp == 0) && (basereg != EBP)) {
741                 emit_address_byte(0, dreg, basereg);
742         }
743         else if (IS_IMM8(disp)) {
744                 emit_address_byte(1, dreg, basereg);
745                 emit_imm8(disp);
746         }
747         else {
748                 emit_address_byte(2, dreg, basereg);
749                 emit_imm32(disp);
750         }
751 }
752
753
754 static void emit_membase32(codegendata *cd, s4 basereg, s4 disp, s4 dreg)
755 {
756         if (basereg == ESP) {
757                 emit_address_byte(2, dreg, ESP);
758                 emit_address_byte(0, ESP, ESP);
759                 emit_imm32(disp);
760         }
761         else {
762                 emit_address_byte(2, dreg, basereg);
763                 emit_imm32(disp);
764         }
765 }
766
767
768 static void emit_memindex(codegendata *cd, s4 reg, s4 disp, s4 basereg, s4 indexreg, s4 scale)
769 {
770         if (basereg == -1) {
771                 emit_address_byte(0, reg, 4);
772                 emit_address_byte(scale, indexreg, 5);
773                 emit_imm32(disp);
774         }
775         else if ((disp == 0) && (basereg != EBP)) {
776                 emit_address_byte(0, reg, 4);
777                 emit_address_byte(scale, indexreg, basereg);
778         }
779         else if (IS_IMM8(disp)) {
780                 emit_address_byte(1, reg, 4);
781                 emit_address_byte(scale, indexreg, basereg);
782                 emit_imm8(disp);
783         }
784         else {
785                 emit_address_byte(2, reg, 4);
786                 emit_address_byte(scale, indexreg, basereg);
787                 emit_imm32(disp);
788         }
789 }
790
791
792 /* low-level code emitter functions *******************************************/
793
794 void emit_mov_reg_reg(codegendata *cd, s4 reg, s4 dreg)
795 {
796         COUNT(count_mov_reg_reg);
797         *(cd->mcodeptr++) = 0x89;
798         emit_reg((reg),(dreg));
799 }
800
801
802 void emit_mov_imm_reg(codegendata *cd, s4 imm, s4 reg)
803 {
804         *(cd->mcodeptr++) = 0xb8 + ((reg) & 0x07);
805         emit_imm32((imm));
806 }
807
808
809 void emit_movb_imm_reg(codegendata *cd, s4 imm, s4 reg)
810 {
811         *(cd->mcodeptr++) = 0xc6;
812         emit_reg(0,(reg));
813         emit_imm8((imm));
814 }
815
816
817 void emit_mov_membase_reg(codegendata *cd, s4 basereg, s4 disp, s4 reg)
818 {
819         COUNT(count_mov_mem_reg);
820         *(cd->mcodeptr++) = 0x8b;
821         emit_membase(cd, (basereg),(disp),(reg));
822 }
823
824
825 /*
826  * this one is for INVOKEVIRTUAL/INVOKEINTERFACE to have a
827  * constant membase immediate length of 32bit
828  */
829 void emit_mov_membase32_reg(codegendata *cd, s4 basereg, s4 disp, s4 reg)
830 {
831         COUNT(count_mov_mem_reg);
832         *(cd->mcodeptr++) = 0x8b;
833         emit_membase32(cd, (basereg),(disp),(reg));
834 }
835
836
837 void emit_mov_reg_membase(codegendata *cd, s4 reg, s4 basereg, s4 disp)
838 {
839         COUNT(count_mov_reg_mem);
840         *(cd->mcodeptr++) = 0x89;
841         emit_membase(cd, (basereg),(disp),(reg));
842 }
843
844
845 void emit_mov_reg_membase32(codegendata *cd, s4 reg, s4 basereg, s4 disp)
846 {
847         COUNT(count_mov_reg_mem);
848         *(cd->mcodeptr++) = 0x89;
849         emit_membase32(cd, (basereg),(disp),(reg));
850 }
851
852
853 void emit_mov_memindex_reg(codegendata *cd, s4 disp, s4 basereg, s4 indexreg, s4 scale, s4 reg)
854 {
855         COUNT(count_mov_mem_reg);
856         *(cd->mcodeptr++) = 0x8b;
857         emit_memindex(cd, (reg),(disp),(basereg),(indexreg),(scale));
858 }
859
860
861 void emit_mov_reg_memindex(codegendata *cd, s4 reg, s4 disp, s4 basereg, s4 indexreg, s4 scale)
862 {
863         COUNT(count_mov_reg_mem);
864         *(cd->mcodeptr++) = 0x89;
865         emit_memindex(cd, (reg),(disp),(basereg),(indexreg),(scale));
866 }
867
868
869 void emit_movw_reg_memindex(codegendata *cd, s4 reg, s4 disp, s4 basereg, s4 indexreg, s4 scale)
870 {
871         COUNT(count_mov_reg_mem);
872         *(cd->mcodeptr++) = 0x66;
873         *(cd->mcodeptr++) = 0x89;
874         emit_memindex(cd, (reg),(disp),(basereg),(indexreg),(scale));
875 }
876
877
878 void emit_movb_reg_memindex(codegendata *cd, s4 reg, s4 disp, s4 basereg, s4 indexreg, s4 scale)
879 {
880         COUNT(count_mov_reg_mem);
881         *(cd->mcodeptr++) = 0x88;
882         emit_memindex(cd, (reg),(disp),(basereg),(indexreg),(scale));
883 }
884
885
886 void emit_mov_reg_mem(codegendata *cd, s4 reg, s4 mem)
887 {
888         COUNT(count_mov_reg_mem);
889         *(cd->mcodeptr++) = 0x89;
890         emit_mem((reg),(mem));
891 }
892
893
894 void emit_mov_mem_reg(codegendata *cd, s4 mem, s4 dreg)
895 {
896         COUNT(count_mov_mem_reg);
897         *(cd->mcodeptr++) = 0x8b;
898         emit_mem((dreg),(mem));
899 }
900
901
902 void emit_mov_imm_mem(codegendata *cd, s4 imm, s4 mem)
903 {
904         *(cd->mcodeptr++) = 0xc7;
905         emit_mem(0, mem);
906         emit_imm32(imm);
907 }
908
909
910 void emit_mov_imm_membase(codegendata *cd, s4 imm, s4 basereg, s4 disp)
911 {
912         *(cd->mcodeptr++) = 0xc7;
913         emit_membase(cd, (basereg),(disp),0);
914         emit_imm32((imm));
915 }
916
917
918 void emit_mov_imm_membase32(codegendata *cd, s4 imm, s4 basereg, s4 disp)
919 {
920         *(cd->mcodeptr++) = 0xc7;
921         emit_membase32(cd, (basereg),(disp),0);
922         emit_imm32((imm));
923 }
924
925
926 void emit_movb_imm_membase(codegendata *cd, s4 imm, s4 basereg, s4 disp)
927 {
928         *(cd->mcodeptr++) = 0xc6;
929         emit_membase(cd, (basereg),(disp),0);
930         emit_imm8((imm));
931 }
932
933
934 void emit_movsbl_reg_reg(codegendata *cd, s4 a, s4 b)
935 {
936         assert(a < 4);                     /* Can only operate on al, bl, cl, dl. */
937         *(cd->mcodeptr++) = 0x0f;
938         *(cd->mcodeptr++) = 0xbe;
939         emit_reg((b),(a));
940 }
941
942
943 void emit_movsbl_memindex_reg(codegendata *cd, s4 disp, s4 basereg, s4 indexreg, s4 scale, s4 reg)
944 {
945         COUNT(count_mov_mem_reg);
946         *(cd->mcodeptr++) = 0x0f;
947         *(cd->mcodeptr++) = 0xbe;
948         emit_memindex(cd, (reg),(disp),(basereg),(indexreg),(scale));
949 }
950
951
952 void emit_movswl_reg_reg(codegendata *cd, s4 a, s4 b)
953 {
954         *(cd->mcodeptr++) = 0x0f;
955         *(cd->mcodeptr++) = 0xbf;
956         emit_reg((b),(a));
957 }
958
959
960 void emit_movswl_memindex_reg(codegendata *cd, s4 disp, s4 basereg, s4 indexreg, s4 scale, s4 reg)
961 {
962         COUNT(count_mov_mem_reg);
963         *(cd->mcodeptr++) = 0x0f;
964         *(cd->mcodeptr++) = 0xbf;
965         emit_memindex(cd, (reg),(disp),(basereg),(indexreg),(scale));
966 }
967
968
969 void emit_movzbl_reg_reg(codegendata *cd, s4 a, s4 b)
970 {
971         assert(a < 4);                     /* Can only operate on al, bl, cl, dl. */
972         *(cd->mcodeptr++) = 0x0f;
973         *(cd->mcodeptr++) = 0xb6;
974         emit_reg((b),(a));
975 }
976
977
978 void emit_movzwl_reg_reg(codegendata *cd, s4 a, s4 b)
979 {
980         *(cd->mcodeptr++) = 0x0f;
981         *(cd->mcodeptr++) = 0xb7;
982         emit_reg((b),(a));
983 }
984
985
986 void emit_movzwl_memindex_reg(codegendata *cd, s4 disp, s4 basereg, s4 indexreg, s4 scale, s4 reg)
987 {
988         COUNT(count_mov_mem_reg);
989         *(cd->mcodeptr++) = 0x0f;
990         *(cd->mcodeptr++) = 0xb7;
991         emit_memindex(cd, (reg),(disp),(basereg),(indexreg),(scale));
992 }
993
994
995 void emit_mov_imm_memindex(codegendata *cd, s4 imm, s4 disp, s4 basereg, s4 indexreg, s4 scale)
996 {
997         *(cd->mcodeptr++) = 0xc7;
998         emit_memindex(cd, 0,(disp),(basereg),(indexreg),(scale));
999         emit_imm32((imm));
1000 }
1001
1002
1003 void emit_movw_imm_memindex(codegendata *cd, s4 imm, s4 disp, s4 basereg, s4 indexreg, s4 scale)
1004 {
1005         *(cd->mcodeptr++) = 0x66;
1006         *(cd->mcodeptr++) = 0xc7;
1007         emit_memindex(cd, 0,(disp),(basereg),(indexreg),(scale));
1008         emit_imm16((imm));
1009 }
1010
1011
1012 void emit_movb_imm_memindex(codegendata *cd, s4 imm, s4 disp, s4 basereg, s4 indexreg, s4 scale)
1013 {
1014         *(cd->mcodeptr++) = 0xc6;
1015         emit_memindex(cd, 0,(disp),(basereg),(indexreg),(scale));
1016         emit_imm8((imm));
1017 }
1018
1019
1020 /*
1021  * alu operations
1022  */
1023 void emit_alu_reg_reg(codegendata *cd, s4 opc, s4 reg, s4 dreg)
1024 {
1025         *(cd->mcodeptr++) = (((u1) (opc)) << 3) + 1;
1026         emit_reg((reg),(dreg));
1027 }
1028
1029
1030 void emit_alu_reg_membase(codegendata *cd, s4 opc, s4 reg, s4 basereg, s4 disp)
1031 {
1032         *(cd->mcodeptr++) = (((u1) (opc)) << 3) + 1;
1033         emit_membase(cd, (basereg),(disp),(reg));
1034 }
1035
1036
1037 void emit_alu_membase_reg(codegendata *cd, s4 opc, s4 basereg, s4 disp, s4 reg)
1038 {
1039         *(cd->mcodeptr++) = (((u1) (opc)) << 3) + 3;
1040         emit_membase(cd, (basereg),(disp),(reg));
1041 }
1042
1043
1044 void emit_alu_imm_reg(codegendata *cd, s4 opc, s4 imm, s4 dreg)
1045 {
1046         if (IS_IMM8(imm)) { 
1047                 *(cd->mcodeptr++) = 0x83;
1048                 emit_reg((opc),(dreg));
1049                 emit_imm8((imm));
1050         } else { 
1051                 *(cd->mcodeptr++) = 0x81;
1052                 emit_reg((opc),(dreg));
1053                 emit_imm32((imm));
1054         } 
1055 }
1056
1057
1058 void emit_alu_imm32_reg(codegendata *cd, s4 opc, s4 imm, s4 dreg)
1059 {
1060         *(cd->mcodeptr++) = 0x81;
1061         emit_reg((opc),(dreg));
1062         emit_imm32((imm));
1063 }
1064
1065
1066 void emit_alu_imm_membase(codegendata *cd, s4 opc, s4 imm, s4 basereg, s4 disp)
1067 {
1068         if (IS_IMM8(imm)) { 
1069                 *(cd->mcodeptr++) = 0x83;
1070                 emit_membase(cd, (basereg),(disp),(opc));
1071                 emit_imm8((imm));
1072         } else { 
1073                 *(cd->mcodeptr++) = 0x81;
1074                 emit_membase(cd, (basereg),(disp),(opc));
1075                 emit_imm32((imm));
1076         } 
1077 }
1078
1079
1080 void emit_alu_imm_memabs(codegendata *cd, s4 opc, s4 imm, s4 disp)
1081 {
1082         if (IS_IMM8(imm)) { 
1083                 *(cd->mcodeptr++) = 0x83;
1084                 emit_mem(opc, disp);
1085                 emit_imm8((imm));
1086         } else { 
1087                 *(cd->mcodeptr++) = 0x81;
1088                 emit_mem(opc, disp);
1089                 emit_imm32((imm));
1090         }
1091 }
1092
1093 void emit_alu_memindex_reg(codegendata *cd, s4 opc, s4 disp, s4 basereg, s4 indexreg, s4 scale, s4 reg)
1094 {
1095         *(cd->mcodeptr++) = (((u1) (opc)) << 3) + 3;
1096         emit_memindex(cd, (reg),(disp),(basereg),(indexreg),(scale));
1097 }
1098
1099 void emit_test_reg_reg(codegendata *cd, s4 reg, s4 dreg)
1100 {
1101         *(cd->mcodeptr++) = 0x85;
1102         emit_reg((reg),(dreg));
1103 }
1104
1105
1106 void emit_test_imm_reg(codegendata *cd, s4 imm, s4 reg)
1107 {
1108         *(cd->mcodeptr++) = 0xf7;
1109         emit_reg(0,(reg));
1110         emit_imm32((imm));
1111 }
1112
1113
1114
1115 /*
1116  * inc, dec operations
1117  */
1118 void emit_inc_reg(codegendata *cd, s4 reg)
1119 {
1120         *(cd->mcodeptr++) = 0xff;
1121         emit_reg(0,(reg));
1122 }
1123
1124 void emit_dec_mem(codegendata *cd, s4 mem)
1125 {
1126         *(cd->mcodeptr++) = 0xff;
1127         emit_mem(1,(mem));
1128 }
1129
1130
1131 void emit_imul_reg_reg(codegendata *cd, s4 reg, s4 dreg)
1132 {
1133         *(cd->mcodeptr++) = 0x0f;
1134         *(cd->mcodeptr++) = 0xaf;
1135         emit_reg((dreg),(reg));
1136 }
1137
1138
1139 void emit_imul_membase_reg(codegendata *cd, s4 basereg, s4 disp, s4 dreg)
1140 {
1141         *(cd->mcodeptr++) = 0x0f;
1142         *(cd->mcodeptr++) = 0xaf;
1143         emit_membase(cd, (basereg),(disp),(dreg));
1144 }
1145
1146
1147 void emit_imul_imm_reg(codegendata *cd, s4 imm, s4 dreg)
1148 {
1149         if (IS_IMM8((imm))) { 
1150                 *(cd->mcodeptr++) = 0x6b;
1151                 emit_reg(0,(dreg));
1152                 emit_imm8((imm));
1153         } else { 
1154                 *(cd->mcodeptr++) = 0x69;
1155                 emit_reg(0,(dreg));
1156                 emit_imm32((imm));
1157         } 
1158 }
1159
1160
1161 void emit_imul_imm_reg_reg(codegendata *cd, s4 imm, s4 reg, s4 dreg)
1162 {
1163         if (IS_IMM8((imm))) { 
1164                 *(cd->mcodeptr++) = 0x6b;
1165                 emit_reg((dreg),(reg));
1166                 emit_imm8((imm));
1167         } else { 
1168                 *(cd->mcodeptr++) = 0x69;
1169                 emit_reg((dreg),(reg));
1170                 emit_imm32((imm));
1171         } 
1172 }
1173
1174
1175 void emit_imul_imm_membase_reg(codegendata *cd, s4 imm, s4 basereg, s4 disp, s4 dreg)
1176 {
1177         if (IS_IMM8((imm))) {
1178                 *(cd->mcodeptr++) = 0x6b;
1179                 emit_membase(cd, (basereg),(disp),(dreg));
1180                 emit_imm8((imm));
1181         } else {
1182                 *(cd->mcodeptr++) = 0x69;
1183                 emit_membase(cd, (basereg),(disp),(dreg));
1184                 emit_imm32((imm));
1185         }
1186 }
1187
1188
1189 void emit_mul_reg(codegendata *cd, s4 reg)
1190 {
1191         *(cd->mcodeptr++) = 0xf7;
1192         emit_reg(4, reg);
1193 }
1194
1195
1196 void emit_mul_membase(codegendata *cd, s4 basereg, s4 disp)
1197 {
1198         *(cd->mcodeptr++) = 0xf7;
1199         emit_membase(cd, (basereg),(disp),4);
1200 }
1201
1202
1203 void emit_idiv_reg(codegendata *cd, s4 reg)
1204 {
1205         *(cd->mcodeptr++) = 0xf7;
1206         emit_reg(7,(reg));
1207 }
1208
1209
1210
1211 /*
1212  * shift ops
1213  */
1214 void emit_shift_reg(codegendata *cd, s4 opc, s4 reg)
1215 {
1216         *(cd->mcodeptr++) = 0xd3;
1217         emit_reg((opc),(reg));
1218 }
1219
1220
1221 void emit_shift_imm_reg(codegendata *cd, s4 opc, s4 imm, s4 dreg)
1222 {
1223         if ((imm) == 1) {
1224                 *(cd->mcodeptr++) = 0xd1;
1225                 emit_reg((opc),(dreg));
1226         } else {
1227                 *(cd->mcodeptr++) = 0xc1;
1228                 emit_reg((opc),(dreg));
1229                 emit_imm8((imm));
1230         }
1231 }
1232
1233
1234 void emit_shld_reg_reg(codegendata *cd, s4 reg, s4 dreg)
1235 {
1236         *(cd->mcodeptr++) = 0x0f;
1237         *(cd->mcodeptr++) = 0xa5;
1238         emit_reg((reg),(dreg));
1239 }
1240
1241
1242 void emit_shld_imm_reg_reg(codegendata *cd, s4 imm, s4 reg, s4 dreg)
1243 {
1244         *(cd->mcodeptr++) = 0x0f;
1245         *(cd->mcodeptr++) = 0xa4;
1246         emit_reg((reg),(dreg));
1247         emit_imm8((imm));
1248 }
1249
1250
1251 void emit_shld_reg_membase(codegendata *cd, s4 reg, s4 basereg, s4 disp)
1252 {
1253         *(cd->mcodeptr++) = 0x0f;
1254         *(cd->mcodeptr++) = 0xa5;
1255         emit_membase(cd, (basereg),(disp),(reg));
1256 }
1257
1258
1259 void emit_shrd_reg_reg(codegendata *cd, s4 reg, s4 dreg)
1260 {
1261         *(cd->mcodeptr++) = 0x0f;
1262         *(cd->mcodeptr++) = 0xad;
1263         emit_reg((reg),(dreg));
1264 }
1265
1266
1267 void emit_shrd_imm_reg_reg(codegendata *cd, s4 imm, s4 reg, s4 dreg)
1268 {
1269         *(cd->mcodeptr++) = 0x0f;
1270         *(cd->mcodeptr++) = 0xac;
1271         emit_reg((reg),(dreg));
1272         emit_imm8((imm));
1273 }
1274
1275
1276 void emit_shrd_reg_membase(codegendata *cd, s4 reg, s4 basereg, s4 disp)
1277 {
1278         *(cd->mcodeptr++) = 0x0f;
1279         *(cd->mcodeptr++) = 0xad;
1280         emit_membase(cd, (basereg),(disp),(reg));
1281 }
1282
1283
1284
1285 /*
1286  * jump operations
1287  */
1288 void emit_jmp_imm(codegendata *cd, s4 imm)
1289 {
1290         *(cd->mcodeptr++) = 0xe9;
1291         emit_imm32((imm));
1292 }
1293
1294
1295 void emit_jmp_reg(codegendata *cd, s4 reg)
1296 {
1297         *(cd->mcodeptr++) = 0xff;
1298         emit_reg(4,(reg));
1299 }
1300
1301
1302 void emit_jcc(codegendata *cd, s4 opc, s4 imm)
1303 {
1304         *(cd->mcodeptr++) = 0x0f;
1305         *(cd->mcodeptr++) =  0x80 + (u1) (opc);
1306         emit_imm32((imm));
1307 }
1308
1309
1310
1311 /*
1312  * conditional set operations
1313  */
1314 void emit_setcc_reg(codegendata *cd, s4 opc, s4 reg)
1315 {
1316         assert(reg < 4);                     /* Can only operate on al, bl, cl, dl. */
1317         *(cd->mcodeptr++) = 0x0f;
1318         *(cd->mcodeptr++) = 0x90 + (u1) (opc);
1319         emit_reg(0,(reg));
1320 }
1321
1322
1323 void emit_setcc_membase(codegendata *cd, s4 opc, s4 basereg, s4 disp)
1324 {
1325         *(cd->mcodeptr++) = 0x0f;
1326         *(cd->mcodeptr++) =  0x90 + (u1) (opc);
1327         emit_membase(cd, (basereg),(disp),0);
1328 }
1329
1330
1331 void emit_xadd_reg_mem(codegendata *cd, s4 reg, s4 mem)
1332 {
1333         *(cd->mcodeptr++) = 0x0f;
1334         *(cd->mcodeptr++) = 0xc1;
1335         emit_mem((reg),(mem));
1336 }
1337
1338
1339 void emit_neg_reg(codegendata *cd, s4 reg)
1340 {
1341         *(cd->mcodeptr++) = 0xf7;
1342         emit_reg(3,(reg));
1343 }
1344
1345
1346
1347 void emit_push_imm(codegendata *cd, s4 imm)
1348 {
1349         *(cd->mcodeptr++) = 0x68;
1350         emit_imm32((imm));
1351 }
1352
1353
1354 void emit_pop_reg(codegendata *cd, s4 reg)
1355 {
1356         *(cd->mcodeptr++) = 0x58 + (0x07 & (u1) (reg));
1357 }
1358
1359
1360 void emit_push_reg(codegendata *cd, s4 reg)
1361 {
1362         *(cd->mcodeptr++) = 0x50 + (0x07 & (u1) (reg));
1363 }
1364
1365
1366 void emit_lock(codegendata *cd)
1367 {
1368         *(cd->mcodeptr++) = 0xf0;
1369 }
1370
1371
1372 /*
1373  * call instructions
1374  */
1375 void emit_call_reg(codegendata *cd, s4 reg)
1376 {
1377         *(cd->mcodeptr++) = 0xff;
1378         emit_reg(2,(reg));
1379 }
1380
1381
1382 void emit_call_imm(codegendata *cd, s4 imm)
1383 {
1384         *(cd->mcodeptr++) = 0xe8;
1385         emit_imm32((imm));
1386 }
1387
1388
1389
1390 /*
1391  * floating point instructions
1392  */
1393 void emit_fld1(codegendata *cd)
1394 {
1395         *(cd->mcodeptr++) = 0xd9;
1396         *(cd->mcodeptr++) = 0xe8;
1397 }
1398
1399
1400 void emit_fldz(codegendata *cd)
1401 {
1402         *(cd->mcodeptr++) = 0xd9;
1403         *(cd->mcodeptr++) = 0xee;
1404 }
1405
1406
1407 void emit_fld_reg(codegendata *cd, s4 reg)
1408 {
1409         *(cd->mcodeptr++) = 0xd9;
1410         *(cd->mcodeptr++) = 0xc0 + (0x07 & (u1) (reg));
1411 }
1412
1413
1414 void emit_flds_membase(codegendata *cd, s4 basereg, s4 disp)
1415 {
1416         *(cd->mcodeptr++) = 0xd9;
1417         emit_membase(cd, (basereg),(disp),0);
1418 }
1419
1420
1421 void emit_flds_membase32(codegendata *cd, s4 basereg, s4 disp)
1422 {
1423         *(cd->mcodeptr++) = 0xd9;
1424         emit_membase32(cd, (basereg),(disp),0);
1425 }
1426
1427
1428 void emit_fldl_membase(codegendata *cd, s4 basereg, s4 disp)
1429 {
1430         *(cd->mcodeptr++) = 0xdd;
1431         emit_membase(cd, (basereg),(disp),0);
1432 }
1433
1434
1435 void emit_fldl_membase32(codegendata *cd, s4 basereg, s4 disp)
1436 {
1437         *(cd->mcodeptr++) = 0xdd;
1438         emit_membase32(cd, (basereg),(disp),0);
1439 }
1440
1441
1442 void emit_fldt_membase(codegendata *cd, s4 basereg, s4 disp)
1443 {
1444         *(cd->mcodeptr++) = 0xdb;
1445         emit_membase(cd, (basereg),(disp),5);
1446 }
1447
1448
1449 void emit_flds_memindex(codegendata *cd, s4 disp, s4 basereg, s4 indexreg, s4 scale)
1450 {
1451         *(cd->mcodeptr++) = 0xd9;
1452         emit_memindex(cd, 0,(disp),(basereg),(indexreg),(scale));
1453 }
1454
1455
1456 void emit_fldl_memindex(codegendata *cd, s4 disp, s4 basereg, s4 indexreg, s4 scale)
1457 {
1458         *(cd->mcodeptr++) = 0xdd;
1459         emit_memindex(cd, 0,(disp),(basereg),(indexreg),(scale));
1460 }
1461
1462
1463 void emit_flds_mem(codegendata *cd, s4 mem)
1464 {
1465         *(cd->mcodeptr++) = 0xd9;
1466         emit_mem(0,(mem));
1467 }
1468
1469
1470 void emit_fldl_mem(codegendata *cd, s4 mem)
1471 {
1472         *(cd->mcodeptr++) = 0xdd;
1473         emit_mem(0,(mem));
1474 }
1475
1476
1477 void emit_fildl_membase(codegendata *cd, s4 basereg, s4 disp)
1478 {
1479         *(cd->mcodeptr++) = 0xdb;
1480         emit_membase(cd, (basereg),(disp),0);
1481 }
1482
1483
1484 void emit_fildll_membase(codegendata *cd, s4 basereg, s4 disp)
1485 {
1486         *(cd->mcodeptr++) = 0xdf;
1487         emit_membase(cd, (basereg),(disp),5);
1488 }
1489
1490
1491 void emit_fst_reg(codegendata *cd, s4 reg)
1492 {
1493         *(cd->mcodeptr++) = 0xdd;
1494         *(cd->mcodeptr++) = 0xd0 + (0x07 & (u1) (reg));
1495 }
1496
1497
1498 void emit_fsts_membase(codegendata *cd, s4 basereg, s4 disp)
1499 {
1500         *(cd->mcodeptr++) = 0xd9;
1501         emit_membase(cd, (basereg),(disp),2);
1502 }
1503
1504
1505 void emit_fstl_membase(codegendata *cd, s4 basereg, s4 disp)
1506 {
1507         *(cd->mcodeptr++) = 0xdd;
1508         emit_membase(cd, (basereg),(disp),2);
1509 }
1510
1511
1512 void emit_fsts_memindex(codegendata *cd, s4 disp, s4 basereg, s4 indexreg, s4 scale)
1513 {
1514         *(cd->mcodeptr++) = 0xd9;
1515         emit_memindex(cd, 2,(disp),(basereg),(indexreg),(scale));
1516 }
1517
1518
1519 void emit_fstl_memindex(codegendata *cd, s4 disp, s4 basereg, s4 indexreg, s4 scale)
1520 {
1521         *(cd->mcodeptr++) = 0xdd;
1522         emit_memindex(cd, 2,(disp),(basereg),(indexreg),(scale));
1523 }
1524
1525
1526 void emit_fstp_reg(codegendata *cd, s4 reg)
1527 {
1528         *(cd->mcodeptr++) = 0xdd;
1529         *(cd->mcodeptr++) = 0xd8 + (0x07 & (u1) (reg));
1530 }
1531
1532
1533 void emit_fstps_membase(codegendata *cd, s4 basereg, s4 disp)
1534 {
1535         *(cd->mcodeptr++) = 0xd9;
1536         emit_membase(cd, (basereg),(disp),3);
1537 }
1538
1539
1540 void emit_fstps_membase32(codegendata *cd, s4 basereg, s4 disp)
1541 {
1542         *(cd->mcodeptr++) = 0xd9;
1543         emit_membase32(cd, (basereg),(disp),3);
1544 }
1545
1546
1547 void emit_fstpl_membase(codegendata *cd, s4 basereg, s4 disp)
1548 {
1549         *(cd->mcodeptr++) = 0xdd;
1550         emit_membase(cd, (basereg),(disp),3);
1551 }
1552
1553
1554 void emit_fstpl_membase32(codegendata *cd, s4 basereg, s4 disp)
1555 {
1556         *(cd->mcodeptr++) = 0xdd;
1557         emit_membase32(cd, (basereg),(disp),3);
1558 }
1559
1560
1561 void emit_fstpt_membase(codegendata *cd, s4 basereg, s4 disp)
1562 {
1563         *(cd->mcodeptr++) = 0xdb;
1564         emit_membase(cd, (basereg),(disp),7);
1565 }
1566
1567
1568 void emit_fstps_memindex(codegendata *cd, s4 disp, s4 basereg, s4 indexreg, s4 scale)
1569 {
1570         *(cd->mcodeptr++) = 0xd9;
1571         emit_memindex(cd, 3,(disp),(basereg),(indexreg),(scale));
1572 }
1573
1574
1575 void emit_fstpl_memindex(codegendata *cd, s4 disp, s4 basereg, s4 indexreg, s4 scale)
1576 {
1577         *(cd->mcodeptr++) = 0xdd;
1578         emit_memindex(cd, 3,(disp),(basereg),(indexreg),(scale));
1579 }
1580
1581
1582 void emit_fstps_mem(codegendata *cd, s4 mem)
1583 {
1584         *(cd->mcodeptr++) = 0xd9;
1585         emit_mem(3,(mem));
1586 }
1587
1588
1589 void emit_fstpl_mem(codegendata *cd, s4 mem)
1590 {
1591         *(cd->mcodeptr++) = 0xdd;
1592         emit_mem(3,(mem));
1593 }
1594
1595
1596 void emit_fistl_membase(codegendata *cd, s4 basereg, s4 disp)
1597 {
1598         *(cd->mcodeptr++) = 0xdb;
1599         emit_membase(cd, (basereg),(disp),2);
1600 }
1601
1602
1603 void emit_fistpl_membase(codegendata *cd, s4 basereg, s4 disp)
1604 {
1605         *(cd->mcodeptr++) = 0xdb;
1606         emit_membase(cd, (basereg),(disp),3);
1607 }
1608
1609
1610 void emit_fistpll_membase(codegendata *cd, s4 basereg, s4 disp)
1611 {
1612         *(cd->mcodeptr++) = 0xdf;
1613         emit_membase(cd, (basereg),(disp),7);
1614 }
1615
1616
1617 void emit_fchs(codegendata *cd)
1618 {
1619         *(cd->mcodeptr++) = 0xd9;
1620         *(cd->mcodeptr++) = 0xe0;
1621 }
1622
1623
1624 void emit_faddp(codegendata *cd)
1625 {
1626         *(cd->mcodeptr++) = 0xde;
1627         *(cd->mcodeptr++) = 0xc1;
1628 }
1629
1630
1631 void emit_fadd_reg_st(codegendata *cd, s4 reg)
1632 {
1633         *(cd->mcodeptr++) = 0xd8;
1634         *(cd->mcodeptr++) = 0xc0 + (0x0f & (u1) (reg));
1635 }
1636
1637
1638 void emit_fadd_st_reg(codegendata *cd, s4 reg)
1639 {
1640         *(cd->mcodeptr++) = 0xdc;
1641         *(cd->mcodeptr++) = 0xc0 + (0x0f & (u1) (reg));
1642 }
1643
1644
1645 void emit_faddp_st_reg(codegendata *cd, s4 reg)
1646 {
1647         *(cd->mcodeptr++) = 0xde;
1648         *(cd->mcodeptr++) = 0xc0 + (0x0f & (u1) (reg));
1649 }
1650
1651
1652 void emit_fadds_membase(codegendata *cd, s4 basereg, s4 disp)
1653 {
1654         *(cd->mcodeptr++) = 0xd8;
1655         emit_membase(cd, (basereg),(disp),0);
1656 }
1657
1658
1659 void emit_faddl_membase(codegendata *cd, s4 basereg, s4 disp)
1660 {
1661         *(cd->mcodeptr++) = 0xdc;
1662         emit_membase(cd, (basereg),(disp),0);
1663 }
1664
1665
1666 void emit_fsub_reg_st(codegendata *cd, s4 reg)
1667 {
1668         *(cd->mcodeptr++) = 0xd8;
1669         *(cd->mcodeptr++) = 0xe0 + (0x07 & (u1) (reg));
1670 }
1671
1672
1673 void emit_fsub_st_reg(codegendata *cd, s4 reg)
1674 {
1675         *(cd->mcodeptr++) = 0xdc;
1676         *(cd->mcodeptr++) = 0xe8 + (0x07 & (u1) (reg));
1677 }
1678
1679
1680 void emit_fsubp_st_reg(codegendata *cd, s4 reg)
1681 {
1682         *(cd->mcodeptr++) = 0xde;
1683         *(cd->mcodeptr++) = 0xe8 + (0x07 & (u1) (reg));
1684 }
1685
1686
1687 void emit_fsubp(codegendata *cd)
1688 {
1689         *(cd->mcodeptr++) = 0xde;
1690         *(cd->mcodeptr++) = 0xe9;
1691 }
1692
1693
1694 void emit_fsubs_membase(codegendata *cd, s4 basereg, s4 disp)
1695 {
1696         *(cd->mcodeptr++) = 0xd8;
1697         emit_membase(cd, (basereg),(disp),4);
1698 }
1699
1700
1701 void emit_fsubl_membase(codegendata *cd, s4 basereg, s4 disp)
1702 {
1703         *(cd->mcodeptr++) = 0xdc;
1704         emit_membase(cd, (basereg),(disp),4);
1705 }
1706
1707
1708 void emit_fmul_reg_st(codegendata *cd, s4 reg)
1709 {
1710         *(cd->mcodeptr++) = 0xd8;
1711         *(cd->mcodeptr++) = 0xc8 + (0x07 & (u1) (reg));
1712 }
1713
1714
1715 void emit_fmul_st_reg(codegendata *cd, s4 reg)
1716 {
1717         *(cd->mcodeptr++) = 0xdc;
1718         *(cd->mcodeptr++) = 0xc8 + (0x07 & (u1) (reg));
1719 }
1720
1721
1722 void emit_fmulp(codegendata *cd)
1723 {
1724         *(cd->mcodeptr++) = 0xde;
1725         *(cd->mcodeptr++) = 0xc9;
1726 }
1727
1728
1729 void emit_fmulp_st_reg(codegendata *cd, s4 reg)
1730 {
1731         *(cd->mcodeptr++) = 0xde;
1732         *(cd->mcodeptr++) = 0xc8 + (0x07 & (u1) (reg));
1733 }
1734
1735
1736 void emit_fmuls_membase(codegendata *cd, s4 basereg, s4 disp)
1737 {
1738         *(cd->mcodeptr++) = 0xd8;
1739         emit_membase(cd, (basereg),(disp),1);
1740 }
1741
1742
1743 void emit_fmull_membase(codegendata *cd, s4 basereg, s4 disp)
1744 {
1745         *(cd->mcodeptr++) = 0xdc;
1746         emit_membase(cd, (basereg),(disp),1);
1747 }
1748
1749
1750 void emit_fdiv_reg_st(codegendata *cd, s4 reg)
1751 {
1752         *(cd->mcodeptr++) = 0xd8;
1753         *(cd->mcodeptr++) = 0xf0 + (0x07 & (u1) (reg));
1754 }
1755
1756
1757 void emit_fdiv_st_reg(codegendata *cd, s4 reg)
1758 {
1759         *(cd->mcodeptr++) = 0xdc;
1760         *(cd->mcodeptr++) = 0xf8 + (0x07 & (u1) (reg));
1761 }
1762
1763
1764 void emit_fdivp(codegendata *cd)
1765 {
1766         *(cd->mcodeptr++) = 0xde;
1767         *(cd->mcodeptr++) = 0xf9;
1768 }
1769
1770
1771 void emit_fdivp_st_reg(codegendata *cd, s4 reg)
1772 {
1773         *(cd->mcodeptr++) = 0xde;
1774         *(cd->mcodeptr++) = 0xf8 + (0x07 & (u1) (reg));
1775 }
1776
1777
1778 void emit_fxch(codegendata *cd)
1779 {
1780         *(cd->mcodeptr++) = 0xd9;
1781         *(cd->mcodeptr++) = 0xc9;
1782 }
1783
1784
1785 void emit_fxch_reg(codegendata *cd, s4 reg)
1786 {
1787         *(cd->mcodeptr++) = 0xd9;
1788         *(cd->mcodeptr++) = 0xc8 + (0x07 & (reg));
1789 }
1790
1791
1792 void emit_fprem(codegendata *cd)
1793 {
1794         *(cd->mcodeptr++) = 0xd9;
1795         *(cd->mcodeptr++) = 0xf8;
1796 }
1797
1798
1799 void emit_fprem1(codegendata *cd)
1800 {
1801         *(cd->mcodeptr++) = 0xd9;
1802         *(cd->mcodeptr++) = 0xf5;
1803 }
1804
1805
1806 void emit_fucom(codegendata *cd)
1807 {
1808         *(cd->mcodeptr++) = 0xdd;
1809         *(cd->mcodeptr++) = 0xe1;
1810 }
1811
1812
1813 void emit_fucom_reg(codegendata *cd, s4 reg)
1814 {
1815         *(cd->mcodeptr++) = 0xdd;
1816         *(cd->mcodeptr++) = 0xe0 + (0x07 & (u1) (reg));
1817 }
1818
1819
1820 void emit_fucomp_reg(codegendata *cd, s4 reg)
1821 {
1822         *(cd->mcodeptr++) = 0xdd;
1823         *(cd->mcodeptr++) = 0xe8 + (0x07 & (u1) (reg));
1824 }
1825
1826
1827 void emit_fucompp(codegendata *cd)
1828 {
1829         *(cd->mcodeptr++) = 0xda;
1830         *(cd->mcodeptr++) = 0xe9;
1831 }
1832
1833
1834 void emit_fnstsw(codegendata *cd)
1835 {
1836         *(cd->mcodeptr++) = 0xdf;
1837         *(cd->mcodeptr++) = 0xe0;
1838 }
1839
1840
1841 void emit_sahf(codegendata *cd)
1842 {
1843         *(cd->mcodeptr++) = 0x9e;
1844 }
1845
1846
1847 void emit_finit(codegendata *cd)
1848 {
1849         *(cd->mcodeptr++) = 0x9b;
1850         *(cd->mcodeptr++) = 0xdb;
1851         *(cd->mcodeptr++) = 0xe3;
1852 }
1853
1854
1855 void emit_fldcw_mem(codegendata *cd, s4 mem)
1856 {
1857         *(cd->mcodeptr++) = 0xd9;
1858         emit_mem(5,(mem));
1859 }
1860
1861
1862 void emit_fldcw_membase(codegendata *cd, s4 basereg, s4 disp)
1863 {
1864         *(cd->mcodeptr++) = 0xd9;
1865         emit_membase(cd, (basereg),(disp),5);
1866 }
1867
1868
1869 void emit_wait(codegendata *cd)
1870 {
1871         *(cd->mcodeptr++) = 0x9b;
1872 }
1873
1874
1875 void emit_ffree_reg(codegendata *cd, s4 reg)
1876 {
1877         *(cd->mcodeptr++) = 0xdd;
1878         *(cd->mcodeptr++) = 0xc0 + (0x07 & (u1) (reg));
1879 }
1880
1881
1882 void emit_fdecstp(codegendata *cd)
1883 {
1884         *(cd->mcodeptr++) = 0xd9;
1885         *(cd->mcodeptr++) = 0xf6;
1886 }
1887
1888
1889 void emit_fincstp(codegendata *cd)
1890 {
1891         *(cd->mcodeptr++) = 0xd9;
1892         *(cd->mcodeptr++) = 0xf7;
1893 }
1894
1895 #if defined(ENABLE_ESCAPE_CHECK)
1896 void emit_escape_check(codegendata *cd, s4 reg) {
1897         M_PUSH(reg);
1898         M_MOV_IMM(asm_escape_check, REG_ITMP3);
1899         M_CALL(REG_ITMP3);
1900         M_IADD_IMM(4, REG_SP);
1901 }
1902 #endif
1903
1904 /*
1905  * These are local overrides for various environment variables in Emacs.
1906  * Please do not remove this and leave it at the end of the file, where
1907  * Emacs will automagically detect them.
1908  * ---------------------------------------------------------------------
1909  * Local variables:
1910  * mode: c
1911  * indent-tabs-mode: t
1912  * c-basic-offset: 4
1913  * tab-width: 4
1914  * End:
1915  */