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