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