Merged revisions 7501-7598 via svnmerge from
[cacao.git] / src / vm / jit / s390 / emit.c
1 /* src/vm/jit/x86_64/emit.c - x86_64 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    $Id: emit.c 7581 2007-03-26 07:23:16Z pm $
30
31 */
32
33 #include <assert.h>
34
35 #include "config.h"
36
37 #include "vm/types.h"
38
39 #include "md-abi.h"
40
41 #include "vm/jit/s390/codegen.h"
42 #include "vm/jit/s390/emit.h"
43
44 #if defined(ENABLE_THREADS)
45 # include "threads/native/lock.h"
46 #endif
47
48 #include "vm/builtin.h"
49 #include "vm/jit/abi-asm.h"
50 #include "vm/jit/asmpart.h"
51 #include "vm/jit/codegen-common.h"
52 #include "vm/jit/emit-common.h"
53 #include "vm/jit/jit.h"
54 #include "vm/jit/replace.h"
55 #include "vm/global.h"
56 #include "mm/memory.h"
57
58 #define __PORTED__
59
60 /* emit_load *******************************************************************
61
62    Emits a possible load of an operand.
63
64 *******************************************************************************/
65
66 __PORTED__ s4 emit_load(jitdata *jd, instruction *iptr, varinfo *src, s4 tempreg)
67 {
68         codegendata *cd;
69         s4           disp;
70         s4           reg;
71
72         /* get required compiler data */
73
74         cd = jd->cd;
75
76         if (IS_INMEMORY(src->flags)) {
77                 COUNT_SPILLS;
78
79                 disp = src->vv.regoff * 4;
80
81                 if (IS_FLT_DBL_TYPE(src->type)) {
82                         if (IS_2_WORD_TYPE(src->type))
83                                 M_DLD(tempreg, REG_SP, disp);
84                         else
85                                 M_FLD(tempreg, REG_SP, disp);
86                 }
87                 else {
88                         if (IS_2_WORD_TYPE(src->type))
89                                 M_LLD(tempreg, REG_SP, disp);
90                         else
91                                 M_ILD(tempreg, REG_SP, disp);
92                 }
93
94                 reg = tempreg;
95         }
96         else
97                 reg = src->vv.regoff;
98
99         return reg;
100 }
101
102
103 /* emit_store ******************************************************************
104
105    This function generates the code to store the result of an
106    operation back into a spilled pseudo-variable.  If the
107    pseudo-variable has not been spilled in the first place, this
108    function will generate nothing.
109     
110 *******************************************************************************/
111
112 __PORTED__ inline void emit_store(jitdata *jd, instruction *iptr, varinfo *dst, s4 d)
113 {
114         codegendata *cd;
115
116         /* get required compiler data */
117
118         cd = jd->cd;
119
120         if (IS_INMEMORY(dst->flags)) {
121                 COUNT_SPILLS;
122
123                 if (IS_FLT_DBL_TYPE(dst->type)) {
124                         if (IS_2_WORD_TYPE(dst->type))
125                                 M_DST(d, REG_SP, dst->vv.regoff * 4);
126                         else
127                                 M_FST(d, REG_SP, dst->vv.regoff * 4);
128                 }
129                 else {
130                         if (IS_2_WORD_TYPE(dst->type))
131                                 M_LST(d, REG_SP, dst->vv.regoff * 4);
132                         else
133                                 M_IST(d, REG_SP, dst->vv.regoff * 4);
134                 }
135         }
136 }
137
138
139 /* emit_copy *******************************************************************
140
141    Generates a register/memory to register/memory copy.
142
143 *******************************************************************************/
144
145 __PORTED__ void emit_copy(jitdata *jd, instruction *iptr, varinfo *src, varinfo *dst)
146 {
147         codegendata  *cd;
148         s4            s1, d;
149
150         /* get required compiler data */
151
152         cd = jd->cd;
153
154         if ((src->vv.regoff != dst->vv.regoff) ||
155                 ((src->flags ^ dst->flags) & INMEMORY)) {
156
157                 /* If one of the variables resides in memory, we can eliminate
158                    the register move from/to the temporary register with the
159                    order of getting the destination register and the load. */
160
161                 if (IS_INMEMORY(src->flags)) {
162                         d = codegen_reg_of_var(iptr->opc, dst, REG_IFTMP);
163                         s1 = emit_load(jd, iptr, src, d);
164                 }
165                 else {
166                         s1 = emit_load(jd, iptr, src, REG_IFTMP);
167                         d = codegen_reg_of_var(iptr->opc, dst, s1);
168                 }
169
170                 if (s1 != d) {
171                         if (IS_FLT_DBL_TYPE(src->type))
172                                 M_FMOV(s1, d);
173                         else
174                                 M_MOV(s1, d);
175                 }
176
177                 emit_store(jd, iptr, dst, d);
178         }
179 }
180
181
182 void emit_cmovxx(codegendata *cd, instruction *iptr, s4 s, s4 d)
183 {
184 #if 0
185         switch (iptr->flags.fields.condition) {
186         case ICMD_IFEQ:
187                 M_CMOVEQ(s, d);
188                 break;
189         case ICMD_IFNE:
190                 M_CMOVNE(s, d);
191                 break;
192         case ICMD_IFLT:
193                 M_CMOVLT(s, d);
194                 break;
195         case ICMD_IFGE:
196                 M_CMOVGE(s, d);
197                 break;
198         case ICMD_IFGT:
199                 M_CMOVGT(s, d);
200                 break;
201         case ICMD_IFLE:
202                 M_CMOVLE(s, d);
203                 break;
204         }
205 #endif
206 }
207
208
209 /* emit_exception_stubs ********************************************************
210
211    Generates the code for the exception stubs.
212
213 *******************************************************************************/
214
215 __PORTED__ void emit_exception_stubs(jitdata *jd)
216 {
217         codegendata  *cd;
218         registerdata *rd;
219         exceptionref *er;
220         s4            branchmpc;
221         s4            targetmpc;
222         s4            targetdisp;
223         s4            disp;
224
225         /* get required compiler data */
226
227         cd = jd->cd;
228         rd = jd->rd;
229
230         /* generate exception stubs */
231
232         targetdisp = 0;
233
234         for (er = cd->exceptionrefs; er != NULL; er = er->next) {
235                 /* back-patch the branch to this exception code */
236
237                 branchmpc = er->branchpos;
238                 targetmpc = cd->mcodeptr - cd->mcodebase;
239
240                 md_codegen_patch_branch(cd, branchmpc, targetmpc);
241
242                 MCODECHECK(512);
243
244                 /* move index register into REG_ITMP1 */
245
246                 /* Check if the exception is an
247                    ArrayIndexOutOfBoundsException.  If so, move index register
248                    into a4. */
249
250                 if (er->reg != -1)
251                         M_MOV(er->reg, rd->argintregs[4]);
252
253                 /* calcuate exception address */
254
255                 if (N_VALID_DISP(er->branchpos - 4)) {
256                         M_LDA(rd->argintregs[3], REG_PV, er->branchpos - 4);
257                 } else {
258                         M_INTMOVE(REG_PV, rd->argintregs[3]);
259                         M_AADD_IMM(er->branchpos - 4, REG_PV);
260                 }
261
262                 /* move function to call into REG_ITMP! */
263
264                 disp = dseg_add_functionptr(cd, er->function);
265                 M_ALD(REG_ITMP1, REG_PV, disp);
266
267                 if (targetdisp == 0) {
268                         targetdisp = (cd->mcodeptr) - (cd->mcodebase);
269
270                         M_MOV(REG_PV, rd->argintregs[0]);
271                         M_MOV(REG_SP, rd->argintregs[1]);
272
273                         M_ALD(rd->argintregs[2],
274                                   REG_SP, cd->stackframesize * 4 - SIZEOF_VOID_P);
275
276                         M_ASUB_IMM((2 * 4) + 96, REG_SP);       
277
278                         M_AST(rd->argintregs[3], REG_SP, (0 * 4) + 96); /* store XPC */
279
280                         M_MOV(REG_ITMP1, REG_PV);
281                         M_JSR(REG_RA, REG_PV);
282
283                         /* Recalculate PV */
284
285                         N_BASR(REG_ITMP1, RN);
286                         disp = (s4) (cd->mcodeptr - cd->mcodebase);
287                         M_LDA(REG_PV, REG_ITMP1, -disp);
288
289                         M_MOV(REG_RESULT, REG_ITMP1_XPTR);
290
291                         M_ALD(REG_ITMP2_XPC, REG_SP, (0 * 4) + 96);
292                         M_AADD_IMM((2 * 4) + 96, REG_SP);
293
294                         disp = dseg_add_functionptr(cd, asm_handle_exception);
295                         M_ALD(REG_ITMP3, REG_PV, disp);
296                         M_JMP(RN, REG_ITMP3);
297                 }
298                 else {
299                         disp = ((cd->mcodebase) + targetdisp) -
300                                 (( cd->mcodeptr) );
301
302                         M_BR(disp);
303                 }
304
305         }
306 }
307
308
309 /* emit_patcher_stubs **********************************************************
310
311    Generates the code for the patcher stubs.
312
313 *******************************************************************************/
314
315 __PORTED__ void emit_patcher_stubs(jitdata *jd)
316 {
317         
318         codegendata *cd;
319         patchref    *pref;
320         u4           mcode;
321         u1          *savedmcodeptr;
322         u1          *tmpmcodeptr;
323         s4           targetdisp;
324         s4           disp;
325
326         /* get required compiler data */
327
328         cd = jd->cd;
329
330         /* generate code patching stub call code */
331
332         targetdisp = 0;
333
334         for (pref = cd->patchrefs; pref != NULL; pref = pref->next) {
335                 /* check code segment size */
336
337                 MCODECHECK(100);
338
339                 /* Get machine code which is patched back in later. The
340                    call is 1 instruction word long. */
341
342                 tmpmcodeptr = (u1 *) (cd->mcodebase + pref->branchpos);
343
344                 mcode = *((u4 *) tmpmcodeptr);
345
346                 /* Patch in the call to call the following code (done at
347                    compile time). */
348
349                 savedmcodeptr = cd->mcodeptr;   /* save current mcodeptr              */
350                 cd->mcodeptr  = tmpmcodeptr;    /* set mcodeptr to patch position     */
351
352                 disp = (savedmcodeptr) - (tmpmcodeptr);
353                 M_BSR(REG_ITMP3, disp);
354
355                 cd->mcodeptr = savedmcodeptr;   /* restore the current mcodeptr       */
356
357                 /* create stack frame */
358
359                 M_ASUB_IMM(6 * 4, REG_SP);
360
361                 /* move return address onto stack */
362
363                 M_AST(REG_ITMP3, REG_SP, 5 * 4);
364
365                 /* move pointer to java_objectheader onto stack */
366
367 #if defined(ENABLE_THREADS)
368                 /* create a virtual java_objectheader */
369
370                 (void) dseg_add_unique_address(cd, NULL);                  /* flcword */
371                 (void) dseg_add_unique_address(cd, lock_get_initial_lock_word());
372                 disp = dseg_add_unique_address(cd, NULL);                  /* vftbl   */
373
374                 M_LDA(REG_ITMP3, REG_PV, disp);
375                 M_AST(REG_ITMP3, REG_SP, 4 * 4);
376 #else
377                 /* nothing to do */
378 #endif
379
380                 /* move machine code onto stack */
381
382                 disp = dseg_add_s4(cd, mcode);
383                 M_ILD(REG_ITMP3, REG_PV, disp);
384                 M_IST(REG_ITMP3, REG_SP, 3 * 4);
385
386                 /* move class/method/field reference onto stack */
387
388                 disp = dseg_add_address(cd, pref->ref);
389                 M_ALD(REG_ITMP3, REG_PV, disp);
390                 M_AST(REG_ITMP3, REG_SP, 2 * 4);
391
392                 /* move data segment displacement onto stack */
393
394                 disp = dseg_add_s4(cd, pref->disp);
395                 M_ILD(REG_ITMP3, REG_PV, disp);
396                 M_IST(REG_ITMP3, REG_SP, 1 * 4);
397
398                 /* move patcher function pointer onto stack */
399
400                 disp = dseg_add_functionptr(cd, pref->patcher);
401                 M_ALD(REG_ITMP3, REG_PV, disp);
402                 M_AST(REG_ITMP3, REG_SP, 0 * 4);
403
404                 if (targetdisp == 0) {
405                         targetdisp = (cd->mcodeptr) - (cd->mcodebase);
406
407                         disp = dseg_add_functionptr(cd, asm_patcher_wrapper);
408                         M_ALD(REG_ITMP3, REG_PV, disp);
409                         M_JMP(RN, REG_ITMP3);
410                 }
411                 else {
412                         disp = ((cd->mcodebase) + targetdisp) -
413                                 (( cd->mcodeptr) );
414
415                         M_BR(disp);
416                 }
417         }
418 }
419
420
421 /* emit_replacement_stubs ******************************************************
422
423    Generates the code for the replacement stubs.
424
425 *******************************************************************************/
426
427 void emit_replacement_stubs(jitdata *jd)
428 {
429 #if 0
430         codegendata *cd;
431         codeinfo    *code;
432         rplpoint    *rplp;
433         s4           disp;
434         s4           i;
435
436         /* get required compiler data */
437
438         cd   = jd->cd;
439         code = jd->code;
440
441         rplp = code->rplpoints;
442
443         for (i = 0; i < code->rplpointcount; ++i, ++rplp) {
444                 /* check code segment size */
445
446                 MCODECHECK(512);
447
448                 /* note start of stub code */
449
450                 rplp->outcode = (u1 *) (ptrint) (cd->mcodeptr - cd->mcodebase);
451
452                 /* make machine code for patching */
453
454                 disp = (ptrint) (rplp->outcode - rplp->pc) - 5;
455
456                 rplp->mcode = 0xe9 | ((u8) disp << 8);
457
458                 /* push address of `rplpoint` struct */
459                         
460                 M_MOV_IMM(rplp, REG_ITMP3);
461                 M_PUSH(REG_ITMP3);
462
463                 /* jump to replacement function */
464
465                 M_MOV_IMM(asm_replacement_out, REG_ITMP3);
466                 M_JMP(REG_ITMP3);
467         }
468 #endif
469 }
470         
471
472 /* emit_verbosecall_enter ******************************************************
473
474    Generates the code for the call trace.
475
476 *******************************************************************************/
477
478 #if !defined(NDEBUG)
479 void emit_verbosecall_enter(jitdata *jd)
480 {
481         
482         methodinfo   *m;
483         codegendata  *cd;
484         registerdata *rd;
485         methoddesc   *md;
486         s4            i, j, k;
487         s4            stackframesize, off, foff, aoff, doff, t, iargctr, fargctr, disp;
488
489         /* get required compiler data */
490
491         m  = jd->m;
492         cd = jd->cd;
493         rd = jd->rd;
494
495         md = m->parseddesc;
496
497         /* mark trace code */
498
499         M_NOP;
500
501         stackframesize = 
502                 (6 * 8) + /* s8 on stack parameters x 6 */
503                 (1 * 4) + /* methodinfo on stack parameter */
504                 (ARG_CNT * 8) +
505                 (TMP_CNT * 8) 
506                 ;
507
508         M_ASUB_IMM(stackframesize, REG_SP); /* allocate stackframe */
509
510         /* save argument registers */
511
512         off = (6 * 8) + (1 * 4);
513
514         for (i = 0; i < INT_ARG_CNT; i++, off += 8)
515                 M_IST(rd->argintregs[i], REG_SP, off);
516
517         for (i = 0; i < FLT_ARG_CNT; i++, off += 8)
518                 M_DST(rd->argfltregs[i], REG_SP, off);
519
520         /* save temporary registers for leaf methods */
521
522         if (jd->isleafmethod) {
523                 for (i = 0; i < INT_TMP_CNT; i++, off += 8)
524                         M_LST(rd->tmpintregs[i], REG_SP, off);
525
526                 for (i = 0; i < FLT_TMP_CNT; i++, off += 8)
527                         M_DST(rd->tmpfltregs[i], REG_SP, off);
528         }
529
530         /* Load arguments to new locations */
531
532         /* First move all arguments to stack
533          *
534          * (s8) a7
535          * (s8) a2
536          *   ...
537          * (s8) a1 \ Auxilliary stack frame
538          * (s8) a0 /
539          * ------- <---- SP
540          */
541
542         M_ASUB_IMM(2 * 8, REG_SP);
543         
544         /* offset to where first integer arg is saved on stack */
545         off = (2 * 8) + (6 * 8) + (1 * 4); 
546         /* offset to where first float arg is saved on stack */
547         foff = off + (INT_ARG_CNT * 8); 
548         /* offset to where first argument is passed on stack */
549         aoff = (2 * 8) + stackframesize + (cd->stackframesize * 4);
550         /* offset to destination on stack */
551         doff = 0; 
552
553         iargctr = fargctr = 0;
554
555         ICONST(REG_ITMP1, 0);
556
557         for (i = 0; i < md->paramcount && i < 8; i++) {
558                 t = md->paramtypes[i].type;
559
560                 M_IST(REG_ITMP1, REG_SP, doff);
561                 M_IST(REG_ITMP1, REG_SP, doff + 4);
562
563                 if (IS_FLT_DBL_TYPE(t)) {
564                         if (fargctr < 2) { /* passed in register */
565                                 N_STD(REG_FA0 + fargctr, doff, RN, REG_SP);
566                                 fargctr += 1;
567                         } else { /* passed on stack */
568                                 if (IS_2_WORD_TYPE(t)) {
569                                         N_MVC(doff, 8, REG_SP, aoff, REG_SP);
570                                         aoff += 8;
571                                 } else {
572                                         N_MVC(doff + 4, 4, REG_SP, aoff, REG_SP);
573                                         aoff += 4;
574                                 }
575                         }
576                 } else {
577                         if (IS_2_WORD_TYPE(t)) {
578                                 if (iargctr < 4) { /* passed in 2 registers */
579                                         N_STM(REG_A0 + iargctr, REG_A0 + iargctr + 1, doff, REG_SP);
580                                         iargctr += 2;
581                                 } else { /* passed on stack */
582                                         N_MVC(doff, 8, REG_SP, aoff, REG_SP);
583                                         aoff += 8;
584                                 }
585                         } else {
586                                 if (iargctr < 5) { /* passed in register */
587                                         N_ST(REG_A0 + iargctr, doff + 4, RN, REG_SP);
588                                         iargctr += 1;
589                                 } else { /* passed on stack */
590                                         N_MVC(doff + 4, 4, REG_SP, aoff, REG_SP);
591                                         aoff += 4;
592                                 }
593                         }
594                 }
595
596                 doff += 8;
597         }
598
599         /* Now move a0 and a1 to registers
600          *
601          * (s8) a7
602          *   ...
603          * (s8) a2
604          * ------- <- SP
605          * (s8) a0 ==> a0, a1
606          * (s8) a1 ==> a2, a3
607          */
608
609         N_LM(REG_A0, REG_A1, 0, REG_SP);
610         N_LM(REG_A2, REG_A3, 8, REG_SP);
611
612         M_AADD_IMM(2 * 8, REG_SP);
613
614         /* Finally load methodinfo argument */
615
616         disp = dseg_add_address(cd, m);
617         M_ALD(REG_ITMP2, REG_PV, disp); 
618         M_AST(REG_ITMP2, REG_SP, 6 * 8);
619
620         /* Call builtin_verbosecall_enter */
621
622         disp = dseg_add_address(cd, builtin_verbosecall_enter);
623         M_ALD(REG_ITMP2, REG_PV, disp);
624         M_ASUB_IMM(96, REG_SP);
625         M_CALL(REG_ITMP2);
626         M_AADD_IMM(96, REG_SP);
627
628         /* restore argument registers */
629
630         off = (6 * 8) + (1 * 4);
631
632         for (i = 0; i < INT_ARG_CNT; i++, off += 8)
633                 M_ILD(rd->argintregs[i], REG_SP, off);
634
635         for (i = 0; i < FLT_ARG_CNT; i++, off += 8)
636                 M_DLD(rd->argfltregs[i], REG_SP, off);
637
638         /* restore temporary registers for leaf methods */
639
640         if (jd->isleafmethod) {
641                 for (i = 0; i < INT_TMP_CNT; i++, off += 8)
642                         M_ILD(rd->tmpintregs[i], REG_SP, off);
643
644                 for (i = 0; i < FLT_TMP_CNT; i++, off += 8)
645                         M_DLD(rd->tmpfltregs[i], REG_SP, off);
646         }
647
648         /* remove stackframe */
649
650         M_AADD_IMM(stackframesize, REG_SP);
651
652         /* mark trace code */
653
654         M_NOP;
655 }
656 #endif /* !defined(NDEBUG) */
657
658
659 /* emit_verbosecall_exit *******************************************************
660
661    Generates the code for the call trace.
662
663 *******************************************************************************/
664
665 #if !defined(NDEBUG)
666 void emit_verbosecall_exit(jitdata *jd)
667 {
668         methodinfo   *m;
669         codegendata  *cd;
670         registerdata *rd;
671         s4            disp;
672
673         /* get required compiler data */
674
675         m  = jd->m;
676         cd = jd->cd;
677         rd = jd->rd;
678
679         /* mark trace code */
680
681         M_NOP;
682
683         M_ASUB_IMM(2 * 8, REG_SP);
684
685         N_STM(REG_RESULT, REG_RESULT2, 0 * 8, REG_SP);
686         M_DST(REG_FRESULT, REG_SP, 1 * 8);
687
688         if (IS_2_WORD_TYPE(m->parseddesc->returntype.type)) {
689                 /* (REG_A0, REG_A1) == (REG_RESULT, REG_RESULT2), se no need to move */
690         } else {
691                 M_INTMOVE(REG_RESULT, REG_A1);
692                 ICONST(REG_A0, 0);
693         }
694
695         disp = dseg_add_address(cd, m);
696         M_ALD(REG_A2, REG_PV, disp);
697
698         /* REG_FRESULT is REG_FA0, so no need to move */
699         M_FLTMOVE(REG_FRESULT, REG_FA1);
700
701         disp = dseg_add_address(cd, builtin_verbosecall_exit);
702         M_ALD(REG_ITMP1, REG_PV, disp);
703         M_ASUB_IMM(96, REG_SP);
704         M_CALL(REG_ITMP1);
705         M_AADD_IMM(96, REG_SP);
706
707         N_LM(REG_RESULT, REG_RESULT2, 0 * 8, REG_SP);
708         M_DLD(REG_FRESULT, REG_SP, 1 * 8);
709
710         M_AADD_IMM(2 * 8, REG_SP);
711
712         /* mark trace code */
713
714         M_NOP;
715 }
716 #endif /* !defined(NDEBUG) */
717
718
719 /* code generation functions **************************************************/
720
721 static void emit_membase(codegendata *cd, s4 basereg, s4 disp, s4 dreg)
722 {
723         if ((basereg == REG_SP) || (basereg == R12)) {
724                 if (disp == 0) {
725                         emit_address_byte(0, dreg, REG_SP);
726                         emit_address_byte(0, REG_SP, REG_SP);
727
728                 } else if (IS_IMM8(disp)) {
729                         emit_address_byte(1, dreg, REG_SP);
730                         emit_address_byte(0, REG_SP, REG_SP);
731                         emit_imm8(disp);
732
733                 } else {
734                         emit_address_byte(2, dreg, REG_SP);
735                         emit_address_byte(0, REG_SP, REG_SP);
736                         emit_imm32(disp);
737                 }
738
739         } else if ((disp) == 0 && (basereg) != RBP && (basereg) != R13) {
740                 emit_address_byte(0,(dreg),(basereg));
741
742         } else if ((basereg) == RIP) {
743                 emit_address_byte(0, dreg, RBP);
744                 emit_imm32(disp);
745
746         } else {
747                 if (IS_IMM8(disp)) {
748                         emit_address_byte(1, dreg, basereg);
749                         emit_imm8(disp);
750
751                 } else {
752                         emit_address_byte(2, dreg, basereg);
753                         emit_imm32(disp);
754                 }
755         }
756 }
757
758
759 static void emit_membase32(codegendata *cd, s4 basereg, s4 disp, s4 dreg)
760 {
761         if ((basereg == REG_SP) || (basereg == R12)) {
762                 emit_address_byte(2, dreg, REG_SP);
763                 emit_address_byte(0, REG_SP, REG_SP);
764                 emit_imm32(disp);
765         }
766         else {
767                 emit_address_byte(2, dreg, basereg);
768                 emit_imm32(disp);
769         }
770 }
771
772
773 static void emit_memindex(codegendata *cd, s4 reg, s4 disp, s4 basereg, s4 indexreg, s4 scale)
774 {
775         if (basereg == -1) {
776                 emit_address_byte(0, reg, 4);
777                 emit_address_byte(scale, indexreg, 5);
778                 emit_imm32(disp);
779         }
780         else if ((disp == 0) && (basereg != RBP) && (basereg != R13)) {
781                 emit_address_byte(0, reg, 4);
782                 emit_address_byte(scale, indexreg, basereg);
783         }
784         else if (IS_IMM8(disp)) {
785                 emit_address_byte(1, reg, 4);
786                 emit_address_byte(scale, indexreg, basereg);
787                 emit_imm8(disp);
788         }
789         else {
790                 emit_address_byte(2, reg, 4);
791                 emit_address_byte(scale, indexreg, basereg);
792                 emit_imm32(disp);
793         }
794 }
795
796
797 void emit_ishift(jitdata *jd, s4 shift_op, instruction *iptr)
798 {
799         s4 s1, s2, d, d_old;
800         varinfo *v_s1,*v_s2,*v_dst;
801         codegendata *cd;
802
803         /* get required compiler data */
804
805         cd = jd->cd;
806
807         v_s1  = VAROP(iptr->s1);
808         v_s2  = VAROP(iptr->sx.s23.s2);
809         v_dst = VAROP(iptr->dst);
810
811         s1 = v_s1->vv.regoff;
812         s2 = v_s2->vv.regoff;
813         d  = v_dst->vv.regoff;
814
815         M_INTMOVE(RCX, REG_ITMP1);                                    /* save RCX */
816
817         if (IS_INMEMORY(v_dst->flags)) {
818                 if (IS_INMEMORY(v_s2->flags) && IS_INMEMORY(v_s1->flags)) {
819                         if (s1 == d) {
820                                 M_ILD(RCX, REG_SP, s2 * 8);
821                                 emit_shiftl_membase(cd, shift_op, REG_SP, d * 8);
822
823                         } else {
824                                 M_ILD(RCX, REG_SP, s2 * 8);
825                                 M_ILD(REG_ITMP2, REG_SP, s1 * 8);
826                                 emit_shiftl_reg(cd, shift_op, REG_ITMP2);
827                                 M_IST(REG_ITMP2, REG_SP, d * 8);
828                         }
829
830                 } else if (IS_INMEMORY(v_s2->flags) && !IS_INMEMORY(v_s1->flags)) {
831                         /* s1 may be equal to RCX */
832                         if (s1 == RCX) {
833                                 if (s2 == d) {
834                                         M_ILD(REG_ITMP1, REG_SP, s2 * 8);
835                                         M_IST(s1, REG_SP, d * 8);
836                                         M_INTMOVE(REG_ITMP1, RCX);
837
838                                 } else {
839                                         M_IST(s1, REG_SP, d * 8);
840                                         M_ILD(RCX, REG_SP, s2 * 8);
841                                 }
842
843                         } else {
844                                 M_ILD(RCX, REG_SP, s2 * 8);
845                                 M_IST(s1, REG_SP, d * 8);
846                         }
847
848                         emit_shiftl_membase(cd, shift_op, REG_SP, d * 8);
849
850                 } else if (!IS_INMEMORY(v_s2->flags) && IS_INMEMORY(v_s1->flags)) {
851                         if (s1 == d) {
852                                 M_INTMOVE(s2, RCX);
853                                 emit_shiftl_membase(cd, shift_op, REG_SP, d * 8);
854
855                         } else {
856                                 M_INTMOVE(s2, RCX);
857                                 M_ILD(REG_ITMP2, REG_SP, s1 * 8);
858                                 emit_shiftl_reg(cd, shift_op, REG_ITMP2);
859                                 M_IST(REG_ITMP2, REG_SP, d * 8);
860                         }
861
862                 } else {
863                         /* s1 may be equal to RCX */
864                         M_IST(s1, REG_SP, d * 8);
865                         M_INTMOVE(s2, RCX);
866                         emit_shiftl_membase(cd, shift_op, REG_SP, d * 8);
867                 }
868
869                 M_INTMOVE(REG_ITMP1, RCX);                             /* restore RCX */
870
871         } else {
872                 d_old = d;
873                 if (d == RCX) {
874                         d = REG_ITMP3;
875                 }
876                                         
877                 if (IS_INMEMORY(v_s2->flags) && IS_INMEMORY(v_s1->flags)) {
878                         M_ILD(RCX, REG_SP, s2 * 8);
879                         M_ILD(d, REG_SP, s1 * 8);
880                         emit_shiftl_reg(cd, shift_op, d);
881
882                 } else if (IS_INMEMORY(v_s2->flags) && !IS_INMEMORY(v_s1->flags)) {
883                         /* s1 may be equal to RCX */
884                         M_INTMOVE(s1, d);
885                         M_ILD(RCX, REG_SP, s2 * 8);
886                         emit_shiftl_reg(cd, shift_op, d);
887
888                 } else if (!IS_INMEMORY(v_s2->flags) && IS_INMEMORY(v_s1->flags)) {
889                         M_INTMOVE(s2, RCX);
890                         M_ILD(d, REG_SP, s1 * 8);
891                         emit_shiftl_reg(cd, shift_op, d);
892
893                 } else {
894                         /* s1 may be equal to RCX */
895                         if (s1 == RCX) {
896                                 if (s2 == d) {
897                                         /* d cannot be used to backup s1 since this would
898                                            overwrite s2. */
899                                         M_INTMOVE(s1, REG_ITMP3);
900                                         M_INTMOVE(s2, RCX);
901                                         M_INTMOVE(REG_ITMP3, d);
902
903                                 } else {
904                                         M_INTMOVE(s1, d);
905                                         M_INTMOVE(s2, RCX);
906                                 }
907
908                         } else {
909                                 /* d may be equal to s2 */
910                                 M_INTMOVE(s2, RCX);
911                                 M_INTMOVE(s1, d);
912                         }
913                         emit_shiftl_reg(cd, shift_op, d);
914                 }
915
916                 if (d_old == RCX)
917                         M_INTMOVE(REG_ITMP3, RCX);
918                 else
919                         M_INTMOVE(REG_ITMP1, RCX);                         /* restore RCX */
920         }
921 }
922
923
924 void emit_lshift(jitdata *jd, s4 shift_op, instruction *iptr)
925 {
926         s4 s1, s2, d, d_old;
927         varinfo *v_s1,*v_s2,*v_dst;
928         codegendata *cd;
929
930         /* get required compiler data */
931
932         cd = jd->cd;
933
934         v_s1  = VAROP(iptr->s1);
935         v_s2  = VAROP(iptr->sx.s23.s2);
936         v_dst = VAROP(iptr->dst);
937
938         s1 = v_s1->vv.regoff;
939         s2 = v_s2->vv.regoff;
940         d  = v_dst->vv.regoff;
941         
942         M_INTMOVE(RCX, REG_ITMP1);                                    /* save RCX */
943
944         if (IS_INMEMORY(v_dst->flags)) {
945                 if (IS_INMEMORY(v_s2->flags) && IS_INMEMORY(v_s1->flags)) {
946                         if (s1 == d) {
947                                 M_ILD(RCX, REG_SP, s2 * 8);
948                                 emit_shift_membase(cd, shift_op, REG_SP, d * 8);
949
950                         } else {
951                                 M_ILD(RCX, REG_SP, s2 * 8);
952                                 M_LLD(REG_ITMP2, REG_SP, s1 * 8);
953                                 emit_shift_reg(cd, shift_op, REG_ITMP2);
954                                 M_LST(REG_ITMP2, REG_SP, d * 8);
955                         }
956
957                 } else if (IS_INMEMORY(v_s2->flags) && !IS_INMEMORY(v_s1->flags)) {
958                         /* s1 may be equal to RCX */
959                         if (s1 == RCX) {
960                                 if (s2 == d) {
961                                         M_ILD(REG_ITMP1, REG_SP, s2 * 8);
962                                         M_LST(s1, REG_SP, d * 8);
963                                         M_INTMOVE(REG_ITMP1, RCX);
964
965                                 } else {
966                                         M_LST(s1, REG_SP, d * 8);
967                                         M_ILD(RCX, REG_SP, s2 * 8);
968                                 }
969
970                         } else {
971                                 M_ILD(RCX, REG_SP, s2 * 8);
972                                 M_LST(s1, REG_SP, d * 8);
973                         }
974
975                         emit_shift_membase(cd, shift_op, REG_SP, d * 8);
976
977                 } else if (!IS_INMEMORY(v_s2->flags) && IS_INMEMORY(v_s1->flags)) {
978                         if (s1 == d) {
979                                 M_INTMOVE(s2, RCX);
980                                 emit_shift_membase(cd, shift_op, REG_SP, d * 8);
981
982                         } else {
983                                 M_INTMOVE(s2, RCX);
984                                 M_LLD(REG_ITMP2, REG_SP, s1 * 8);
985                                 emit_shift_reg(cd, shift_op, REG_ITMP2);
986                                 M_LST(REG_ITMP2, REG_SP, d * 8);
987                         }
988
989                 } else {
990                         /* s1 may be equal to RCX */
991                         M_LST(s1, REG_SP, d * 8);
992                         M_INTMOVE(s2, RCX);
993                         emit_shift_membase(cd, shift_op, REG_SP, d * 8);
994                 }
995
996                 M_INTMOVE(REG_ITMP1, RCX);                             /* restore RCX */
997
998         } else {
999                 d_old = d;
1000                 if (d == RCX) {
1001                         d = REG_ITMP3;
1002                 }
1003
1004                 if (IS_INMEMORY(v_s2->flags) && IS_INMEMORY(v_s1->flags)) {
1005                         M_ILD(RCX, REG_SP, s2 * 8);
1006                         M_LLD(d, REG_SP, s1 * 8);
1007                         emit_shift_reg(cd, shift_op, d);
1008
1009                 } else if (IS_INMEMORY(v_s2->flags) && !IS_INMEMORY(v_s1->flags)) {
1010                         /* s1 may be equal to RCX */
1011                         M_INTMOVE(s1, d);
1012                         M_ILD(RCX, REG_SP, s2 * 8);
1013                         emit_shift_reg(cd, shift_op, d);
1014
1015                 } else if (!IS_INMEMORY(v_s2->flags) && IS_INMEMORY(v_s1->flags)) {
1016                         M_INTMOVE(s2, RCX);
1017                         M_LLD(d, REG_SP, s1 * 8);
1018                         emit_shift_reg(cd, shift_op, d);
1019
1020                 } else {
1021                         /* s1 may be equal to RCX */
1022                         if (s1 == RCX) {
1023                                 if (s2 == d) {
1024                                         /* d cannot be used to backup s1 since this would
1025                                            overwrite s2. */
1026                                         M_INTMOVE(s1, REG_ITMP3);
1027                                         M_INTMOVE(s2, RCX);
1028                                         M_INTMOVE(REG_ITMP3, d);
1029
1030                                 } else {
1031                                         M_INTMOVE(s1, d);
1032                                         M_INTMOVE(s2, RCX);
1033                                 }
1034
1035                         } else {
1036                                 /* d may be equal to s2 */
1037                                 M_INTMOVE(s2, RCX);
1038                                 M_INTMOVE(s1, d);
1039                         }
1040                         emit_shift_reg(cd, shift_op, d);
1041                 }
1042
1043                 if (d_old == RCX)
1044                         M_INTMOVE(REG_ITMP3, RCX);
1045                 else
1046                         M_INTMOVE(REG_ITMP1, RCX);                         /* restore RCX */
1047         }
1048 }
1049
1050
1051 /* low-level code emitter functions *******************************************/
1052
1053 void emit_mov_reg_reg(codegendata *cd, s8 reg, s8 dreg)
1054 {
1055         emit_rex(1,(reg),0,(dreg));
1056         *(cd->mcodeptr++) = 0x89;
1057         emit_reg((reg),(dreg));
1058 }
1059
1060
1061 void emit_mov_imm_reg(codegendata *cd, s8 imm, s8 reg)
1062 {
1063         emit_rex(1,0,0,(reg));
1064         *(cd->mcodeptr++) = 0xb8 + ((reg) & 0x07);
1065         emit_imm64((imm));
1066 }
1067
1068
1069 void emit_movl_reg_reg(codegendata *cd, s8 reg, s8 dreg)
1070 {
1071         emit_rex(0,(reg),0,(dreg));
1072         *(cd->mcodeptr++) = 0x89;
1073         emit_reg((reg),(dreg));
1074 }
1075
1076
1077 void emit_movl_imm_reg(codegendata *cd, s8 imm, s8 reg) {
1078         emit_rex(0,0,0,(reg));
1079         *(cd->mcodeptr++) = 0xb8 + ((reg) & 0x07);
1080         emit_imm32((imm));
1081 }
1082
1083
1084 void emit_mov_membase_reg(codegendata *cd, s8 basereg, s8 disp, s8 reg) {
1085         emit_rex(1,(reg),0,(basereg));
1086         *(cd->mcodeptr++) = 0x8b;
1087         emit_membase(cd, (basereg),(disp),(reg));
1088 }
1089
1090
1091 /*
1092  * this one is for INVOKEVIRTUAL/INVOKEINTERFACE to have a
1093  * constant membase immediate length of 32bit
1094  */
1095 void emit_mov_membase32_reg(codegendata *cd, s8 basereg, s8 disp, s8 reg) {
1096         emit_rex(1,(reg),0,(basereg));
1097         *(cd->mcodeptr++) = 0x8b;
1098         emit_membase32(cd, (basereg),(disp),(reg));
1099 }
1100
1101
1102 void emit_movl_membase_reg(codegendata *cd, s8 basereg, s8 disp, s8 reg)
1103 {
1104         emit_rex(0,(reg),0,(basereg));
1105         *(cd->mcodeptr++) = 0x8b;
1106         emit_membase(cd, (basereg),(disp),(reg));
1107 }
1108
1109
1110 /* ATTENTION: Always emit a REX byte, because the instruction size can
1111    be smaller when all register indexes are smaller than 7. */
1112 void emit_movl_membase32_reg(codegendata *cd, s8 basereg, s8 disp, s8 reg)
1113 {
1114         emit_byte_rex((reg),0,(basereg));
1115         *(cd->mcodeptr++) = 0x8b;
1116         emit_membase32(cd, (basereg),(disp),(reg));
1117 }
1118
1119
1120 void emit_mov_reg_membase(codegendata *cd, s8 reg, s8 basereg, s8 disp) {
1121         emit_rex(1,(reg),0,(basereg));
1122         *(cd->mcodeptr++) = 0x89;
1123         emit_membase(cd, (basereg),(disp),(reg));
1124 }
1125
1126
1127 void emit_mov_reg_membase32(codegendata *cd, s8 reg, s8 basereg, s8 disp) {
1128         emit_rex(1,(reg),0,(basereg));
1129         *(cd->mcodeptr++) = 0x89;
1130         emit_membase32(cd, (basereg),(disp),(reg));
1131 }
1132
1133
1134 void emit_movl_reg_membase(codegendata *cd, s8 reg, s8 basereg, s8 disp) {
1135         emit_rex(0,(reg),0,(basereg));
1136         *(cd->mcodeptr++) = 0x89;
1137         emit_membase(cd, (basereg),(disp),(reg));
1138 }
1139
1140
1141 /* Always emit a REX byte, because the instruction size can be smaller when   */
1142 /* all register indexes are smaller than 7.                                   */
1143 void emit_movl_reg_membase32(codegendata *cd, s8 reg, s8 basereg, s8 disp) {
1144         emit_byte_rex((reg),0,(basereg));
1145         *(cd->mcodeptr++) = 0x89;
1146         emit_membase32(cd, (basereg),(disp),(reg));
1147 }
1148
1149
1150 void emit_mov_memindex_reg(codegendata *cd, s8 disp, s8 basereg, s8 indexreg, s8 scale, s8 reg) {
1151         emit_rex(1,(reg),(indexreg),(basereg));
1152         *(cd->mcodeptr++) = 0x8b;
1153         emit_memindex(cd, (reg),(disp),(basereg),(indexreg),(scale));
1154 }
1155
1156
1157 void emit_movl_memindex_reg(codegendata *cd, s8 disp, s8 basereg, s8 indexreg, s8 scale, s8 reg) {
1158         emit_rex(0,(reg),(indexreg),(basereg));
1159         *(cd->mcodeptr++) = 0x8b;
1160         emit_memindex(cd, (reg),(disp),(basereg),(indexreg),(scale));
1161 }
1162
1163
1164 void emit_mov_reg_memindex(codegendata *cd, s8 reg, s8 disp, s8 basereg, s8 indexreg, s8 scale) {
1165         emit_rex(1,(reg),(indexreg),(basereg));
1166         *(cd->mcodeptr++) = 0x89;
1167         emit_memindex(cd, (reg),(disp),(basereg),(indexreg),(scale));
1168 }
1169
1170
1171 void emit_movl_reg_memindex(codegendata *cd, s8 reg, s8 disp, s8 basereg, s8 indexreg, s8 scale) {
1172         emit_rex(0,(reg),(indexreg),(basereg));
1173         *(cd->mcodeptr++) = 0x89;
1174         emit_memindex(cd, (reg),(disp),(basereg),(indexreg),(scale));
1175 }
1176
1177
1178 void emit_movw_reg_memindex(codegendata *cd, s8 reg, s8 disp, s8 basereg, s8 indexreg, s8 scale) {
1179         *(cd->mcodeptr++) = 0x66;
1180         emit_rex(0,(reg),(indexreg),(basereg));
1181         *(cd->mcodeptr++) = 0x89;
1182         emit_memindex(cd, (reg),(disp),(basereg),(indexreg),(scale));
1183 }
1184
1185
1186 void emit_movb_reg_memindex(codegendata *cd, s8 reg, s8 disp, s8 basereg, s8 indexreg, s8 scale) {
1187         emit_byte_rex((reg),(indexreg),(basereg));
1188         *(cd->mcodeptr++) = 0x88;
1189         emit_memindex(cd, (reg),(disp),(basereg),(indexreg),(scale));
1190 }
1191
1192
1193 void emit_mov_imm_membase(codegendata *cd, s8 imm, s8 basereg, s8 disp) {
1194         emit_rex(1,0,0,(basereg));
1195         *(cd->mcodeptr++) = 0xc7;
1196         emit_membase(cd, (basereg),(disp),0);
1197         emit_imm32((imm));
1198 }
1199
1200
1201 void emit_mov_imm_membase32(codegendata *cd, s8 imm, s8 basereg, s8 disp) {
1202         emit_rex(1,0,0,(basereg));
1203         *(cd->mcodeptr++) = 0xc7;
1204         emit_membase32(cd, (basereg),(disp),0);
1205         emit_imm32((imm));
1206 }
1207
1208
1209 void emit_movl_imm_membase(codegendata *cd, s8 imm, s8 basereg, s8 disp) {
1210         emit_rex(0,0,0,(basereg));
1211         *(cd->mcodeptr++) = 0xc7;
1212         emit_membase(cd, (basereg),(disp),0);
1213         emit_imm32((imm));
1214 }
1215
1216
1217 /* Always emit a REX byte, because the instruction size can be smaller when   */
1218 /* all register indexes are smaller than 7.                                   */
1219 void emit_movl_imm_membase32(codegendata *cd, s8 imm, s8 basereg, s8 disp) {
1220         emit_byte_rex(0,0,(basereg));
1221         *(cd->mcodeptr++) = 0xc7;
1222         emit_membase32(cd, (basereg),(disp),0);
1223         emit_imm32((imm));
1224 }
1225
1226
1227 void emit_movsbq_reg_reg(codegendata *cd, s8 reg, s8 dreg)
1228 {
1229         emit_rex(1,(dreg),0,(reg));
1230         *(cd->mcodeptr++) = 0x0f;
1231         *(cd->mcodeptr++) = 0xbe;
1232         /* XXX: why do reg and dreg have to be exchanged */
1233         emit_reg((dreg),(reg));
1234 }
1235
1236
1237 void emit_movswq_reg_reg(codegendata *cd, s8 reg, s8 dreg)
1238 {
1239         emit_rex(1,(dreg),0,(reg));
1240         *(cd->mcodeptr++) = 0x0f;
1241         *(cd->mcodeptr++) = 0xbf;
1242         /* XXX: why do reg and dreg have to be exchanged */
1243         emit_reg((dreg),(reg));
1244 }
1245
1246
1247 void emit_movslq_reg_reg(codegendata *cd, s8 reg, s8 dreg)
1248 {
1249         emit_rex(1,(dreg),0,(reg));
1250         *(cd->mcodeptr++) = 0x63;
1251         /* XXX: why do reg and dreg have to be exchanged */
1252         emit_reg((dreg),(reg));
1253 }
1254
1255
1256 void emit_movzwq_reg_reg(codegendata *cd, s8 reg, s8 dreg)
1257 {
1258         emit_rex(1,(dreg),0,(reg));
1259         *(cd->mcodeptr++) = 0x0f;
1260         *(cd->mcodeptr++) = 0xb7;
1261         /* XXX: why do reg and dreg have to be exchanged */
1262         emit_reg((dreg),(reg));
1263 }
1264
1265
1266 void emit_movswq_memindex_reg(codegendata *cd, s8 disp, s8 basereg, s8 indexreg, s8 scale, s8 reg) {
1267         emit_rex(1,(reg),(indexreg),(basereg));
1268         *(cd->mcodeptr++) = 0x0f;
1269         *(cd->mcodeptr++) = 0xbf;
1270         emit_memindex(cd, (reg),(disp),(basereg),(indexreg),(scale));
1271 }
1272
1273
1274 void emit_movsbq_memindex_reg(codegendata *cd, s8 disp, s8 basereg, s8 indexreg, s8 scale, s8 reg) {
1275         emit_rex(1,(reg),(indexreg),(basereg));
1276         *(cd->mcodeptr++) = 0x0f;
1277         *(cd->mcodeptr++) = 0xbe;
1278         emit_memindex(cd, (reg),(disp),(basereg),(indexreg),(scale));
1279 }
1280
1281
1282 void emit_movzwq_memindex_reg(codegendata *cd, s8 disp, s8 basereg, s8 indexreg, s8 scale, s8 reg) {
1283         emit_rex(1,(reg),(indexreg),(basereg));
1284         *(cd->mcodeptr++) = 0x0f;
1285         *(cd->mcodeptr++) = 0xb7;
1286         emit_memindex(cd, (reg),(disp),(basereg),(indexreg),(scale));
1287 }
1288
1289
1290 void emit_mov_imm_memindex(codegendata *cd, s4 imm, s4 disp, s4 basereg, s4 indexreg, s4 scale)
1291 {
1292         emit_rex(1,0,(indexreg),(basereg));
1293         *(cd->mcodeptr++) = 0xc7;
1294         emit_memindex(cd, 0,(disp),(basereg),(indexreg),(scale));
1295         emit_imm32((imm));
1296 }
1297
1298
1299 void emit_movl_imm_memindex(codegendata *cd, s4 imm, s4 disp, s4 basereg, s4 indexreg, s4 scale)
1300 {
1301         emit_rex(0,0,(indexreg),(basereg));
1302         *(cd->mcodeptr++) = 0xc7;
1303         emit_memindex(cd, 0,(disp),(basereg),(indexreg),(scale));
1304         emit_imm32((imm));
1305 }
1306
1307
1308 void emit_movw_imm_memindex(codegendata *cd, s4 imm, s4 disp, s4 basereg, s4 indexreg, s4 scale)
1309 {
1310         *(cd->mcodeptr++) = 0x66;
1311         emit_rex(0,0,(indexreg),(basereg));
1312         *(cd->mcodeptr++) = 0xc7;
1313         emit_memindex(cd, 0,(disp),(basereg),(indexreg),(scale));
1314         emit_imm16((imm));
1315 }
1316
1317
1318 void emit_movb_imm_memindex(codegendata *cd, s4 imm, s4 disp, s4 basereg, s4 indexreg, s4 scale)
1319 {
1320         emit_rex(0,0,(indexreg),(basereg));
1321         *(cd->mcodeptr++) = 0xc6;
1322         emit_memindex(cd, 0,(disp),(basereg),(indexreg),(scale));
1323         emit_imm8((imm));
1324 }
1325
1326
1327 /*
1328  * alu operations
1329  */
1330 void emit_alu_reg_reg(codegendata *cd, s8 opc, s8 reg, s8 dreg)
1331 {
1332         emit_rex(1,(reg),0,(dreg));
1333         *(cd->mcodeptr++) = (((opc)) << 3) + 1;
1334         emit_reg((reg),(dreg));
1335 }
1336
1337
1338 void emit_alul_reg_reg(codegendata *cd, s8 opc, s8 reg, s8 dreg)
1339 {
1340         emit_rex(0,(reg),0,(dreg));
1341         *(cd->mcodeptr++) = (((opc)) << 3) + 1;
1342         emit_reg((reg),(dreg));
1343 }
1344
1345
1346 void emit_alu_reg_membase(codegendata *cd, s8 opc, s8 reg, s8 basereg, s8 disp)
1347 {
1348         emit_rex(1,(reg),0,(basereg));
1349         *(cd->mcodeptr++) = (((opc)) << 3) + 1;
1350         emit_membase(cd, (basereg),(disp),(reg));
1351 }
1352
1353
1354 void emit_alul_reg_membase(codegendata *cd, s8 opc, s8 reg, s8 basereg, s8 disp)
1355 {
1356         emit_rex(0,(reg),0,(basereg));
1357         *(cd->mcodeptr++) = (((opc)) << 3) + 1;
1358         emit_membase(cd, (basereg),(disp),(reg));
1359 }
1360
1361
1362 void emit_alu_membase_reg(codegendata *cd, s8 opc, s8 basereg, s8 disp, s8 reg)
1363 {
1364         emit_rex(1,(reg),0,(basereg));
1365         *(cd->mcodeptr++) = (((opc)) << 3) + 3;
1366         emit_membase(cd, (basereg),(disp),(reg));
1367 }
1368
1369
1370 void emit_alul_membase_reg(codegendata *cd, s8 opc, s8 basereg, s8 disp, s8 reg)
1371 {
1372         emit_rex(0,(reg),0,(basereg));
1373         *(cd->mcodeptr++) = (((opc)) << 3) + 3;
1374         emit_membase(cd, (basereg),(disp),(reg));
1375 }
1376
1377
1378 void emit_alu_imm_reg(codegendata *cd, s8 opc, s8 imm, s8 dreg) {
1379         if (IS_IMM8(imm)) {
1380                 emit_rex(1,0,0,(dreg));
1381                 *(cd->mcodeptr++) = 0x83;
1382                 emit_reg((opc),(dreg));
1383                 emit_imm8((imm));
1384         } else {
1385                 emit_rex(1,0,0,(dreg));
1386                 *(cd->mcodeptr++) = 0x81;
1387                 emit_reg((opc),(dreg));
1388                 emit_imm32((imm));
1389         }
1390 }
1391
1392
1393 void emit_alu_imm32_reg(codegendata *cd, s8 opc, s8 imm, s8 dreg) {
1394         emit_rex(1,0,0,(dreg));
1395         *(cd->mcodeptr++) = 0x81;
1396         emit_reg((opc),(dreg));
1397         emit_imm32((imm));
1398 }
1399
1400
1401 void emit_alul_imm_reg(codegendata *cd, s8 opc, s8 imm, s8 dreg) {
1402         if (IS_IMM8(imm)) {
1403                 emit_rex(0,0,0,(dreg));
1404                 *(cd->mcodeptr++) = 0x83;
1405                 emit_reg((opc),(dreg));
1406                 emit_imm8((imm));
1407         } else {
1408                 emit_rex(0,0,0,(dreg));
1409                 *(cd->mcodeptr++) = 0x81;
1410                 emit_reg((opc),(dreg));
1411                 emit_imm32((imm));
1412         }
1413 }
1414
1415
1416 void emit_alu_imm_membase(codegendata *cd, s8 opc, s8 imm, s8 basereg, s8 disp) {
1417         if (IS_IMM8(imm)) {
1418                 emit_rex(1,(basereg),0,0);
1419                 *(cd->mcodeptr++) = 0x83;
1420                 emit_membase(cd, (basereg),(disp),(opc));
1421                 emit_imm8((imm));
1422         } else {
1423                 emit_rex(1,(basereg),0,0);
1424                 *(cd->mcodeptr++) = 0x81;
1425                 emit_membase(cd, (basereg),(disp),(opc));
1426                 emit_imm32((imm));
1427         }
1428 }
1429
1430
1431 void emit_alul_imm_membase(codegendata *cd, s8 opc, s8 imm, s8 basereg, s8 disp) {
1432         if (IS_IMM8(imm)) {
1433                 emit_rex(0,(basereg),0,0);
1434                 *(cd->mcodeptr++) = 0x83;
1435                 emit_membase(cd, (basereg),(disp),(opc));
1436                 emit_imm8((imm));
1437         } else {
1438                 emit_rex(0,(basereg),0,0);
1439                 *(cd->mcodeptr++) = 0x81;
1440                 emit_membase(cd, (basereg),(disp),(opc));
1441                 emit_imm32((imm));
1442         }
1443 }
1444
1445
1446 void emit_test_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
1447         emit_rex(1,(reg),0,(dreg));
1448         *(cd->mcodeptr++) = 0x85;
1449         emit_reg((reg),(dreg));
1450 }
1451
1452
1453 void emit_testl_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
1454         emit_rex(0,(reg),0,(dreg));
1455         *(cd->mcodeptr++) = 0x85;
1456         emit_reg((reg),(dreg));
1457 }
1458
1459
1460 void emit_test_imm_reg(codegendata *cd, s8 imm, s8 reg) {
1461         *(cd->mcodeptr++) = 0xf7;
1462         emit_reg(0,(reg));
1463         emit_imm32((imm));
1464 }
1465
1466
1467 void emit_testw_imm_reg(codegendata *cd, s8 imm, s8 reg) {
1468         *(cd->mcodeptr++) = 0x66;
1469         *(cd->mcodeptr++) = 0xf7;
1470         emit_reg(0,(reg));
1471         emit_imm16((imm));
1472 }
1473
1474
1475 void emit_testb_imm_reg(codegendata *cd, s8 imm, s8 reg) {
1476         *(cd->mcodeptr++) = 0xf6;
1477         emit_reg(0,(reg));
1478         emit_imm8((imm));
1479 }
1480
1481
1482 void emit_lea_membase_reg(codegendata *cd, s8 basereg, s8 disp, s8 reg) {
1483         emit_rex(1,(reg),0,(basereg));
1484         *(cd->mcodeptr++) = 0x8d;
1485         emit_membase(cd, (basereg),(disp),(reg));
1486 }
1487
1488
1489 void emit_leal_membase_reg(codegendata *cd, s8 basereg, s8 disp, s8 reg) {
1490         emit_rex(0,(reg),0,(basereg));
1491         *(cd->mcodeptr++) = 0x8d;
1492         emit_membase(cd, (basereg),(disp),(reg));
1493 }
1494
1495
1496
1497 void emit_incl_membase(codegendata *cd, s8 basereg, s8 disp)
1498 {
1499         emit_rex(0,0,0,(basereg));
1500         *(cd->mcodeptr++) = 0xff;
1501         emit_membase(cd, (basereg),(disp),0);
1502 }
1503
1504
1505
1506 void emit_cltd(codegendata *cd) {
1507     *(cd->mcodeptr++) = 0x99;
1508 }
1509
1510
1511 void emit_cqto(codegendata *cd) {
1512         emit_rex(1,0,0,0);
1513         *(cd->mcodeptr++) = 0x99;
1514 }
1515
1516
1517
1518 void emit_imul_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
1519         emit_rex(1,(dreg),0,(reg));
1520         *(cd->mcodeptr++) = 0x0f;
1521         *(cd->mcodeptr++) = 0xaf;
1522         emit_reg((dreg),(reg));
1523 }
1524
1525
1526 void emit_imull_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
1527         emit_rex(0,(dreg),0,(reg));
1528         *(cd->mcodeptr++) = 0x0f;
1529         *(cd->mcodeptr++) = 0xaf;
1530         emit_reg((dreg),(reg));
1531 }
1532
1533
1534 void emit_imul_membase_reg(codegendata *cd, s8 basereg, s8 disp, s8 dreg) {
1535         emit_rex(1,(dreg),0,(basereg));
1536         *(cd->mcodeptr++) = 0x0f;
1537         *(cd->mcodeptr++) = 0xaf;
1538         emit_membase(cd, (basereg),(disp),(dreg));
1539 }
1540
1541
1542 void emit_imull_membase_reg(codegendata *cd, s8 basereg, s8 disp, s8 dreg) {
1543         emit_rex(0,(dreg),0,(basereg));
1544         *(cd->mcodeptr++) = 0x0f;
1545         *(cd->mcodeptr++) = 0xaf;
1546         emit_membase(cd, (basereg),(disp),(dreg));
1547 }
1548
1549
1550 void emit_imul_imm_reg(codegendata *cd, s8 imm, s8 dreg) {
1551         if (IS_IMM8((imm))) {
1552                 emit_rex(1,0,0,(dreg));
1553                 *(cd->mcodeptr++) = 0x6b;
1554                 emit_reg(0,(dreg));
1555                 emit_imm8((imm));
1556         } else {
1557                 emit_rex(1,0,0,(dreg));
1558                 *(cd->mcodeptr++) = 0x69;
1559                 emit_reg(0,(dreg));
1560                 emit_imm32((imm));
1561         }
1562 }
1563
1564
1565 void emit_imul_imm_reg_reg(codegendata *cd, s8 imm, s8 reg, s8 dreg) {
1566         if (IS_IMM8((imm))) {
1567                 emit_rex(1,(dreg),0,(reg));
1568                 *(cd->mcodeptr++) = 0x6b;
1569                 emit_reg((dreg),(reg));
1570                 emit_imm8((imm));
1571         } else {
1572                 emit_rex(1,(dreg),0,(reg));
1573                 *(cd->mcodeptr++) = 0x69;
1574                 emit_reg((dreg),(reg));
1575                 emit_imm32((imm));
1576         }
1577 }
1578
1579
1580 void emit_imull_imm_reg_reg(codegendata *cd, s8 imm, s8 reg, s8 dreg) {
1581         if (IS_IMM8((imm))) {
1582                 emit_rex(0,(dreg),0,(reg));
1583                 *(cd->mcodeptr++) = 0x6b;
1584                 emit_reg((dreg),(reg));
1585                 emit_imm8((imm));
1586         } else {
1587                 emit_rex(0,(dreg),0,(reg));
1588                 *(cd->mcodeptr++) = 0x69;
1589                 emit_reg((dreg),(reg));
1590                 emit_imm32((imm));
1591         }
1592 }
1593
1594
1595 void emit_imul_imm_membase_reg(codegendata *cd, s8 imm, s8 basereg, s8 disp, s8 dreg) {
1596         if (IS_IMM8((imm))) {
1597                 emit_rex(1,(dreg),0,(basereg));
1598                 *(cd->mcodeptr++) = 0x6b;
1599                 emit_membase(cd, (basereg),(disp),(dreg));
1600                 emit_imm8((imm));
1601         } else {
1602                 emit_rex(1,(dreg),0,(basereg));
1603                 *(cd->mcodeptr++) = 0x69;
1604                 emit_membase(cd, (basereg),(disp),(dreg));
1605                 emit_imm32((imm));
1606         }
1607 }
1608
1609
1610 void emit_imull_imm_membase_reg(codegendata *cd, s8 imm, s8 basereg, s8 disp, s8 dreg) {
1611         if (IS_IMM8((imm))) {
1612                 emit_rex(0,(dreg),0,(basereg));
1613                 *(cd->mcodeptr++) = 0x6b;
1614                 emit_membase(cd, (basereg),(disp),(dreg));
1615                 emit_imm8((imm));
1616         } else {
1617                 emit_rex(0,(dreg),0,(basereg));
1618                 *(cd->mcodeptr++) = 0x69;
1619                 emit_membase(cd, (basereg),(disp),(dreg));
1620                 emit_imm32((imm));
1621         }
1622 }
1623
1624
1625 void emit_idiv_reg(codegendata *cd, s8 reg) {
1626         emit_rex(1,0,0,(reg));
1627         *(cd->mcodeptr++) = 0xf7;
1628         emit_reg(7,(reg));
1629 }
1630
1631
1632 void emit_idivl_reg(codegendata *cd, s8 reg) {
1633         emit_rex(0,0,0,(reg));
1634         *(cd->mcodeptr++) = 0xf7;
1635         emit_reg(7,(reg));
1636 }
1637
1638
1639
1640 void emit_ret(codegendata *cd) {
1641     *(cd->mcodeptr++) = 0xc3;
1642 }
1643
1644
1645
1646 /*
1647  * shift ops
1648  */
1649 void emit_shift_reg(codegendata *cd, s8 opc, s8 reg) {
1650         emit_rex(1,0,0,(reg));
1651         *(cd->mcodeptr++) = 0xd3;
1652         emit_reg((opc),(reg));
1653 }
1654
1655
1656 void emit_shiftl_reg(codegendata *cd, s8 opc, s8 reg) {
1657         emit_rex(0,0,0,(reg));
1658         *(cd->mcodeptr++) = 0xd3;
1659         emit_reg((opc),(reg));
1660 }
1661
1662
1663 void emit_shift_membase(codegendata *cd, s8 opc, s8 basereg, s8 disp) {
1664         emit_rex(1,0,0,(basereg));
1665         *(cd->mcodeptr++) = 0xd3;
1666         emit_membase(cd, (basereg),(disp),(opc));
1667 }
1668
1669
1670 void emit_shiftl_membase(codegendata *cd, s8 opc, s8 basereg, s8 disp) {
1671         emit_rex(0,0,0,(basereg));
1672         *(cd->mcodeptr++) = 0xd3;
1673         emit_membase(cd, (basereg),(disp),(opc));
1674 }
1675
1676
1677 void emit_shift_imm_reg(codegendata *cd, s8 opc, s8 imm, s8 dreg) {
1678         if ((imm) == 1) {
1679                 emit_rex(1,0,0,(dreg));
1680                 *(cd->mcodeptr++) = 0xd1;
1681                 emit_reg((opc),(dreg));
1682         } else {
1683                 emit_rex(1,0,0,(dreg));
1684                 *(cd->mcodeptr++) = 0xc1;
1685                 emit_reg((opc),(dreg));
1686                 emit_imm8((imm));
1687         }
1688 }
1689
1690
1691 void emit_shiftl_imm_reg(codegendata *cd, s8 opc, s8 imm, s8 dreg) {
1692         if ((imm) == 1) {
1693                 emit_rex(0,0,0,(dreg));
1694                 *(cd->mcodeptr++) = 0xd1;
1695                 emit_reg((opc),(dreg));
1696         } else {
1697                 emit_rex(0,0,0,(dreg));
1698                 *(cd->mcodeptr++) = 0xc1;
1699                 emit_reg((opc),(dreg));
1700                 emit_imm8((imm));
1701         }
1702 }
1703
1704
1705 void emit_shift_imm_membase(codegendata *cd, s8 opc, s8 imm, s8 basereg, s8 disp) {
1706         if ((imm) == 1) {
1707                 emit_rex(1,0,0,(basereg));
1708                 *(cd->mcodeptr++) = 0xd1;
1709                 emit_membase(cd, (basereg),(disp),(opc));
1710         } else {
1711                 emit_rex(1,0,0,(basereg));
1712                 *(cd->mcodeptr++) = 0xc1;
1713                 emit_membase(cd, (basereg),(disp),(opc));
1714                 emit_imm8((imm));
1715         }
1716 }
1717
1718
1719 void emit_shiftl_imm_membase(codegendata *cd, s8 opc, s8 imm, s8 basereg, s8 disp) {
1720         if ((imm) == 1) {
1721                 emit_rex(0,0,0,(basereg));
1722                 *(cd->mcodeptr++) = 0xd1;
1723                 emit_membase(cd, (basereg),(disp),(opc));
1724         } else {
1725                 emit_rex(0,0,0,(basereg));
1726                 *(cd->mcodeptr++) = 0xc1;
1727                 emit_membase(cd, (basereg),(disp),(opc));
1728                 emit_imm8((imm));
1729         }
1730 }
1731
1732
1733
1734 /*
1735  * jump operations
1736  */
1737 void emit_jmp_imm(codegendata *cd, s8 imm) {
1738         *(cd->mcodeptr++) = 0xe9;
1739         emit_imm32((imm));
1740 }
1741
1742
1743 void emit_jmp_reg(codegendata *cd, s8 reg) {
1744         emit_rex(0,0,0,(reg));
1745         *(cd->mcodeptr++) = 0xff;
1746         emit_reg(4,(reg));
1747 }
1748
1749
1750 void emit_jcc(codegendata *cd, s8 opc, s8 imm) {
1751         *(cd->mcodeptr++) = 0x0f;
1752         *(cd->mcodeptr++) = (0x80 + (opc));
1753         emit_imm32((imm));
1754 }
1755
1756
1757
1758 /*
1759  * conditional set and move operations
1760  */
1761
1762 /* we need the rex byte to get all low bytes */
1763 void emit_setcc_reg(codegendata *cd, s8 opc, s8 reg) {
1764         *(cd->mcodeptr++) = (0x40 | (((reg) >> 3) & 0x01));
1765         *(cd->mcodeptr++) = 0x0f;
1766         *(cd->mcodeptr++) = (0x90 + (opc));
1767         emit_reg(0,(reg));
1768 }
1769
1770
1771 /* we need the rex byte to get all low bytes */
1772 void emit_setcc_membase(codegendata *cd, s8 opc, s8 basereg, s8 disp) {
1773         *(cd->mcodeptr++) = (0x40 | (((basereg) >> 3) & 0x01));
1774         *(cd->mcodeptr++) = 0x0f;
1775         *(cd->mcodeptr++) = (0x90 + (opc));
1776         emit_membase(cd, (basereg),(disp),0);
1777 }
1778
1779
1780 void emit_cmovcc_reg_reg(codegendata *cd, s8 opc, s8 reg, s8 dreg)
1781 {
1782         emit_rex(1,(dreg),0,(reg));
1783         *(cd->mcodeptr++) = 0x0f;
1784         *(cd->mcodeptr++) = (0x40 + (opc));
1785         emit_reg((dreg),(reg));
1786 }
1787
1788
1789 void emit_cmovccl_reg_reg(codegendata *cd, s8 opc, s8 reg, s8 dreg)
1790 {
1791         emit_rex(0,(dreg),0,(reg));
1792         *(cd->mcodeptr++) = 0x0f;
1793         *(cd->mcodeptr++) = (0x40 + (opc));
1794         emit_reg((dreg),(reg));
1795 }
1796
1797
1798
1799 void emit_neg_reg(codegendata *cd, s8 reg)
1800 {
1801         emit_rex(1,0,0,(reg));
1802         *(cd->mcodeptr++) = 0xf7;
1803         emit_reg(3,(reg));
1804 }
1805
1806
1807 void emit_negl_reg(codegendata *cd, s8 reg)
1808 {
1809         emit_rex(0,0,0,(reg));
1810         *(cd->mcodeptr++) = 0xf7;
1811         emit_reg(3,(reg));
1812 }
1813
1814
1815 void emit_push_reg(codegendata *cd, s8 reg) {
1816         emit_rex(0,0,0,(reg));
1817         *(cd->mcodeptr++) = 0x50 + (0x07 & (reg));
1818 }
1819
1820
1821 void emit_push_imm(codegendata *cd, s8 imm) {
1822         *(cd->mcodeptr++) = 0x68;
1823         emit_imm32((imm));
1824 }
1825
1826
1827 void emit_pop_reg(codegendata *cd, s8 reg) {
1828         emit_rex(0,0,0,(reg));
1829         *(cd->mcodeptr++) = 0x58 + (0x07 & (reg));
1830 }
1831
1832
1833 void emit_xchg_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
1834         emit_rex(1,(reg),0,(dreg));
1835         *(cd->mcodeptr++) = 0x87;
1836         emit_reg((reg),(dreg));
1837 }
1838
1839
1840 void emit_nop(codegendata *cd) {
1841     *(cd->mcodeptr++) = 0x90;
1842 }
1843
1844
1845
1846 /*
1847  * call instructions
1848  */
1849 void emit_call_reg(codegendata *cd, s8 reg) {
1850         emit_rex(1,0,0,(reg));
1851         *(cd->mcodeptr++) = 0xff;
1852         emit_reg(2,(reg));
1853 }
1854
1855
1856 void emit_call_imm(codegendata *cd, s8 imm) {
1857         *(cd->mcodeptr++) = 0xe8;
1858         emit_imm32((imm));
1859 }
1860
1861
1862 void emit_call_mem(codegendata *cd, ptrint mem)
1863 {
1864         *(cd->mcodeptr++) = 0xff;
1865         emit_mem(2,(mem));
1866 }
1867
1868
1869
1870 /*
1871  * floating point instructions (SSE2)
1872  */
1873 void emit_addsd_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
1874         *(cd->mcodeptr++) = 0xf2;
1875         emit_rex(0,(dreg),0,(reg));
1876         *(cd->mcodeptr++) = 0x0f;
1877         *(cd->mcodeptr++) = 0x58;
1878         emit_reg((dreg),(reg));
1879 }
1880
1881
1882 void emit_addss_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
1883         *(cd->mcodeptr++) = 0xf3;
1884         emit_rex(0,(dreg),0,(reg));
1885         *(cd->mcodeptr++) = 0x0f;
1886         *(cd->mcodeptr++) = 0x58;
1887         emit_reg((dreg),(reg));
1888 }
1889
1890
1891 void emit_cvtsi2ssq_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
1892         *(cd->mcodeptr++) = 0xf3;
1893         emit_rex(1,(dreg),0,(reg));
1894         *(cd->mcodeptr++) = 0x0f;
1895         *(cd->mcodeptr++) = 0x2a;
1896         emit_reg((dreg),(reg));
1897 }
1898
1899
1900 void emit_cvtsi2ss_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
1901         *(cd->mcodeptr++) = 0xf3;
1902         emit_rex(0,(dreg),0,(reg));
1903         *(cd->mcodeptr++) = 0x0f;
1904         *(cd->mcodeptr++) = 0x2a;
1905         emit_reg((dreg),(reg));
1906 }
1907
1908
1909 void emit_cvtsi2sdq_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
1910         *(cd->mcodeptr++) = 0xf2;
1911         emit_rex(1,(dreg),0,(reg));
1912         *(cd->mcodeptr++) = 0x0f;
1913         *(cd->mcodeptr++) = 0x2a;
1914         emit_reg((dreg),(reg));
1915 }
1916
1917
1918 void emit_cvtsi2sd_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
1919         *(cd->mcodeptr++) = 0xf2;
1920         emit_rex(0,(dreg),0,(reg));
1921         *(cd->mcodeptr++) = 0x0f;
1922         *(cd->mcodeptr++) = 0x2a;
1923         emit_reg((dreg),(reg));
1924 }
1925
1926
1927 void emit_cvtss2sd_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
1928         *(cd->mcodeptr++) = 0xf3;
1929         emit_rex(0,(dreg),0,(reg));
1930         *(cd->mcodeptr++) = 0x0f;
1931         *(cd->mcodeptr++) = 0x5a;
1932         emit_reg((dreg),(reg));
1933 }
1934
1935
1936 void emit_cvtsd2ss_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
1937         *(cd->mcodeptr++) = 0xf2;
1938         emit_rex(0,(dreg),0,(reg));
1939         *(cd->mcodeptr++) = 0x0f;
1940         *(cd->mcodeptr++) = 0x5a;
1941         emit_reg((dreg),(reg));
1942 }
1943
1944
1945 void emit_cvttss2siq_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
1946         *(cd->mcodeptr++) = 0xf3;
1947         emit_rex(1,(dreg),0,(reg));
1948         *(cd->mcodeptr++) = 0x0f;
1949         *(cd->mcodeptr++) = 0x2c;
1950         emit_reg((dreg),(reg));
1951 }
1952
1953
1954 void emit_cvttss2si_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
1955         *(cd->mcodeptr++) = 0xf3;
1956         emit_rex(0,(dreg),0,(reg));
1957         *(cd->mcodeptr++) = 0x0f;
1958         *(cd->mcodeptr++) = 0x2c;
1959         emit_reg((dreg),(reg));
1960 }
1961
1962
1963 void emit_cvttsd2siq_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
1964         *(cd->mcodeptr++) = 0xf2;
1965         emit_rex(1,(dreg),0,(reg));
1966         *(cd->mcodeptr++) = 0x0f;
1967         *(cd->mcodeptr++) = 0x2c;
1968         emit_reg((dreg),(reg));
1969 }
1970
1971
1972 void emit_cvttsd2si_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
1973         *(cd->mcodeptr++) = 0xf2;
1974         emit_rex(0,(dreg),0,(reg));
1975         *(cd->mcodeptr++) = 0x0f;
1976         *(cd->mcodeptr++) = 0x2c;
1977         emit_reg((dreg),(reg));
1978 }
1979
1980
1981 void emit_divss_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
1982         *(cd->mcodeptr++) = 0xf3;
1983         emit_rex(0,(dreg),0,(reg));
1984         *(cd->mcodeptr++) = 0x0f;
1985         *(cd->mcodeptr++) = 0x5e;
1986         emit_reg((dreg),(reg));
1987 }
1988
1989
1990 void emit_divsd_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
1991         *(cd->mcodeptr++) = 0xf2;
1992         emit_rex(0,(dreg),0,(reg));
1993         *(cd->mcodeptr++) = 0x0f;
1994         *(cd->mcodeptr++) = 0x5e;
1995         emit_reg((dreg),(reg));
1996 }
1997
1998
1999 void emit_movd_reg_freg(codegendata *cd, s8 reg, s8 freg) {
2000         *(cd->mcodeptr++) = 0x66;
2001         emit_rex(1,(freg),0,(reg));
2002         *(cd->mcodeptr++) = 0x0f;
2003         *(cd->mcodeptr++) = 0x6e;
2004         emit_reg((freg),(reg));
2005 }
2006
2007
2008 void emit_movd_freg_reg(codegendata *cd, s8 freg, s8 reg) {
2009         *(cd->mcodeptr++) = 0x66;
2010         emit_rex(1,(freg),0,(reg));
2011         *(cd->mcodeptr++) = 0x0f;
2012         *(cd->mcodeptr++) = 0x7e;
2013         emit_reg((freg),(reg));
2014 }
2015
2016
2017 void emit_movd_reg_membase(codegendata *cd, s8 reg, s8 basereg, s8 disp) {
2018         *(cd->mcodeptr++) = 0x66;
2019         emit_rex(0,(reg),0,(basereg));
2020         *(cd->mcodeptr++) = 0x0f;
2021         *(cd->mcodeptr++) = 0x7e;
2022         emit_membase(cd, (basereg),(disp),(reg));
2023 }
2024
2025
2026 void emit_movd_reg_memindex(codegendata *cd, s8 reg, s8 disp, s8 basereg, s8 indexreg, s8 scale) {
2027         *(cd->mcodeptr++) = 0x66;
2028         emit_rex(0,(reg),(indexreg),(basereg));
2029         *(cd->mcodeptr++) = 0x0f;
2030         *(cd->mcodeptr++) = 0x7e;
2031         emit_memindex(cd, (reg),(disp),(basereg),(indexreg),(scale));
2032 }
2033
2034
2035 void emit_movd_membase_reg(codegendata *cd, s8 basereg, s8 disp, s8 dreg) {
2036         *(cd->mcodeptr++) = 0x66;
2037         emit_rex(1,(dreg),0,(basereg));
2038         *(cd->mcodeptr++) = 0x0f;
2039         *(cd->mcodeptr++) = 0x6e;
2040         emit_membase(cd, (basereg),(disp),(dreg));
2041 }
2042
2043
2044 void emit_movdl_membase_reg(codegendata *cd, s8 basereg, s8 disp, s8 dreg) {
2045         *(cd->mcodeptr++) = 0x66;
2046         emit_rex(0,(dreg),0,(basereg));
2047         *(cd->mcodeptr++) = 0x0f;
2048         *(cd->mcodeptr++) = 0x6e;
2049         emit_membase(cd, (basereg),(disp),(dreg));
2050 }
2051
2052
2053 void emit_movd_memindex_reg(codegendata *cd, s8 disp, s8 basereg, s8 indexreg, s8 scale, s8 dreg) {
2054         *(cd->mcodeptr++) = 0x66;
2055         emit_rex(0,(dreg),(indexreg),(basereg));
2056         *(cd->mcodeptr++) = 0x0f;
2057         *(cd->mcodeptr++) = 0x6e;
2058         emit_memindex(cd, (dreg),(disp),(basereg),(indexreg),(scale));
2059 }
2060
2061
2062 void emit_movq_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
2063         *(cd->mcodeptr++) = 0xf3;
2064         emit_rex(0,(dreg),0,(reg));
2065         *(cd->mcodeptr++) = 0x0f;
2066         *(cd->mcodeptr++) = 0x7e;
2067         emit_reg((dreg),(reg));
2068 }
2069
2070
2071 void emit_movq_reg_membase(codegendata *cd, s8 reg, s8 basereg, s8 disp) {
2072         *(cd->mcodeptr++) = 0x66;
2073         emit_rex(0,(reg),0,(basereg));
2074         *(cd->mcodeptr++) = 0x0f;
2075         *(cd->mcodeptr++) = 0xd6;
2076         emit_membase(cd, (basereg),(disp),(reg));
2077 }
2078
2079
2080 void emit_movq_membase_reg(codegendata *cd, s8 basereg, s8 disp, s8 dreg) {
2081         *(cd->mcodeptr++) = 0xf3;
2082         emit_rex(0,(dreg),0,(basereg));
2083         *(cd->mcodeptr++) = 0x0f;
2084         *(cd->mcodeptr++) = 0x7e;
2085         emit_membase(cd, (basereg),(disp),(dreg));
2086 }
2087
2088
2089 void emit_movss_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
2090         *(cd->mcodeptr++) = 0xf3;
2091         emit_rex(0,(reg),0,(dreg));
2092         *(cd->mcodeptr++) = 0x0f;
2093         *(cd->mcodeptr++) = 0x10;
2094         emit_reg((reg),(dreg));
2095 }
2096
2097
2098 void emit_movsd_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
2099         *(cd->mcodeptr++) = 0xf2;
2100         emit_rex(0,(reg),0,(dreg));
2101         *(cd->mcodeptr++) = 0x0f;
2102         *(cd->mcodeptr++) = 0x10;
2103         emit_reg((reg),(dreg));
2104 }
2105
2106
2107 void emit_movss_reg_membase(codegendata *cd, s8 reg, s8 basereg, s8 disp) {
2108         *(cd->mcodeptr++) = 0xf3;
2109         emit_rex(0,(reg),0,(basereg));
2110         *(cd->mcodeptr++) = 0x0f;
2111         *(cd->mcodeptr++) = 0x11;
2112         emit_membase(cd, (basereg),(disp),(reg));
2113 }
2114
2115
2116 /* Always emit a REX byte, because the instruction size can be smaller when   */
2117 /* all register indexes are smaller than 7.                                   */
2118 void emit_movss_reg_membase32(codegendata *cd, s8 reg, s8 basereg, s8 disp) {
2119         *(cd->mcodeptr++) = 0xf3;
2120         emit_byte_rex((reg),0,(basereg));
2121         *(cd->mcodeptr++) = 0x0f;
2122         *(cd->mcodeptr++) = 0x11;
2123         emit_membase32(cd, (basereg),(disp),(reg));
2124 }
2125
2126
2127 void emit_movsd_reg_membase(codegendata *cd, s8 reg, s8 basereg, s8 disp) {
2128         *(cd->mcodeptr++) = 0xf2;
2129         emit_rex(0,(reg),0,(basereg));
2130         *(cd->mcodeptr++) = 0x0f;
2131         *(cd->mcodeptr++) = 0x11;
2132         emit_membase(cd, (basereg),(disp),(reg));
2133 }
2134
2135
2136 /* Always emit a REX byte, because the instruction size can be smaller when   */
2137 /* all register indexes are smaller than 7.                                   */
2138 void emit_movsd_reg_membase32(codegendata *cd, s8 reg, s8 basereg, s8 disp) {
2139         *(cd->mcodeptr++) = 0xf2;
2140         emit_byte_rex((reg),0,(basereg));
2141         *(cd->mcodeptr++) = 0x0f;
2142         *(cd->mcodeptr++) = 0x11;
2143         emit_membase32(cd, (basereg),(disp),(reg));
2144 }
2145
2146
2147 void emit_movss_membase_reg(codegendata *cd, s8 basereg, s8 disp, s8 dreg) {
2148         *(cd->mcodeptr++) = 0xf3;
2149         emit_rex(0,(dreg),0,(basereg));
2150         *(cd->mcodeptr++) = 0x0f;
2151         *(cd->mcodeptr++) = 0x10;
2152         emit_membase(cd, (basereg),(disp),(dreg));
2153 }
2154
2155
2156 /* Always emit a REX byte, because the instruction size can be smaller when   */
2157 /* all register indexes are smaller than 7.                                   */
2158 void emit_movss_membase32_reg(codegendata *cd, s8 basereg, s8 disp, s8 dreg) {
2159         *(cd->mcodeptr++) = 0xf3;
2160         emit_byte_rex((dreg),0,(basereg));
2161         *(cd->mcodeptr++) = 0x0f;
2162         *(cd->mcodeptr++) = 0x10;
2163         emit_membase32(cd, (basereg),(disp),(dreg));
2164 }
2165
2166
2167 void emit_movlps_membase_reg(codegendata *cd, s8 basereg, s8 disp, s8 dreg)
2168 {
2169         emit_rex(0,(dreg),0,(basereg));
2170         *(cd->mcodeptr++) = 0x0f;
2171         *(cd->mcodeptr++) = 0x12;
2172         emit_membase(cd, (basereg),(disp),(dreg));
2173 }
2174
2175
2176 void emit_movlps_reg_membase(codegendata *cd, s8 reg, s8 basereg, s8 disp)
2177 {
2178         emit_rex(0,(reg),0,(basereg));
2179         *(cd->mcodeptr++) = 0x0f;
2180         *(cd->mcodeptr++) = 0x13;
2181         emit_membase(cd, (basereg),(disp),(reg));
2182 }
2183
2184
2185 void emit_movsd_membase_reg(codegendata *cd, s8 basereg, s8 disp, s8 dreg) {
2186         *(cd->mcodeptr++) = 0xf2;
2187         emit_rex(0,(dreg),0,(basereg));
2188         *(cd->mcodeptr++) = 0x0f;
2189         *(cd->mcodeptr++) = 0x10;
2190         emit_membase(cd, (basereg),(disp),(dreg));
2191 }
2192
2193
2194 /* Always emit a REX byte, because the instruction size can be smaller when   */
2195 /* all register indexes are smaller than 7.                                   */
2196 void emit_movsd_membase32_reg(codegendata *cd, s8 basereg, s8 disp, s8 dreg) {
2197         *(cd->mcodeptr++) = 0xf2;
2198         emit_byte_rex((dreg),0,(basereg));
2199         *(cd->mcodeptr++) = 0x0f;
2200         *(cd->mcodeptr++) = 0x10;
2201         emit_membase32(cd, (basereg),(disp),(dreg));
2202 }
2203
2204
2205 void emit_movlpd_membase_reg(codegendata *cd, s8 basereg, s8 disp, s8 dreg)
2206 {
2207         *(cd->mcodeptr++) = 0x66;
2208         emit_rex(0,(dreg),0,(basereg));
2209         *(cd->mcodeptr++) = 0x0f;
2210         *(cd->mcodeptr++) = 0x12;
2211         emit_membase(cd, (basereg),(disp),(dreg));
2212 }
2213
2214
2215 void emit_movlpd_reg_membase(codegendata *cd, s8 reg, s8 basereg, s8 disp)
2216 {
2217         *(cd->mcodeptr++) = 0x66;
2218         emit_rex(0,(reg),0,(basereg));
2219         *(cd->mcodeptr++) = 0x0f;
2220         *(cd->mcodeptr++) = 0x13;
2221         emit_membase(cd, (basereg),(disp),(reg));
2222 }
2223
2224
2225 void emit_movss_reg_memindex(codegendata *cd, s8 reg, s8 disp, s8 basereg, s8 indexreg, s8 scale) {
2226         *(cd->mcodeptr++) = 0xf3;
2227         emit_rex(0,(reg),(indexreg),(basereg));
2228         *(cd->mcodeptr++) = 0x0f;
2229         *(cd->mcodeptr++) = 0x11;
2230         emit_memindex(cd, (reg),(disp),(basereg),(indexreg),(scale));
2231 }
2232
2233
2234 void emit_movsd_reg_memindex(codegendata *cd, s8 reg, s8 disp, s8 basereg, s8 indexreg, s8 scale) {
2235         *(cd->mcodeptr++) = 0xf2;
2236         emit_rex(0,(reg),(indexreg),(basereg));
2237         *(cd->mcodeptr++) = 0x0f;
2238         *(cd->mcodeptr++) = 0x11;
2239         emit_memindex(cd, (reg),(disp),(basereg),(indexreg),(scale));
2240 }
2241
2242
2243 void emit_movss_memindex_reg(codegendata *cd, s8 disp, s8 basereg, s8 indexreg, s8 scale, s8 dreg) {
2244         *(cd->mcodeptr++) = 0xf3;
2245         emit_rex(0,(dreg),(indexreg),(basereg));
2246         *(cd->mcodeptr++) = 0x0f;
2247         *(cd->mcodeptr++) = 0x10;
2248         emit_memindex(cd, (dreg),(disp),(basereg),(indexreg),(scale));
2249 }
2250
2251
2252 void emit_movsd_memindex_reg(codegendata *cd, s8 disp, s8 basereg, s8 indexreg, s8 scale, s8 dreg) {
2253         *(cd->mcodeptr++) = 0xf2;
2254         emit_rex(0,(dreg),(indexreg),(basereg));
2255         *(cd->mcodeptr++) = 0x0f;
2256         *(cd->mcodeptr++) = 0x10;
2257         emit_memindex(cd, (dreg),(disp),(basereg),(indexreg),(scale));
2258 }
2259
2260
2261 void emit_mulss_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
2262         *(cd->mcodeptr++) = 0xf3;
2263         emit_rex(0,(dreg),0,(reg));
2264         *(cd->mcodeptr++) = 0x0f;
2265         *(cd->mcodeptr++) = 0x59;
2266         emit_reg((dreg),(reg));
2267 }
2268
2269
2270 void emit_mulsd_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
2271         *(cd->mcodeptr++) = 0xf2;
2272         emit_rex(0,(dreg),0,(reg));
2273         *(cd->mcodeptr++) = 0x0f;
2274         *(cd->mcodeptr++) = 0x59;
2275         emit_reg((dreg),(reg));
2276 }
2277
2278
2279 void emit_subss_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
2280         *(cd->mcodeptr++) = 0xf3;
2281         emit_rex(0,(dreg),0,(reg));
2282         *(cd->mcodeptr++) = 0x0f;
2283         *(cd->mcodeptr++) = 0x5c;
2284         emit_reg((dreg),(reg));
2285 }
2286
2287
2288 void emit_subsd_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
2289         *(cd->mcodeptr++) = 0xf2;
2290         emit_rex(0,(dreg),0,(reg));
2291         *(cd->mcodeptr++) = 0x0f;
2292         *(cd->mcodeptr++) = 0x5c;
2293         emit_reg((dreg),(reg));
2294 }
2295
2296
2297 void emit_ucomiss_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
2298         emit_rex(0,(dreg),0,(reg));
2299         *(cd->mcodeptr++) = 0x0f;
2300         *(cd->mcodeptr++) = 0x2e;
2301         emit_reg((dreg),(reg));
2302 }
2303
2304
2305 void emit_ucomisd_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
2306         *(cd->mcodeptr++) = 0x66;
2307         emit_rex(0,(dreg),0,(reg));
2308         *(cd->mcodeptr++) = 0x0f;
2309         *(cd->mcodeptr++) = 0x2e;
2310         emit_reg((dreg),(reg));
2311 }
2312
2313
2314 void emit_xorps_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
2315         emit_rex(0,(dreg),0,(reg));
2316         *(cd->mcodeptr++) = 0x0f;
2317         *(cd->mcodeptr++) = 0x57;
2318         emit_reg((dreg),(reg));
2319 }
2320
2321
2322 void emit_xorps_membase_reg(codegendata *cd, s8 basereg, s8 disp, s8 dreg) {
2323         emit_rex(0,(dreg),0,(basereg));
2324         *(cd->mcodeptr++) = 0x0f;
2325         *(cd->mcodeptr++) = 0x57;
2326         emit_membase(cd, (basereg),(disp),(dreg));
2327 }
2328
2329
2330 void emit_xorpd_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
2331         *(cd->mcodeptr++) = 0x66;
2332         emit_rex(0,(dreg),0,(reg));
2333         *(cd->mcodeptr++) = 0x0f;
2334         *(cd->mcodeptr++) = 0x57;
2335         emit_reg((dreg),(reg));
2336 }
2337
2338
2339 void emit_xorpd_membase_reg(codegendata *cd, s8 basereg, s8 disp, s8 dreg) {
2340         *(cd->mcodeptr++) = 0x66;
2341         emit_rex(0,(dreg),0,(basereg));
2342         *(cd->mcodeptr++) = 0x0f;
2343         *(cd->mcodeptr++) = 0x57;
2344         emit_membase(cd, (basereg),(disp),(dreg));
2345 }
2346
2347
2348 /* system instructions ********************************************************/
2349
2350 void emit_rdtsc(codegendata *cd)
2351 {
2352         *(cd->mcodeptr++) = 0x0f;
2353         *(cd->mcodeptr++) = 0x31;
2354 }
2355
2356 /* emit_load_high **************************************************************
2357
2358    Emits a possible load of the high 32-bits of an operand.
2359
2360 *******************************************************************************/
2361
2362 __PORTED__ s4 emit_load_high(jitdata *jd, instruction *iptr, varinfo *src, s4 tempreg)
2363 {
2364         codegendata  *cd;
2365         s4            disp;
2366         s4            reg;
2367
2368         assert(src->type == TYPE_LNG);
2369
2370         /* get required compiler data */
2371
2372         cd = jd->cd;
2373
2374         if (IS_INMEMORY(src->flags)) {
2375                 COUNT_SPILLS;
2376
2377                 disp = src->vv.regoff * 4;
2378
2379                 M_ILD(tempreg, REG_SP, disp + 4);
2380
2381                 reg = tempreg;
2382         }
2383         else
2384                 reg = GET_HIGH_REG(src->vv.regoff);
2385
2386         return reg;
2387 }
2388
2389 /* emit_load_low ***************************************************************
2390
2391    Emits a possible load of the low 32-bits of an operand.
2392
2393 *******************************************************************************/
2394
2395 __PORTED__ s4 emit_load_low(jitdata *jd, instruction *iptr, varinfo *src, s4 tempreg)
2396 {
2397         codegendata  *cd;
2398         s4            disp;
2399         s4            reg;
2400
2401         assert(src->type == TYPE_LNG);
2402
2403         /* get required compiler data */
2404
2405         cd = jd->cd;
2406
2407         if (IS_INMEMORY(src->flags)) {
2408                 COUNT_SPILLS;
2409
2410                 disp = src->vv.regoff * 4;
2411
2412                 M_ILD(tempreg, REG_SP, disp);
2413
2414                 reg = tempreg;
2415         }
2416         else
2417                 reg = GET_LOW_REG(src->vv.regoff);
2418
2419         return reg;
2420 }
2421
2422 /* emit_nullpointer_check ******************************************************
2423
2424    Emit a NullPointerException check.
2425
2426 *******************************************************************************/
2427
2428 __PORTED__ void emit_nullpointer_check(codegendata *cd, instruction *iptr, s4 reg)
2429 {
2430         if (INSTRUCTION_MUST_CHECK(iptr)) {
2431                 M_TEST(reg);
2432                 M_BEQ(0);
2433                 codegen_add_nullpointerexception_ref(cd);
2434         }
2435 }
2436
2437 /* emit_arrayindexoutofbounds_check ********************************************
2438
2439    Emit a ArrayIndexOutOfBoundsException check.
2440
2441 *******************************************************************************/
2442
2443 __PORTED__ void emit_arrayindexoutofbounds_check(codegendata *cd, instruction *iptr, s4 s1, s4 s2)
2444 {
2445         if (INSTRUCTION_MUST_CHECK(iptr)) {
2446                 N_C(s2, OFFSET(java_arrayheader, size), RN, s1);
2447         M_BGE(0);
2448         codegen_add_arrayindexoutofboundsexception_ref(cd, s2);
2449         }
2450 }
2451
2452 s4 emit_load_s1_notzero(jitdata *jd, instruction *iptr, s4 tempreg) {
2453         codegendata *cd = jd->cd;
2454         s4 reg = emit_load_s1(jd, iptr, tempreg);
2455         if (reg == 0) {
2456                 M_MOV(reg, tempreg);
2457                 return tempreg;
2458         } else {
2459                 return reg;
2460         }
2461 }
2462
2463 s4 emit_load_s2_notzero(jitdata *jd, instruction *iptr, s4 tempreg) {
2464         codegendata *cd = jd->cd;
2465         s4 reg = emit_load_s2(jd, iptr, tempreg);
2466         if (reg == 0) {
2467                 M_MOV(reg, tempreg);
2468                 return tempreg;
2469         } else {
2470                 return reg;
2471         }
2472 }
2473
2474 s4 emit_load_s1_but(jitdata *jd, instruction *iptr, s4 tempreg, s4 notreg) {
2475         codegendata *cd = jd->cd;
2476         s4 reg = emit_load_s1(jd, iptr, tempreg);
2477         if (reg == notreg) {
2478                 M_MOV(reg, tempreg);
2479                 return tempreg;
2480         } else {
2481                 return reg;
2482         }
2483 }
2484
2485 s4 emit_load_s2_but(jitdata *jd, instruction *iptr, s4 tempreg, s4 notreg) {
2486         codegendata *cd = jd->cd;
2487         s4 reg = emit_load_s2(jd, iptr, tempreg);
2488         if (reg == notreg) {
2489                 M_MOV(reg, tempreg);
2490                 return tempreg;
2491         } else {
2492                 return reg;
2493         }
2494 }
2495
2496 /*
2497  * These are local overrides for various environment variables in Emacs.
2498  * Please do not remove this and leave it at the end of the file, where
2499  * Emacs will automagically detect them.
2500  * ---------------------------------------------------------------------
2501  * Local variables:
2502  * mode: c
2503  * indent-tabs-mode: t
2504  * c-basic-offset: 4
2505  * tab-width: 4
2506  * End:
2507  */