Proper x86_64 mnemonics
[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 void emit_alu_memindex_reg(codegendata *cd, s8 opc, s8 disp, s8 basereg, s8 indexreg, s8 scale, s8 reg)
1407 {
1408         emit_rex(1,(reg),(indexreg),(basereg));
1409         *(cd->mcodeptr++) = (((opc)) << 3) + 3;
1410         emit_memindex(cd, (reg),(disp),(basereg),(indexreg),(scale));
1411 }
1412
1413 void emit_alul_memindex_reg(codegendata *cd, s8 opc, s8 disp, s8 basereg, s8 indexreg, s8 scale, s8 reg)
1414 {
1415         emit_rex(0,(reg),(indexreg),(basereg));
1416         *(cd->mcodeptr++) = (((opc)) << 3) + 3;
1417         emit_memindex(cd, (reg),(disp),(basereg),(indexreg),(scale));
1418 }
1419
1420 void emit_test_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
1421         emit_rex(1,(reg),0,(dreg));
1422         *(cd->mcodeptr++) = 0x85;
1423         emit_reg((reg),(dreg));
1424 }
1425
1426
1427 void emit_testl_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
1428         emit_rex(0,(reg),0,(dreg));
1429         *(cd->mcodeptr++) = 0x85;
1430         emit_reg((reg),(dreg));
1431 }
1432
1433
1434 void emit_test_imm_reg(codegendata *cd, s8 imm, s8 reg) {
1435         *(cd->mcodeptr++) = 0xf7;
1436         emit_reg(0,(reg));
1437         emit_imm32((imm));
1438 }
1439
1440
1441 void emit_testw_imm_reg(codegendata *cd, s8 imm, s8 reg) {
1442         *(cd->mcodeptr++) = 0x66;
1443         *(cd->mcodeptr++) = 0xf7;
1444         emit_reg(0,(reg));
1445         emit_imm16((imm));
1446 }
1447
1448
1449 void emit_testb_imm_reg(codegendata *cd, s8 imm, s8 reg) {
1450         *(cd->mcodeptr++) = 0xf6;
1451         emit_reg(0,(reg));
1452         emit_imm8((imm));
1453 }
1454
1455
1456 void emit_lea_membase_reg(codegendata *cd, s8 basereg, s8 disp, s8 reg) {
1457         emit_rex(1,(reg),0,(basereg));
1458         *(cd->mcodeptr++) = 0x8d;
1459         emit_membase(cd, (basereg),(disp),(reg));
1460 }
1461
1462
1463 void emit_leal_membase_reg(codegendata *cd, s8 basereg, s8 disp, s8 reg) {
1464         emit_rex(0,(reg),0,(basereg));
1465         *(cd->mcodeptr++) = 0x8d;
1466         emit_membase(cd, (basereg),(disp),(reg));
1467 }
1468
1469
1470 void emit_incl_reg(codegendata *cd, s8 reg)
1471 {
1472         *(cd->mcodeptr++) = 0xff;
1473         emit_reg(0,(reg));
1474 }
1475
1476 void emit_incq_reg(codegendata *cd, s8 reg)
1477 {
1478         emit_rex(1,0,0,(reg));
1479         *(cd->mcodeptr++) = 0xff;
1480         emit_reg(0,(reg));
1481 }
1482
1483 void emit_incl_membase(codegendata *cd, s8 basereg, s8 disp)
1484 {
1485         emit_rex(0,0,0,(basereg));
1486         *(cd->mcodeptr++) = 0xff;
1487         emit_membase(cd, (basereg),(disp),0);
1488 }
1489
1490 void emit_incq_membase(codegendata *cd, s8 basereg, s8 disp)
1491 {
1492         emit_rex(1,0,0,(basereg));
1493         *(cd->mcodeptr++) = 0xff;
1494         emit_membase(cd, (basereg),(disp),0);
1495 }
1496
1497
1498
1499 void emit_cltd(codegendata *cd) {
1500     *(cd->mcodeptr++) = 0x99;
1501 }
1502
1503
1504 void emit_cqto(codegendata *cd) {
1505         emit_rex(1,0,0,0);
1506         *(cd->mcodeptr++) = 0x99;
1507 }
1508
1509
1510
1511 void emit_imul_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
1512         emit_rex(1,(dreg),0,(reg));
1513         *(cd->mcodeptr++) = 0x0f;
1514         *(cd->mcodeptr++) = 0xaf;
1515         emit_reg((dreg),(reg));
1516 }
1517
1518
1519 void emit_imull_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
1520         emit_rex(0,(dreg),0,(reg));
1521         *(cd->mcodeptr++) = 0x0f;
1522         *(cd->mcodeptr++) = 0xaf;
1523         emit_reg((dreg),(reg));
1524 }
1525
1526
1527 void emit_imul_membase_reg(codegendata *cd, s8 basereg, s8 disp, s8 dreg) {
1528         emit_rex(1,(dreg),0,(basereg));
1529         *(cd->mcodeptr++) = 0x0f;
1530         *(cd->mcodeptr++) = 0xaf;
1531         emit_membase(cd, (basereg),(disp),(dreg));
1532 }
1533
1534
1535 void emit_imull_membase_reg(codegendata *cd, s8 basereg, s8 disp, s8 dreg) {
1536         emit_rex(0,(dreg),0,(basereg));
1537         *(cd->mcodeptr++) = 0x0f;
1538         *(cd->mcodeptr++) = 0xaf;
1539         emit_membase(cd, (basereg),(disp),(dreg));
1540 }
1541
1542
1543 void emit_imul_imm_reg(codegendata *cd, s8 imm, s8 dreg) {
1544         if (IS_IMM8((imm))) {
1545                 emit_rex(1,0,0,(dreg));
1546                 *(cd->mcodeptr++) = 0x6b;
1547                 emit_reg(0,(dreg));
1548                 emit_imm8((imm));
1549         } else {
1550                 emit_rex(1,0,0,(dreg));
1551                 *(cd->mcodeptr++) = 0x69;
1552                 emit_reg(0,(dreg));
1553                 emit_imm32((imm));
1554         }
1555 }
1556
1557
1558 void emit_imul_imm_reg_reg(codegendata *cd, s8 imm, s8 reg, s8 dreg) {
1559         if (IS_IMM8((imm))) {
1560                 emit_rex(1,(dreg),0,(reg));
1561                 *(cd->mcodeptr++) = 0x6b;
1562                 emit_reg((dreg),(reg));
1563                 emit_imm8((imm));
1564         } else {
1565                 emit_rex(1,(dreg),0,(reg));
1566                 *(cd->mcodeptr++) = 0x69;
1567                 emit_reg((dreg),(reg));
1568                 emit_imm32((imm));
1569         }
1570 }
1571
1572
1573 void emit_imull_imm_reg_reg(codegendata *cd, s8 imm, s8 reg, s8 dreg) {
1574         if (IS_IMM8((imm))) {
1575                 emit_rex(0,(dreg),0,(reg));
1576                 *(cd->mcodeptr++) = 0x6b;
1577                 emit_reg((dreg),(reg));
1578                 emit_imm8((imm));
1579         } else {
1580                 emit_rex(0,(dreg),0,(reg));
1581                 *(cd->mcodeptr++) = 0x69;
1582                 emit_reg((dreg),(reg));
1583                 emit_imm32((imm));
1584         }
1585 }
1586
1587
1588 void emit_imul_imm_membase_reg(codegendata *cd, s8 imm, s8 basereg, s8 disp, s8 dreg) {
1589         if (IS_IMM8((imm))) {
1590                 emit_rex(1,(dreg),0,(basereg));
1591                 *(cd->mcodeptr++) = 0x6b;
1592                 emit_membase(cd, (basereg),(disp),(dreg));
1593                 emit_imm8((imm));
1594         } else {
1595                 emit_rex(1,(dreg),0,(basereg));
1596                 *(cd->mcodeptr++) = 0x69;
1597                 emit_membase(cd, (basereg),(disp),(dreg));
1598                 emit_imm32((imm));
1599         }
1600 }
1601
1602
1603 void emit_imull_imm_membase_reg(codegendata *cd, s8 imm, s8 basereg, s8 disp, s8 dreg) {
1604         if (IS_IMM8((imm))) {
1605                 emit_rex(0,(dreg),0,(basereg));
1606                 *(cd->mcodeptr++) = 0x6b;
1607                 emit_membase(cd, (basereg),(disp),(dreg));
1608                 emit_imm8((imm));
1609         } else {
1610                 emit_rex(0,(dreg),0,(basereg));
1611                 *(cd->mcodeptr++) = 0x69;
1612                 emit_membase(cd, (basereg),(disp),(dreg));
1613                 emit_imm32((imm));
1614         }
1615 }
1616
1617
1618 void emit_idiv_reg(codegendata *cd, s8 reg) {
1619         emit_rex(1,0,0,(reg));
1620         *(cd->mcodeptr++) = 0xf7;
1621         emit_reg(7,(reg));
1622 }
1623
1624
1625 void emit_idivl_reg(codegendata *cd, s8 reg) {
1626         emit_rex(0,0,0,(reg));
1627         *(cd->mcodeptr++) = 0xf7;
1628         emit_reg(7,(reg));
1629 }
1630
1631
1632
1633 /*
1634  * shift ops
1635  */
1636 void emit_shift_reg(codegendata *cd, s8 opc, s8 reg) {
1637         emit_rex(1,0,0,(reg));
1638         *(cd->mcodeptr++) = 0xd3;
1639         emit_reg((opc),(reg));
1640 }
1641
1642
1643 void emit_shiftl_reg(codegendata *cd, s8 opc, s8 reg) {
1644         emit_rex(0,0,0,(reg));
1645         *(cd->mcodeptr++) = 0xd3;
1646         emit_reg((opc),(reg));
1647 }
1648
1649
1650 void emit_shift_membase(codegendata *cd, s8 opc, s8 basereg, s8 disp) {
1651         emit_rex(1,0,0,(basereg));
1652         *(cd->mcodeptr++) = 0xd3;
1653         emit_membase(cd, (basereg),(disp),(opc));
1654 }
1655
1656
1657 void emit_shiftl_membase(codegendata *cd, s8 opc, s8 basereg, s8 disp) {
1658         emit_rex(0,0,0,(basereg));
1659         *(cd->mcodeptr++) = 0xd3;
1660         emit_membase(cd, (basereg),(disp),(opc));
1661 }
1662
1663
1664 void emit_shift_imm_reg(codegendata *cd, s8 opc, s8 imm, s8 dreg) {
1665         if ((imm) == 1) {
1666                 emit_rex(1,0,0,(dreg));
1667                 *(cd->mcodeptr++) = 0xd1;
1668                 emit_reg((opc),(dreg));
1669         } else {
1670                 emit_rex(1,0,0,(dreg));
1671                 *(cd->mcodeptr++) = 0xc1;
1672                 emit_reg((opc),(dreg));
1673                 emit_imm8((imm));
1674         }
1675 }
1676
1677
1678 void emit_shiftl_imm_reg(codegendata *cd, s8 opc, s8 imm, s8 dreg) {
1679         if ((imm) == 1) {
1680                 emit_rex(0,0,0,(dreg));
1681                 *(cd->mcodeptr++) = 0xd1;
1682                 emit_reg((opc),(dreg));
1683         } else {
1684                 emit_rex(0,0,0,(dreg));
1685                 *(cd->mcodeptr++) = 0xc1;
1686                 emit_reg((opc),(dreg));
1687                 emit_imm8((imm));
1688         }
1689 }
1690
1691
1692 void emit_shift_imm_membase(codegendata *cd, s8 opc, s8 imm, s8 basereg, s8 disp) {
1693         if ((imm) == 1) {
1694                 emit_rex(1,0,0,(basereg));
1695                 *(cd->mcodeptr++) = 0xd1;
1696                 emit_membase(cd, (basereg),(disp),(opc));
1697         } else {
1698                 emit_rex(1,0,0,(basereg));
1699                 *(cd->mcodeptr++) = 0xc1;
1700                 emit_membase(cd, (basereg),(disp),(opc));
1701                 emit_imm8((imm));
1702         }
1703 }
1704
1705
1706 void emit_shiftl_imm_membase(codegendata *cd, s8 opc, s8 imm, s8 basereg, s8 disp) {
1707         if ((imm) == 1) {
1708                 emit_rex(0,0,0,(basereg));
1709                 *(cd->mcodeptr++) = 0xd1;
1710                 emit_membase(cd, (basereg),(disp),(opc));
1711         } else {
1712                 emit_rex(0,0,0,(basereg));
1713                 *(cd->mcodeptr++) = 0xc1;
1714                 emit_membase(cd, (basereg),(disp),(opc));
1715                 emit_imm8((imm));
1716         }
1717 }
1718
1719
1720
1721 /*
1722  * jump operations
1723  */
1724 void emit_jmp_imm(codegendata *cd, s8 imm) {
1725         *(cd->mcodeptr++) = 0xe9;
1726         emit_imm32((imm));
1727 }
1728
1729 /* like emit_jmp_imm but allows 8 bit optimization */
1730 void emit_jmp_imm2(codegendata *cd, s8 imm) {
1731         if (IS_IMM8(imm)) {
1732                 *(cd->mcodeptr++) = 0xeb;
1733                 emit_imm8((imm));
1734         }
1735         else {
1736                 *(cd->mcodeptr++) = 0xe9;
1737                 emit_imm32((imm));
1738         }
1739 }
1740
1741
1742 void emit_jmp_reg(codegendata *cd, s8 reg) {
1743         emit_rex(0,0,0,(reg));
1744         *(cd->mcodeptr++) = 0xff;
1745         emit_reg(4,(reg));
1746 }
1747
1748
1749 void emit_jcc(codegendata *cd, s8 opc, s8 imm) {
1750         *(cd->mcodeptr++) = 0x0f;
1751         *(cd->mcodeptr++) = (0x80 + (opc));
1752         emit_imm32((imm));
1753 }
1754
1755
1756
1757 /*
1758  * conditional set and move operations
1759  */
1760
1761 /* we need the rex byte to get all low bytes */
1762 void emit_setcc_reg(codegendata *cd, s4 opc, s4 reg)
1763 {
1764         *(cd->mcodeptr++) = (0x40 | (((reg) >> 3) & 0x01));
1765         *(cd->mcodeptr++) = 0x0f;
1766         *(cd->mcodeptr++) = (0x90 + (opc));
1767         emit_reg(0,(reg));
1768 }
1769
1770
1771 /* we need the rex byte to get all low bytes */
1772 void emit_setcc_membase(codegendata *cd, s4 opc, s4 basereg, s4 disp)
1773 {
1774         *(cd->mcodeptr++) = (0x40 | (((basereg) >> 3) & 0x01));
1775         *(cd->mcodeptr++) = 0x0f;
1776         *(cd->mcodeptr++) = (0x90 + (opc));
1777         emit_membase(cd, (basereg),(disp),0);
1778 }
1779
1780
1781 void emit_cmovcc_reg_reg(codegendata *cd, s4 opc, s4 reg, s4 dreg)
1782 {
1783         emit_rex(1,(dreg),0,(reg));
1784         *(cd->mcodeptr++) = 0x0f;
1785         *(cd->mcodeptr++) = (0x40 + (opc));
1786         emit_reg((dreg),(reg));
1787 }
1788
1789
1790 void emit_cmovccl_reg_reg(codegendata *cd, s4 opc, s4 reg, s4 dreg)
1791 {
1792         emit_rex(0,(dreg),0,(reg));
1793         *(cd->mcodeptr++) = 0x0f;
1794         *(cd->mcodeptr++) = (0x40 + (opc));
1795         emit_reg((dreg),(reg));
1796 }
1797
1798
1799 void emit_neg_reg(codegendata *cd, s8 reg)
1800 {
1801         emit_rex(1,0,0,(reg));
1802         *(cd->mcodeptr++) = 0xf7;
1803         emit_reg(3,(reg));
1804 }
1805
1806
1807 void emit_negl_reg(codegendata *cd, s8 reg)
1808 {
1809         emit_rex(0,0,0,(reg));
1810         *(cd->mcodeptr++) = 0xf7;
1811         emit_reg(3,(reg));
1812 }
1813
1814
1815 void emit_push_reg(codegendata *cd, s8 reg) {
1816         emit_rex(0,0,0,(reg));
1817         *(cd->mcodeptr++) = 0x50 + (0x07 & (reg));
1818 }
1819
1820
1821 void emit_push_imm(codegendata *cd, s8 imm) {
1822         *(cd->mcodeptr++) = 0x68;
1823         emit_imm32((imm));
1824 }
1825
1826
1827 void emit_pop_reg(codegendata *cd, s8 reg) {
1828         emit_rex(0,0,0,(reg));
1829         *(cd->mcodeptr++) = 0x58 + (0x07 & (reg));
1830 }
1831
1832
1833 void emit_xchg_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
1834         emit_rex(1,(reg),0,(dreg));
1835         *(cd->mcodeptr++) = 0x87;
1836         emit_reg((reg),(dreg));
1837 }
1838
1839
1840
1841 /*
1842  * call instructions
1843  */
1844 void emit_call_reg(codegendata *cd, s8 reg)
1845 {
1846         emit_rex(0,0,0,(reg));
1847         *(cd->mcodeptr++) = 0xff;
1848         emit_reg(2,(reg));
1849 }
1850
1851
1852 void emit_call_imm(codegendata *cd, s8 imm)
1853 {
1854         *(cd->mcodeptr++) = 0xe8;
1855         emit_imm32((imm));
1856 }
1857
1858
1859 void emit_call_mem(codegendata *cd, ptrint mem)
1860 {
1861         *(cd->mcodeptr++) = 0xff;
1862         emit_mem(2,(mem));
1863 }
1864
1865
1866
1867 /*
1868  * floating point instructions (SSE2)
1869  */
1870 void emit_addsd_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
1871         *(cd->mcodeptr++) = 0xf2;
1872         emit_rex(0,(dreg),0,(reg));
1873         *(cd->mcodeptr++) = 0x0f;
1874         *(cd->mcodeptr++) = 0x58;
1875         emit_reg((dreg),(reg));
1876 }
1877
1878
1879 void emit_addss_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
1880         *(cd->mcodeptr++) = 0xf3;
1881         emit_rex(0,(dreg),0,(reg));
1882         *(cd->mcodeptr++) = 0x0f;
1883         *(cd->mcodeptr++) = 0x58;
1884         emit_reg((dreg),(reg));
1885 }
1886
1887
1888 void emit_cvtsi2ssq_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
1889         *(cd->mcodeptr++) = 0xf3;
1890         emit_rex(1,(dreg),0,(reg));
1891         *(cd->mcodeptr++) = 0x0f;
1892         *(cd->mcodeptr++) = 0x2a;
1893         emit_reg((dreg),(reg));
1894 }
1895
1896
1897 void emit_cvtsi2ss_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
1898         *(cd->mcodeptr++) = 0xf3;
1899         emit_rex(0,(dreg),0,(reg));
1900         *(cd->mcodeptr++) = 0x0f;
1901         *(cd->mcodeptr++) = 0x2a;
1902         emit_reg((dreg),(reg));
1903 }
1904
1905
1906 void emit_cvtsi2sdq_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
1907         *(cd->mcodeptr++) = 0xf2;
1908         emit_rex(1,(dreg),0,(reg));
1909         *(cd->mcodeptr++) = 0x0f;
1910         *(cd->mcodeptr++) = 0x2a;
1911         emit_reg((dreg),(reg));
1912 }
1913
1914
1915 void emit_cvtsi2sd_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
1916         *(cd->mcodeptr++) = 0xf2;
1917         emit_rex(0,(dreg),0,(reg));
1918         *(cd->mcodeptr++) = 0x0f;
1919         *(cd->mcodeptr++) = 0x2a;
1920         emit_reg((dreg),(reg));
1921 }
1922
1923
1924 void emit_cvtss2sd_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
1925         *(cd->mcodeptr++) = 0xf3;
1926         emit_rex(0,(dreg),0,(reg));
1927         *(cd->mcodeptr++) = 0x0f;
1928         *(cd->mcodeptr++) = 0x5a;
1929         emit_reg((dreg),(reg));
1930 }
1931
1932
1933 void emit_cvtsd2ss_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
1934         *(cd->mcodeptr++) = 0xf2;
1935         emit_rex(0,(dreg),0,(reg));
1936         *(cd->mcodeptr++) = 0x0f;
1937         *(cd->mcodeptr++) = 0x5a;
1938         emit_reg((dreg),(reg));
1939 }
1940
1941
1942 void emit_cvttss2siq_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
1943         *(cd->mcodeptr++) = 0xf3;
1944         emit_rex(1,(dreg),0,(reg));
1945         *(cd->mcodeptr++) = 0x0f;
1946         *(cd->mcodeptr++) = 0x2c;
1947         emit_reg((dreg),(reg));
1948 }
1949
1950
1951 void emit_cvttss2si_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
1952         *(cd->mcodeptr++) = 0xf3;
1953         emit_rex(0,(dreg),0,(reg));
1954         *(cd->mcodeptr++) = 0x0f;
1955         *(cd->mcodeptr++) = 0x2c;
1956         emit_reg((dreg),(reg));
1957 }
1958
1959
1960 void emit_cvttsd2siq_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
1961         *(cd->mcodeptr++) = 0xf2;
1962         emit_rex(1,(dreg),0,(reg));
1963         *(cd->mcodeptr++) = 0x0f;
1964         *(cd->mcodeptr++) = 0x2c;
1965         emit_reg((dreg),(reg));
1966 }
1967
1968
1969 void emit_cvttsd2si_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
1970         *(cd->mcodeptr++) = 0xf2;
1971         emit_rex(0,(dreg),0,(reg));
1972         *(cd->mcodeptr++) = 0x0f;
1973         *(cd->mcodeptr++) = 0x2c;
1974         emit_reg((dreg),(reg));
1975 }
1976
1977
1978 void emit_divss_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
1979         *(cd->mcodeptr++) = 0xf3;
1980         emit_rex(0,(dreg),0,(reg));
1981         *(cd->mcodeptr++) = 0x0f;
1982         *(cd->mcodeptr++) = 0x5e;
1983         emit_reg((dreg),(reg));
1984 }
1985
1986
1987 void emit_divsd_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
1988         *(cd->mcodeptr++) = 0xf2;
1989         emit_rex(0,(dreg),0,(reg));
1990         *(cd->mcodeptr++) = 0x0f;
1991         *(cd->mcodeptr++) = 0x5e;
1992         emit_reg((dreg),(reg));
1993 }
1994
1995
1996 void emit_movd_reg_freg(codegendata *cd, s8 reg, s8 freg) {
1997         *(cd->mcodeptr++) = 0x66;
1998         emit_rex(1,(freg),0,(reg));
1999         *(cd->mcodeptr++) = 0x0f;
2000         *(cd->mcodeptr++) = 0x6e;
2001         emit_reg((freg),(reg));
2002 }
2003
2004
2005 void emit_movd_freg_reg(codegendata *cd, s8 freg, s8 reg) {
2006         *(cd->mcodeptr++) = 0x66;
2007         emit_rex(1,(freg),0,(reg));
2008         *(cd->mcodeptr++) = 0x0f;
2009         *(cd->mcodeptr++) = 0x7e;
2010         emit_reg((freg),(reg));
2011 }
2012
2013
2014 void emit_movd_reg_membase(codegendata *cd, s8 reg, s8 basereg, s8 disp) {
2015         *(cd->mcodeptr++) = 0x66;
2016         emit_rex(0,(reg),0,(basereg));
2017         *(cd->mcodeptr++) = 0x0f;
2018         *(cd->mcodeptr++) = 0x7e;
2019         emit_membase(cd, (basereg),(disp),(reg));
2020 }
2021
2022
2023 void emit_movd_reg_memindex(codegendata *cd, s8 reg, s8 disp, s8 basereg, s8 indexreg, s8 scale) {
2024         *(cd->mcodeptr++) = 0x66;
2025         emit_rex(0,(reg),(indexreg),(basereg));
2026         *(cd->mcodeptr++) = 0x0f;
2027         *(cd->mcodeptr++) = 0x7e;
2028         emit_memindex(cd, (reg),(disp),(basereg),(indexreg),(scale));
2029 }
2030
2031
2032 void emit_movd_membase_reg(codegendata *cd, s8 basereg, s8 disp, s8 dreg) {
2033         *(cd->mcodeptr++) = 0x66;
2034         emit_rex(1,(dreg),0,(basereg));
2035         *(cd->mcodeptr++) = 0x0f;
2036         *(cd->mcodeptr++) = 0x6e;
2037         emit_membase(cd, (basereg),(disp),(dreg));
2038 }
2039
2040
2041 void emit_movdl_membase_reg(codegendata *cd, s8 basereg, s8 disp, s8 dreg) {
2042         *(cd->mcodeptr++) = 0x66;
2043         emit_rex(0,(dreg),0,(basereg));
2044         *(cd->mcodeptr++) = 0x0f;
2045         *(cd->mcodeptr++) = 0x6e;
2046         emit_membase(cd, (basereg),(disp),(dreg));
2047 }
2048
2049
2050 void emit_movd_memindex_reg(codegendata *cd, s8 disp, s8 basereg, s8 indexreg, s8 scale, s8 dreg) {
2051         *(cd->mcodeptr++) = 0x66;
2052         emit_rex(0,(dreg),(indexreg),(basereg));
2053         *(cd->mcodeptr++) = 0x0f;
2054         *(cd->mcodeptr++) = 0x6e;
2055         emit_memindex(cd, (dreg),(disp),(basereg),(indexreg),(scale));
2056 }
2057
2058
2059 void emit_movq_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
2060         *(cd->mcodeptr++) = 0xf3;
2061         emit_rex(0,(dreg),0,(reg));
2062         *(cd->mcodeptr++) = 0x0f;
2063         *(cd->mcodeptr++) = 0x7e;
2064         emit_reg((dreg),(reg));
2065 }
2066
2067
2068 void emit_movq_reg_membase(codegendata *cd, s8 reg, s8 basereg, s8 disp) {
2069         *(cd->mcodeptr++) = 0x66;
2070         emit_rex(0,(reg),0,(basereg));
2071         *(cd->mcodeptr++) = 0x0f;
2072         *(cd->mcodeptr++) = 0xd6;
2073         emit_membase(cd, (basereg),(disp),(reg));
2074 }
2075
2076
2077 void emit_movq_membase_reg(codegendata *cd, s8 basereg, s8 disp, s8 dreg) {
2078         *(cd->mcodeptr++) = 0xf3;
2079         emit_rex(0,(dreg),0,(basereg));
2080         *(cd->mcodeptr++) = 0x0f;
2081         *(cd->mcodeptr++) = 0x7e;
2082         emit_membase(cd, (basereg),(disp),(dreg));
2083 }
2084
2085
2086 void emit_movss_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
2087         *(cd->mcodeptr++) = 0xf3;
2088         emit_rex(0,(reg),0,(dreg));
2089         *(cd->mcodeptr++) = 0x0f;
2090         *(cd->mcodeptr++) = 0x10;
2091         emit_reg((reg),(dreg));
2092 }
2093
2094
2095 void emit_movsd_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
2096         *(cd->mcodeptr++) = 0xf2;
2097         emit_rex(0,(reg),0,(dreg));
2098         *(cd->mcodeptr++) = 0x0f;
2099         *(cd->mcodeptr++) = 0x10;
2100         emit_reg((reg),(dreg));
2101 }
2102
2103
2104 void emit_movss_reg_membase(codegendata *cd, s8 reg, s8 basereg, s8 disp) {
2105         *(cd->mcodeptr++) = 0xf3;
2106         emit_rex(0,(reg),0,(basereg));
2107         *(cd->mcodeptr++) = 0x0f;
2108         *(cd->mcodeptr++) = 0x11;
2109         emit_membase(cd, (basereg),(disp),(reg));
2110 }
2111
2112
2113 /* Always emit a REX byte, because the instruction size can be smaller when   */
2114 /* all register indexes are smaller than 7.                                   */
2115 void emit_movss_reg_membase32(codegendata *cd, s8 reg, s8 basereg, s8 disp) {
2116         *(cd->mcodeptr++) = 0xf3;
2117         emit_byte_rex((reg),0,(basereg));
2118         *(cd->mcodeptr++) = 0x0f;
2119         *(cd->mcodeptr++) = 0x11;
2120         emit_membase32(cd, (basereg),(disp),(reg));
2121 }
2122
2123
2124 void emit_movsd_reg_membase(codegendata *cd, s8 reg, s8 basereg, s8 disp) {
2125         *(cd->mcodeptr++) = 0xf2;
2126         emit_rex(0,(reg),0,(basereg));
2127         *(cd->mcodeptr++) = 0x0f;
2128         *(cd->mcodeptr++) = 0x11;
2129         emit_membase(cd, (basereg),(disp),(reg));
2130 }
2131
2132
2133 /* Always emit a REX byte, because the instruction size can be smaller when   */
2134 /* all register indexes are smaller than 7.                                   */
2135 void emit_movsd_reg_membase32(codegendata *cd, s8 reg, s8 basereg, s8 disp) {
2136         *(cd->mcodeptr++) = 0xf2;
2137         emit_byte_rex((reg),0,(basereg));
2138         *(cd->mcodeptr++) = 0x0f;
2139         *(cd->mcodeptr++) = 0x11;
2140         emit_membase32(cd, (basereg),(disp),(reg));
2141 }
2142
2143
2144 void emit_movss_membase_reg(codegendata *cd, s8 basereg, s8 disp, s8 dreg) {
2145         *(cd->mcodeptr++) = 0xf3;
2146         emit_rex(0,(dreg),0,(basereg));
2147         *(cd->mcodeptr++) = 0x0f;
2148         *(cd->mcodeptr++) = 0x10;
2149         emit_membase(cd, (basereg),(disp),(dreg));
2150 }
2151
2152
2153 /* Always emit a REX byte, because the instruction size can be smaller when   */
2154 /* all register indexes are smaller than 7.                                   */
2155 void emit_movss_membase32_reg(codegendata *cd, s8 basereg, s8 disp, s8 dreg) {
2156         *(cd->mcodeptr++) = 0xf3;
2157         emit_byte_rex((dreg),0,(basereg));
2158         *(cd->mcodeptr++) = 0x0f;
2159         *(cd->mcodeptr++) = 0x10;
2160         emit_membase32(cd, (basereg),(disp),(dreg));
2161 }
2162
2163
2164 void emit_movlps_membase_reg(codegendata *cd, s8 basereg, s8 disp, s8 dreg)
2165 {
2166         emit_rex(0,(dreg),0,(basereg));
2167         *(cd->mcodeptr++) = 0x0f;
2168         *(cd->mcodeptr++) = 0x12;
2169         emit_membase(cd, (basereg),(disp),(dreg));
2170 }
2171
2172
2173 void emit_movlps_reg_membase(codegendata *cd, s8 reg, s8 basereg, s8 disp)
2174 {
2175         emit_rex(0,(reg),0,(basereg));
2176         *(cd->mcodeptr++) = 0x0f;
2177         *(cd->mcodeptr++) = 0x13;
2178         emit_membase(cd, (basereg),(disp),(reg));
2179 }
2180
2181
2182 void emit_movsd_membase_reg(codegendata *cd, s8 basereg, s8 disp, s8 dreg) {
2183         *(cd->mcodeptr++) = 0xf2;
2184         emit_rex(0,(dreg),0,(basereg));
2185         *(cd->mcodeptr++) = 0x0f;
2186         *(cd->mcodeptr++) = 0x10;
2187         emit_membase(cd, (basereg),(disp),(dreg));
2188 }
2189
2190
2191 /* Always emit a REX byte, because the instruction size can be smaller when   */
2192 /* all register indexes are smaller than 7.                                   */
2193 void emit_movsd_membase32_reg(codegendata *cd, s8 basereg, s8 disp, s8 dreg) {
2194         *(cd->mcodeptr++) = 0xf2;
2195         emit_byte_rex((dreg),0,(basereg));
2196         *(cd->mcodeptr++) = 0x0f;
2197         *(cd->mcodeptr++) = 0x10;
2198         emit_membase32(cd, (basereg),(disp),(dreg));
2199 }
2200
2201
2202 void emit_movlpd_membase_reg(codegendata *cd, s8 basereg, s8 disp, s8 dreg)
2203 {
2204         *(cd->mcodeptr++) = 0x66;
2205         emit_rex(0,(dreg),0,(basereg));
2206         *(cd->mcodeptr++) = 0x0f;
2207         *(cd->mcodeptr++) = 0x12;
2208         emit_membase(cd, (basereg),(disp),(dreg));
2209 }
2210
2211
2212 void emit_movlpd_reg_membase(codegendata *cd, s8 reg, s8 basereg, s8 disp)
2213 {
2214         *(cd->mcodeptr++) = 0x66;
2215         emit_rex(0,(reg),0,(basereg));
2216         *(cd->mcodeptr++) = 0x0f;
2217         *(cd->mcodeptr++) = 0x13;
2218         emit_membase(cd, (basereg),(disp),(reg));
2219 }
2220
2221
2222 void emit_movss_reg_memindex(codegendata *cd, s8 reg, s8 disp, s8 basereg, s8 indexreg, s8 scale) {
2223         *(cd->mcodeptr++) = 0xf3;
2224         emit_rex(0,(reg),(indexreg),(basereg));
2225         *(cd->mcodeptr++) = 0x0f;
2226         *(cd->mcodeptr++) = 0x11;
2227         emit_memindex(cd, (reg),(disp),(basereg),(indexreg),(scale));
2228 }
2229
2230
2231 void emit_movsd_reg_memindex(codegendata *cd, s8 reg, s8 disp, s8 basereg, s8 indexreg, s8 scale) {
2232         *(cd->mcodeptr++) = 0xf2;
2233         emit_rex(0,(reg),(indexreg),(basereg));
2234         *(cd->mcodeptr++) = 0x0f;
2235         *(cd->mcodeptr++) = 0x11;
2236         emit_memindex(cd, (reg),(disp),(basereg),(indexreg),(scale));
2237 }
2238
2239
2240 void emit_movss_memindex_reg(codegendata *cd, s8 disp, s8 basereg, s8 indexreg, s8 scale, s8 dreg) {
2241         *(cd->mcodeptr++) = 0xf3;
2242         emit_rex(0,(dreg),(indexreg),(basereg));
2243         *(cd->mcodeptr++) = 0x0f;
2244         *(cd->mcodeptr++) = 0x10;
2245         emit_memindex(cd, (dreg),(disp),(basereg),(indexreg),(scale));
2246 }
2247
2248
2249 void emit_movsd_memindex_reg(codegendata *cd, s8 disp, s8 basereg, s8 indexreg, s8 scale, s8 dreg) {
2250         *(cd->mcodeptr++) = 0xf2;
2251         emit_rex(0,(dreg),(indexreg),(basereg));
2252         *(cd->mcodeptr++) = 0x0f;
2253         *(cd->mcodeptr++) = 0x10;
2254         emit_memindex(cd, (dreg),(disp),(basereg),(indexreg),(scale));
2255 }
2256
2257
2258 void emit_mulss_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
2259         *(cd->mcodeptr++) = 0xf3;
2260         emit_rex(0,(dreg),0,(reg));
2261         *(cd->mcodeptr++) = 0x0f;
2262         *(cd->mcodeptr++) = 0x59;
2263         emit_reg((dreg),(reg));
2264 }
2265
2266
2267 void emit_mulsd_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
2268         *(cd->mcodeptr++) = 0xf2;
2269         emit_rex(0,(dreg),0,(reg));
2270         *(cd->mcodeptr++) = 0x0f;
2271         *(cd->mcodeptr++) = 0x59;
2272         emit_reg((dreg),(reg));
2273 }
2274
2275
2276 void emit_subss_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
2277         *(cd->mcodeptr++) = 0xf3;
2278         emit_rex(0,(dreg),0,(reg));
2279         *(cd->mcodeptr++) = 0x0f;
2280         *(cd->mcodeptr++) = 0x5c;
2281         emit_reg((dreg),(reg));
2282 }
2283
2284
2285 void emit_subsd_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
2286         *(cd->mcodeptr++) = 0xf2;
2287         emit_rex(0,(dreg),0,(reg));
2288         *(cd->mcodeptr++) = 0x0f;
2289         *(cd->mcodeptr++) = 0x5c;
2290         emit_reg((dreg),(reg));
2291 }
2292
2293
2294 void emit_ucomiss_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
2295         emit_rex(0,(dreg),0,(reg));
2296         *(cd->mcodeptr++) = 0x0f;
2297         *(cd->mcodeptr++) = 0x2e;
2298         emit_reg((dreg),(reg));
2299 }
2300
2301
2302 void emit_ucomisd_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
2303         *(cd->mcodeptr++) = 0x66;
2304         emit_rex(0,(dreg),0,(reg));
2305         *(cd->mcodeptr++) = 0x0f;
2306         *(cd->mcodeptr++) = 0x2e;
2307         emit_reg((dreg),(reg));
2308 }
2309
2310
2311 void emit_xorps_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
2312         emit_rex(0,(dreg),0,(reg));
2313         *(cd->mcodeptr++) = 0x0f;
2314         *(cd->mcodeptr++) = 0x57;
2315         emit_reg((dreg),(reg));
2316 }
2317
2318
2319 void emit_xorps_membase_reg(codegendata *cd, s8 basereg, s8 disp, s8 dreg) {
2320         emit_rex(0,(dreg),0,(basereg));
2321         *(cd->mcodeptr++) = 0x0f;
2322         *(cd->mcodeptr++) = 0x57;
2323         emit_membase(cd, (basereg),(disp),(dreg));
2324 }
2325
2326
2327 void emit_xorpd_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
2328         *(cd->mcodeptr++) = 0x66;
2329         emit_rex(0,(dreg),0,(reg));
2330         *(cd->mcodeptr++) = 0x0f;
2331         *(cd->mcodeptr++) = 0x57;
2332         emit_reg((dreg),(reg));
2333 }
2334
2335
2336 void emit_xorpd_membase_reg(codegendata *cd, s8 basereg, s8 disp, s8 dreg) {
2337         *(cd->mcodeptr++) = 0x66;
2338         emit_rex(0,(dreg),0,(basereg));
2339         *(cd->mcodeptr++) = 0x0f;
2340         *(cd->mcodeptr++) = 0x57;
2341         emit_membase(cd, (basereg),(disp),(dreg));
2342 }
2343
2344
2345 /* system instructions ********************************************************/
2346
2347 void emit_rdtsc(codegendata *cd)
2348 {
2349         *(cd->mcodeptr++) = 0x0f;
2350         *(cd->mcodeptr++) = 0x31;
2351 }
2352
2353
2354 /*
2355  * These are local overrides for various environment variables in Emacs.
2356  * Please do not remove this and leave it at the end of the file, where
2357  * Emacs will automagically detect them.
2358  * ---------------------------------------------------------------------
2359  * Local variables:
2360  * mode: c
2361  * indent-tabs-mode: t
2362  * c-basic-offset: 4
2363  * tab-width: 4
2364  * End:
2365  */