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