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