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