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