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