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