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