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