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