163f840c26fb30a299827140c67dd09d93824d9e
[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 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_movzbq_reg_reg(codegendata *cd, s8 reg, s8 dreg)
1183 {
1184         emit_rex(1,(dreg),0,(reg));
1185         *(cd->mcodeptr++) = 0x0f;
1186         *(cd->mcodeptr++) = 0xb6;
1187         /* XXX: why do reg and dreg have to be exchanged */
1188         emit_reg((dreg),(reg));
1189 }
1190
1191
1192 void emit_movzwq_reg_reg(codegendata *cd, s8 reg, s8 dreg)
1193 {
1194         emit_rex(1,(dreg),0,(reg));
1195         *(cd->mcodeptr++) = 0x0f;
1196         *(cd->mcodeptr++) = 0xb7;
1197         /* XXX: why do reg and dreg have to be exchanged */
1198         emit_reg((dreg),(reg));
1199 }
1200
1201
1202 void emit_movswq_memindex_reg(codegendata *cd, s8 disp, s8 basereg, s8 indexreg, s8 scale, s8 reg) {
1203         emit_rex(1,(reg),(indexreg),(basereg));
1204         *(cd->mcodeptr++) = 0x0f;
1205         *(cd->mcodeptr++) = 0xbf;
1206         emit_memindex(cd, (reg),(disp),(basereg),(indexreg),(scale));
1207 }
1208
1209
1210 void emit_movsbq_memindex_reg(codegendata *cd, s8 disp, s8 basereg, s8 indexreg, s8 scale, s8 reg) {
1211         emit_rex(1,(reg),(indexreg),(basereg));
1212         *(cd->mcodeptr++) = 0x0f;
1213         *(cd->mcodeptr++) = 0xbe;
1214         emit_memindex(cd, (reg),(disp),(basereg),(indexreg),(scale));
1215 }
1216
1217
1218 void emit_movzwq_memindex_reg(codegendata *cd, s8 disp, s8 basereg, s8 indexreg, s8 scale, s8 reg) {
1219         emit_rex(1,(reg),(indexreg),(basereg));
1220         *(cd->mcodeptr++) = 0x0f;
1221         *(cd->mcodeptr++) = 0xb7;
1222         emit_memindex(cd, (reg),(disp),(basereg),(indexreg),(scale));
1223 }
1224
1225
1226 void emit_mov_imm_memindex(codegendata *cd, s4 imm, s4 disp, s4 basereg, s4 indexreg, s4 scale)
1227 {
1228         emit_rex(1,0,(indexreg),(basereg));
1229         *(cd->mcodeptr++) = 0xc7;
1230         emit_memindex(cd, 0,(disp),(basereg),(indexreg),(scale));
1231         emit_imm32((imm));
1232 }
1233
1234
1235 void emit_movl_imm_memindex(codegendata *cd, s4 imm, s4 disp, s4 basereg, s4 indexreg, s4 scale)
1236 {
1237         emit_rex(0,0,(indexreg),(basereg));
1238         *(cd->mcodeptr++) = 0xc7;
1239         emit_memindex(cd, 0,(disp),(basereg),(indexreg),(scale));
1240         emit_imm32((imm));
1241 }
1242
1243
1244 void emit_movw_imm_memindex(codegendata *cd, s4 imm, s4 disp, s4 basereg, s4 indexreg, s4 scale)
1245 {
1246         *(cd->mcodeptr++) = 0x66;
1247         emit_rex(0,0,(indexreg),(basereg));
1248         *(cd->mcodeptr++) = 0xc7;
1249         emit_memindex(cd, 0,(disp),(basereg),(indexreg),(scale));
1250         emit_imm16((imm));
1251 }
1252
1253
1254 void emit_movb_imm_memindex(codegendata *cd, s4 imm, s4 disp, s4 basereg, s4 indexreg, s4 scale)
1255 {
1256         emit_rex(0,0,(indexreg),(basereg));
1257         *(cd->mcodeptr++) = 0xc6;
1258         emit_memindex(cd, 0,(disp),(basereg),(indexreg),(scale));
1259         emit_imm8((imm));
1260 }
1261
1262
1263 void emit_mov_mem_reg(codegendata *cd, s4 disp, s4 dreg)
1264 {
1265         emit_rex(1, dreg, 0, 0);
1266         *(cd->mcodeptr++) = 0x8b;
1267         emit_address_byte(0, dreg, 4);
1268         emit_mem(4, disp);
1269 }
1270
1271
1272 /*
1273  * alu operations
1274  */
1275 void emit_alu_reg_reg(codegendata *cd, s8 opc, s8 reg, s8 dreg)
1276 {
1277         emit_rex(1,(reg),0,(dreg));
1278         *(cd->mcodeptr++) = (((opc)) << 3) + 1;
1279         emit_reg((reg),(dreg));
1280 }
1281
1282
1283 void emit_alul_reg_reg(codegendata *cd, s8 opc, s8 reg, s8 dreg)
1284 {
1285         emit_rex(0,(reg),0,(dreg));
1286         *(cd->mcodeptr++) = (((opc)) << 3) + 1;
1287         emit_reg((reg),(dreg));
1288 }
1289
1290
1291 void emit_alu_reg_membase(codegendata *cd, s8 opc, s8 reg, s8 basereg, s8 disp)
1292 {
1293         emit_rex(1,(reg),0,(basereg));
1294         *(cd->mcodeptr++) = (((opc)) << 3) + 1;
1295         emit_membase(cd, (basereg),(disp),(reg));
1296 }
1297
1298
1299 void emit_alul_reg_membase(codegendata *cd, s8 opc, s8 reg, s8 basereg, s8 disp)
1300 {
1301         emit_rex(0,(reg),0,(basereg));
1302         *(cd->mcodeptr++) = (((opc)) << 3) + 1;
1303         emit_membase(cd, (basereg),(disp),(reg));
1304 }
1305
1306
1307 void emit_alu_membase_reg(codegendata *cd, s8 opc, s8 basereg, s8 disp, s8 reg)
1308 {
1309         emit_rex(1,(reg),0,(basereg));
1310         *(cd->mcodeptr++) = (((opc)) << 3) + 3;
1311         emit_membase(cd, (basereg),(disp),(reg));
1312 }
1313
1314
1315 void emit_alul_membase_reg(codegendata *cd, s8 opc, s8 basereg, s8 disp, s8 reg)
1316 {
1317         emit_rex(0,(reg),0,(basereg));
1318         *(cd->mcodeptr++) = (((opc)) << 3) + 3;
1319         emit_membase(cd, (basereg),(disp),(reg));
1320 }
1321
1322
1323 void emit_alu_imm_reg(codegendata *cd, s8 opc, s8 imm, s8 dreg) {
1324         if (IS_IMM8(imm)) {
1325                 emit_rex(1,0,0,(dreg));
1326                 *(cd->mcodeptr++) = 0x83;
1327                 emit_reg((opc),(dreg));
1328                 emit_imm8((imm));
1329         } else {
1330                 emit_rex(1,0,0,(dreg));
1331                 *(cd->mcodeptr++) = 0x81;
1332                 emit_reg((opc),(dreg));
1333                 emit_imm32((imm));
1334         }
1335 }
1336
1337
1338 void emit_alu_imm32_reg(codegendata *cd, s4 opc, s4 imm, s4 dreg)
1339 {
1340         emit_rex(1,0,0,(dreg));
1341         *(cd->mcodeptr++) = 0x81;
1342         emit_reg((opc),(dreg));
1343         emit_imm32((imm));
1344 }
1345
1346
1347 void emit_alul_imm32_reg(codegendata *cd, s4 opc, s4 imm, s4 dreg)
1348 {
1349         emit_rex(0,0,0,(dreg));
1350         *(cd->mcodeptr++) = 0x81;
1351         emit_reg((opc),(dreg));
1352         emit_imm32((imm));
1353 }
1354
1355
1356 void emit_alul_imm_reg(codegendata *cd, s8 opc, s8 imm, s8 dreg) {
1357         if (IS_IMM8(imm)) {
1358                 emit_rex(0,0,0,(dreg));
1359                 *(cd->mcodeptr++) = 0x83;
1360                 emit_reg((opc),(dreg));
1361                 emit_imm8((imm));
1362         } else {
1363                 emit_rex(0,0,0,(dreg));
1364                 *(cd->mcodeptr++) = 0x81;
1365                 emit_reg((opc),(dreg));
1366                 emit_imm32((imm));
1367         }
1368 }
1369
1370
1371 void emit_alu_imm_membase(codegendata *cd, s8 opc, s8 imm, s8 basereg, s8 disp) {
1372         if (IS_IMM8(imm)) {
1373                 emit_rex(1,0,0,(basereg));
1374                 *(cd->mcodeptr++) = 0x83;
1375                 emit_membase(cd, (basereg),(disp),(opc));
1376                 emit_imm8((imm));
1377         } else {
1378                 emit_rex(1,0,0,(basereg));
1379                 *(cd->mcodeptr++) = 0x81;
1380                 emit_membase(cd, (basereg),(disp),(opc));
1381                 emit_imm32((imm));
1382         }
1383 }
1384
1385
1386 void emit_alul_imm_membase(codegendata *cd, s8 opc, s8 imm, s8 basereg, s8 disp) {
1387         if (IS_IMM8(imm)) {
1388                 emit_rex(0,0,0,(basereg));
1389                 *(cd->mcodeptr++) = 0x83;
1390                 emit_membase(cd, (basereg),(disp),(opc));
1391                 emit_imm8((imm));
1392         } else {
1393                 emit_rex(0,0,0,(basereg));
1394                 *(cd->mcodeptr++) = 0x81;
1395                 emit_membase(cd, (basereg),(disp),(opc));
1396                 emit_imm32((imm));
1397         }
1398 }
1399
1400
1401 void emit_test_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
1402         emit_rex(1,(reg),0,(dreg));
1403         *(cd->mcodeptr++) = 0x85;
1404         emit_reg((reg),(dreg));
1405 }
1406
1407
1408 void emit_testl_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
1409         emit_rex(0,(reg),0,(dreg));
1410         *(cd->mcodeptr++) = 0x85;
1411         emit_reg((reg),(dreg));
1412 }
1413
1414
1415 void emit_test_imm_reg(codegendata *cd, s8 imm, s8 reg) {
1416         *(cd->mcodeptr++) = 0xf7;
1417         emit_reg(0,(reg));
1418         emit_imm32((imm));
1419 }
1420
1421
1422 void emit_testw_imm_reg(codegendata *cd, s8 imm, s8 reg) {
1423         *(cd->mcodeptr++) = 0x66;
1424         *(cd->mcodeptr++) = 0xf7;
1425         emit_reg(0,(reg));
1426         emit_imm16((imm));
1427 }
1428
1429
1430 void emit_testb_imm_reg(codegendata *cd, s8 imm, s8 reg) {
1431         *(cd->mcodeptr++) = 0xf6;
1432         emit_reg(0,(reg));
1433         emit_imm8((imm));
1434 }
1435
1436
1437 void emit_lea_membase_reg(codegendata *cd, s8 basereg, s8 disp, s8 reg) {
1438         emit_rex(1,(reg),0,(basereg));
1439         *(cd->mcodeptr++) = 0x8d;
1440         emit_membase(cd, (basereg),(disp),(reg));
1441 }
1442
1443
1444 void emit_leal_membase_reg(codegendata *cd, s8 basereg, s8 disp, s8 reg) {
1445         emit_rex(0,(reg),0,(basereg));
1446         *(cd->mcodeptr++) = 0x8d;
1447         emit_membase(cd, (basereg),(disp),(reg));
1448 }
1449
1450
1451
1452 void emit_incl_membase(codegendata *cd, s8 basereg, s8 disp)
1453 {
1454         emit_rex(0,0,0,(basereg));
1455         *(cd->mcodeptr++) = 0xff;
1456         emit_membase(cd, (basereg),(disp),0);
1457 }
1458
1459
1460
1461 void emit_cltd(codegendata *cd) {
1462     *(cd->mcodeptr++) = 0x99;
1463 }
1464
1465
1466 void emit_cqto(codegendata *cd) {
1467         emit_rex(1,0,0,0);
1468         *(cd->mcodeptr++) = 0x99;
1469 }
1470
1471
1472
1473 void emit_imul_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
1474         emit_rex(1,(dreg),0,(reg));
1475         *(cd->mcodeptr++) = 0x0f;
1476         *(cd->mcodeptr++) = 0xaf;
1477         emit_reg((dreg),(reg));
1478 }
1479
1480
1481 void emit_imull_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
1482         emit_rex(0,(dreg),0,(reg));
1483         *(cd->mcodeptr++) = 0x0f;
1484         *(cd->mcodeptr++) = 0xaf;
1485         emit_reg((dreg),(reg));
1486 }
1487
1488
1489 void emit_imul_membase_reg(codegendata *cd, s8 basereg, s8 disp, s8 dreg) {
1490         emit_rex(1,(dreg),0,(basereg));
1491         *(cd->mcodeptr++) = 0x0f;
1492         *(cd->mcodeptr++) = 0xaf;
1493         emit_membase(cd, (basereg),(disp),(dreg));
1494 }
1495
1496
1497 void emit_imull_membase_reg(codegendata *cd, s8 basereg, s8 disp, s8 dreg) {
1498         emit_rex(0,(dreg),0,(basereg));
1499         *(cd->mcodeptr++) = 0x0f;
1500         *(cd->mcodeptr++) = 0xaf;
1501         emit_membase(cd, (basereg),(disp),(dreg));
1502 }
1503
1504
1505 void emit_imul_imm_reg(codegendata *cd, s8 imm, s8 dreg) {
1506         if (IS_IMM8((imm))) {
1507                 emit_rex(1,0,0,(dreg));
1508                 *(cd->mcodeptr++) = 0x6b;
1509                 emit_reg(0,(dreg));
1510                 emit_imm8((imm));
1511         } else {
1512                 emit_rex(1,0,0,(dreg));
1513                 *(cd->mcodeptr++) = 0x69;
1514                 emit_reg(0,(dreg));
1515                 emit_imm32((imm));
1516         }
1517 }
1518
1519
1520 void emit_imul_imm_reg_reg(codegendata *cd, s8 imm, s8 reg, s8 dreg) {
1521         if (IS_IMM8((imm))) {
1522                 emit_rex(1,(dreg),0,(reg));
1523                 *(cd->mcodeptr++) = 0x6b;
1524                 emit_reg((dreg),(reg));
1525                 emit_imm8((imm));
1526         } else {
1527                 emit_rex(1,(dreg),0,(reg));
1528                 *(cd->mcodeptr++) = 0x69;
1529                 emit_reg((dreg),(reg));
1530                 emit_imm32((imm));
1531         }
1532 }
1533
1534
1535 void emit_imull_imm_reg_reg(codegendata *cd, s8 imm, s8 reg, s8 dreg) {
1536         if (IS_IMM8((imm))) {
1537                 emit_rex(0,(dreg),0,(reg));
1538                 *(cd->mcodeptr++) = 0x6b;
1539                 emit_reg((dreg),(reg));
1540                 emit_imm8((imm));
1541         } else {
1542                 emit_rex(0,(dreg),0,(reg));
1543                 *(cd->mcodeptr++) = 0x69;
1544                 emit_reg((dreg),(reg));
1545                 emit_imm32((imm));
1546         }
1547 }
1548
1549
1550 void emit_imul_imm_membase_reg(codegendata *cd, s8 imm, s8 basereg, s8 disp, s8 dreg) {
1551         if (IS_IMM8((imm))) {
1552                 emit_rex(1,(dreg),0,(basereg));
1553                 *(cd->mcodeptr++) = 0x6b;
1554                 emit_membase(cd, (basereg),(disp),(dreg));
1555                 emit_imm8((imm));
1556         } else {
1557                 emit_rex(1,(dreg),0,(basereg));
1558                 *(cd->mcodeptr++) = 0x69;
1559                 emit_membase(cd, (basereg),(disp),(dreg));
1560                 emit_imm32((imm));
1561         }
1562 }
1563
1564
1565 void emit_imull_imm_membase_reg(codegendata *cd, s8 imm, s8 basereg, s8 disp, s8 dreg) {
1566         if (IS_IMM8((imm))) {
1567                 emit_rex(0,(dreg),0,(basereg));
1568                 *(cd->mcodeptr++) = 0x6b;
1569                 emit_membase(cd, (basereg),(disp),(dreg));
1570                 emit_imm8((imm));
1571         } else {
1572                 emit_rex(0,(dreg),0,(basereg));
1573                 *(cd->mcodeptr++) = 0x69;
1574                 emit_membase(cd, (basereg),(disp),(dreg));
1575                 emit_imm32((imm));
1576         }
1577 }
1578
1579
1580 void emit_idiv_reg(codegendata *cd, s8 reg) {
1581         emit_rex(1,0,0,(reg));
1582         *(cd->mcodeptr++) = 0xf7;
1583         emit_reg(7,(reg));
1584 }
1585
1586
1587 void emit_idivl_reg(codegendata *cd, s8 reg) {
1588         emit_rex(0,0,0,(reg));
1589         *(cd->mcodeptr++) = 0xf7;
1590         emit_reg(7,(reg));
1591 }
1592
1593
1594
1595 /*
1596  * shift ops
1597  */
1598 void emit_shift_reg(codegendata *cd, s8 opc, s8 reg) {
1599         emit_rex(1,0,0,(reg));
1600         *(cd->mcodeptr++) = 0xd3;
1601         emit_reg((opc),(reg));
1602 }
1603
1604
1605 void emit_shiftl_reg(codegendata *cd, s8 opc, s8 reg) {
1606         emit_rex(0,0,0,(reg));
1607         *(cd->mcodeptr++) = 0xd3;
1608         emit_reg((opc),(reg));
1609 }
1610
1611
1612 void emit_shift_membase(codegendata *cd, s8 opc, s8 basereg, s8 disp) {
1613         emit_rex(1,0,0,(basereg));
1614         *(cd->mcodeptr++) = 0xd3;
1615         emit_membase(cd, (basereg),(disp),(opc));
1616 }
1617
1618
1619 void emit_shiftl_membase(codegendata *cd, s8 opc, s8 basereg, s8 disp) {
1620         emit_rex(0,0,0,(basereg));
1621         *(cd->mcodeptr++) = 0xd3;
1622         emit_membase(cd, (basereg),(disp),(opc));
1623 }
1624
1625
1626 void emit_shift_imm_reg(codegendata *cd, s8 opc, s8 imm, s8 dreg) {
1627         if ((imm) == 1) {
1628                 emit_rex(1,0,0,(dreg));
1629                 *(cd->mcodeptr++) = 0xd1;
1630                 emit_reg((opc),(dreg));
1631         } else {
1632                 emit_rex(1,0,0,(dreg));
1633                 *(cd->mcodeptr++) = 0xc1;
1634                 emit_reg((opc),(dreg));
1635                 emit_imm8((imm));
1636         }
1637 }
1638
1639
1640 void emit_shiftl_imm_reg(codegendata *cd, s8 opc, s8 imm, s8 dreg) {
1641         if ((imm) == 1) {
1642                 emit_rex(0,0,0,(dreg));
1643                 *(cd->mcodeptr++) = 0xd1;
1644                 emit_reg((opc),(dreg));
1645         } else {
1646                 emit_rex(0,0,0,(dreg));
1647                 *(cd->mcodeptr++) = 0xc1;
1648                 emit_reg((opc),(dreg));
1649                 emit_imm8((imm));
1650         }
1651 }
1652
1653
1654 void emit_shift_imm_membase(codegendata *cd, s8 opc, s8 imm, s8 basereg, s8 disp) {
1655         if ((imm) == 1) {
1656                 emit_rex(1,0,0,(basereg));
1657                 *(cd->mcodeptr++) = 0xd1;
1658                 emit_membase(cd, (basereg),(disp),(opc));
1659         } else {
1660                 emit_rex(1,0,0,(basereg));
1661                 *(cd->mcodeptr++) = 0xc1;
1662                 emit_membase(cd, (basereg),(disp),(opc));
1663                 emit_imm8((imm));
1664         }
1665 }
1666
1667
1668 void emit_shiftl_imm_membase(codegendata *cd, s8 opc, s8 imm, s8 basereg, s8 disp) {
1669         if ((imm) == 1) {
1670                 emit_rex(0,0,0,(basereg));
1671                 *(cd->mcodeptr++) = 0xd1;
1672                 emit_membase(cd, (basereg),(disp),(opc));
1673         } else {
1674                 emit_rex(0,0,0,(basereg));
1675                 *(cd->mcodeptr++) = 0xc1;
1676                 emit_membase(cd, (basereg),(disp),(opc));
1677                 emit_imm8((imm));
1678         }
1679 }
1680
1681
1682
1683 /*
1684  * jump operations
1685  */
1686 void emit_jmp_imm(codegendata *cd, s8 imm) {
1687         *(cd->mcodeptr++) = 0xe9;
1688         emit_imm32((imm));
1689 }
1690
1691
1692 void emit_jmp_reg(codegendata *cd, s8 reg) {
1693         emit_rex(0,0,0,(reg));
1694         *(cd->mcodeptr++) = 0xff;
1695         emit_reg(4,(reg));
1696 }
1697
1698
1699 void emit_jcc(codegendata *cd, s8 opc, s8 imm) {
1700         *(cd->mcodeptr++) = 0x0f;
1701         *(cd->mcodeptr++) = (0x80 + (opc));
1702         emit_imm32((imm));
1703 }
1704
1705
1706
1707 /*
1708  * conditional set and move operations
1709  */
1710
1711 /* we need the rex byte to get all low bytes */
1712 void emit_setcc_reg(codegendata *cd, s4 opc, s4 reg)
1713 {
1714         *(cd->mcodeptr++) = (0x40 | (((reg) >> 3) & 0x01));
1715         *(cd->mcodeptr++) = 0x0f;
1716         *(cd->mcodeptr++) = (0x90 + (opc));
1717         emit_reg(0,(reg));
1718 }
1719
1720
1721 /* we need the rex byte to get all low bytes */
1722 void emit_setcc_membase(codegendata *cd, s4 opc, s4 basereg, s4 disp)
1723 {
1724         *(cd->mcodeptr++) = (0x40 | (((basereg) >> 3) & 0x01));
1725         *(cd->mcodeptr++) = 0x0f;
1726         *(cd->mcodeptr++) = (0x90 + (opc));
1727         emit_membase(cd, (basereg),(disp),0);
1728 }
1729
1730
1731 void emit_cmovcc_reg_reg(codegendata *cd, s4 opc, s4 reg, s4 dreg)
1732 {
1733         emit_rex(1,(dreg),0,(reg));
1734         *(cd->mcodeptr++) = 0x0f;
1735         *(cd->mcodeptr++) = (0x40 + (opc));
1736         emit_reg((dreg),(reg));
1737 }
1738
1739
1740 void emit_cmovccl_reg_reg(codegendata *cd, s4 opc, s4 reg, s4 dreg)
1741 {
1742         emit_rex(0,(dreg),0,(reg));
1743         *(cd->mcodeptr++) = 0x0f;
1744         *(cd->mcodeptr++) = (0x40 + (opc));
1745         emit_reg((dreg),(reg));
1746 }
1747
1748
1749 void emit_neg_reg(codegendata *cd, s8 reg)
1750 {
1751         emit_rex(1,0,0,(reg));
1752         *(cd->mcodeptr++) = 0xf7;
1753         emit_reg(3,(reg));
1754 }
1755
1756
1757 void emit_negl_reg(codegendata *cd, s8 reg)
1758 {
1759         emit_rex(0,0,0,(reg));
1760         *(cd->mcodeptr++) = 0xf7;
1761         emit_reg(3,(reg));
1762 }
1763
1764
1765 void emit_push_reg(codegendata *cd, s8 reg) {
1766         emit_rex(0,0,0,(reg));
1767         *(cd->mcodeptr++) = 0x50 + (0x07 & (reg));
1768 }
1769
1770
1771 void emit_push_imm(codegendata *cd, s8 imm) {
1772         *(cd->mcodeptr++) = 0x68;
1773         emit_imm32((imm));
1774 }
1775
1776
1777 void emit_pop_reg(codegendata *cd, s8 reg) {
1778         emit_rex(0,0,0,(reg));
1779         *(cd->mcodeptr++) = 0x58 + (0x07 & (reg));
1780 }
1781
1782
1783 void emit_xchg_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
1784         emit_rex(1,(reg),0,(dreg));
1785         *(cd->mcodeptr++) = 0x87;
1786         emit_reg((reg),(dreg));
1787 }
1788
1789
1790
1791 /*
1792  * call instructions
1793  */
1794 void emit_call_reg(codegendata *cd, s8 reg)
1795 {
1796         emit_rex(0,0,0,(reg));
1797         *(cd->mcodeptr++) = 0xff;
1798         emit_reg(2,(reg));
1799 }
1800
1801
1802 void emit_call_imm(codegendata *cd, s8 imm)
1803 {
1804         *(cd->mcodeptr++) = 0xe8;
1805         emit_imm32((imm));
1806 }
1807
1808
1809 void emit_call_mem(codegendata *cd, ptrint mem)
1810 {
1811         *(cd->mcodeptr++) = 0xff;
1812         emit_mem(2,(mem));
1813 }
1814
1815
1816
1817 /*
1818  * floating point instructions (SSE2)
1819  */
1820 void emit_addsd_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
1821         *(cd->mcodeptr++) = 0xf2;
1822         emit_rex(0,(dreg),0,(reg));
1823         *(cd->mcodeptr++) = 0x0f;
1824         *(cd->mcodeptr++) = 0x58;
1825         emit_reg((dreg),(reg));
1826 }
1827
1828
1829 void emit_addss_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
1830         *(cd->mcodeptr++) = 0xf3;
1831         emit_rex(0,(dreg),0,(reg));
1832         *(cd->mcodeptr++) = 0x0f;
1833         *(cd->mcodeptr++) = 0x58;
1834         emit_reg((dreg),(reg));
1835 }
1836
1837
1838 void emit_cvtsi2ssq_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
1839         *(cd->mcodeptr++) = 0xf3;
1840         emit_rex(1,(dreg),0,(reg));
1841         *(cd->mcodeptr++) = 0x0f;
1842         *(cd->mcodeptr++) = 0x2a;
1843         emit_reg((dreg),(reg));
1844 }
1845
1846
1847 void emit_cvtsi2ss_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
1848         *(cd->mcodeptr++) = 0xf3;
1849         emit_rex(0,(dreg),0,(reg));
1850         *(cd->mcodeptr++) = 0x0f;
1851         *(cd->mcodeptr++) = 0x2a;
1852         emit_reg((dreg),(reg));
1853 }
1854
1855
1856 void emit_cvtsi2sdq_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
1857         *(cd->mcodeptr++) = 0xf2;
1858         emit_rex(1,(dreg),0,(reg));
1859         *(cd->mcodeptr++) = 0x0f;
1860         *(cd->mcodeptr++) = 0x2a;
1861         emit_reg((dreg),(reg));
1862 }
1863
1864
1865 void emit_cvtsi2sd_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
1866         *(cd->mcodeptr++) = 0xf2;
1867         emit_rex(0,(dreg),0,(reg));
1868         *(cd->mcodeptr++) = 0x0f;
1869         *(cd->mcodeptr++) = 0x2a;
1870         emit_reg((dreg),(reg));
1871 }
1872
1873
1874 void emit_cvtss2sd_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
1875         *(cd->mcodeptr++) = 0xf3;
1876         emit_rex(0,(dreg),0,(reg));
1877         *(cd->mcodeptr++) = 0x0f;
1878         *(cd->mcodeptr++) = 0x5a;
1879         emit_reg((dreg),(reg));
1880 }
1881
1882
1883 void emit_cvtsd2ss_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
1884         *(cd->mcodeptr++) = 0xf2;
1885         emit_rex(0,(dreg),0,(reg));
1886         *(cd->mcodeptr++) = 0x0f;
1887         *(cd->mcodeptr++) = 0x5a;
1888         emit_reg((dreg),(reg));
1889 }
1890
1891
1892 void emit_cvttss2siq_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
1893         *(cd->mcodeptr++) = 0xf3;
1894         emit_rex(1,(dreg),0,(reg));
1895         *(cd->mcodeptr++) = 0x0f;
1896         *(cd->mcodeptr++) = 0x2c;
1897         emit_reg((dreg),(reg));
1898 }
1899
1900
1901 void emit_cvttss2si_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
1902         *(cd->mcodeptr++) = 0xf3;
1903         emit_rex(0,(dreg),0,(reg));
1904         *(cd->mcodeptr++) = 0x0f;
1905         *(cd->mcodeptr++) = 0x2c;
1906         emit_reg((dreg),(reg));
1907 }
1908
1909
1910 void emit_cvttsd2siq_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
1911         *(cd->mcodeptr++) = 0xf2;
1912         emit_rex(1,(dreg),0,(reg));
1913         *(cd->mcodeptr++) = 0x0f;
1914         *(cd->mcodeptr++) = 0x2c;
1915         emit_reg((dreg),(reg));
1916 }
1917
1918
1919 void emit_cvttsd2si_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
1920         *(cd->mcodeptr++) = 0xf2;
1921         emit_rex(0,(dreg),0,(reg));
1922         *(cd->mcodeptr++) = 0x0f;
1923         *(cd->mcodeptr++) = 0x2c;
1924         emit_reg((dreg),(reg));
1925 }
1926
1927
1928 void emit_divss_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
1929         *(cd->mcodeptr++) = 0xf3;
1930         emit_rex(0,(dreg),0,(reg));
1931         *(cd->mcodeptr++) = 0x0f;
1932         *(cd->mcodeptr++) = 0x5e;
1933         emit_reg((dreg),(reg));
1934 }
1935
1936
1937 void emit_divsd_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
1938         *(cd->mcodeptr++) = 0xf2;
1939         emit_rex(0,(dreg),0,(reg));
1940         *(cd->mcodeptr++) = 0x0f;
1941         *(cd->mcodeptr++) = 0x5e;
1942         emit_reg((dreg),(reg));
1943 }
1944
1945
1946 void emit_movd_reg_freg(codegendata *cd, s8 reg, s8 freg) {
1947         *(cd->mcodeptr++) = 0x66;
1948         emit_rex(1,(freg),0,(reg));
1949         *(cd->mcodeptr++) = 0x0f;
1950         *(cd->mcodeptr++) = 0x6e;
1951         emit_reg((freg),(reg));
1952 }
1953
1954
1955 void emit_movd_freg_reg(codegendata *cd, s8 freg, s8 reg) {
1956         *(cd->mcodeptr++) = 0x66;
1957         emit_rex(1,(freg),0,(reg));
1958         *(cd->mcodeptr++) = 0x0f;
1959         *(cd->mcodeptr++) = 0x7e;
1960         emit_reg((freg),(reg));
1961 }
1962
1963
1964 void emit_movd_reg_membase(codegendata *cd, s8 reg, s8 basereg, s8 disp) {
1965         *(cd->mcodeptr++) = 0x66;
1966         emit_rex(0,(reg),0,(basereg));
1967         *(cd->mcodeptr++) = 0x0f;
1968         *(cd->mcodeptr++) = 0x7e;
1969         emit_membase(cd, (basereg),(disp),(reg));
1970 }
1971
1972
1973 void emit_movd_reg_memindex(codegendata *cd, s8 reg, s8 disp, s8 basereg, s8 indexreg, s8 scale) {
1974         *(cd->mcodeptr++) = 0x66;
1975         emit_rex(0,(reg),(indexreg),(basereg));
1976         *(cd->mcodeptr++) = 0x0f;
1977         *(cd->mcodeptr++) = 0x7e;
1978         emit_memindex(cd, (reg),(disp),(basereg),(indexreg),(scale));
1979 }
1980
1981
1982 void emit_movd_membase_reg(codegendata *cd, s8 basereg, s8 disp, s8 dreg) {
1983         *(cd->mcodeptr++) = 0x66;
1984         emit_rex(1,(dreg),0,(basereg));
1985         *(cd->mcodeptr++) = 0x0f;
1986         *(cd->mcodeptr++) = 0x6e;
1987         emit_membase(cd, (basereg),(disp),(dreg));
1988 }
1989
1990
1991 void emit_movdl_membase_reg(codegendata *cd, s8 basereg, s8 disp, s8 dreg) {
1992         *(cd->mcodeptr++) = 0x66;
1993         emit_rex(0,(dreg),0,(basereg));
1994         *(cd->mcodeptr++) = 0x0f;
1995         *(cd->mcodeptr++) = 0x6e;
1996         emit_membase(cd, (basereg),(disp),(dreg));
1997 }
1998
1999
2000 void emit_movd_memindex_reg(codegendata *cd, s8 disp, s8 basereg, s8 indexreg, s8 scale, s8 dreg) {
2001         *(cd->mcodeptr++) = 0x66;
2002         emit_rex(0,(dreg),(indexreg),(basereg));
2003         *(cd->mcodeptr++) = 0x0f;
2004         *(cd->mcodeptr++) = 0x6e;
2005         emit_memindex(cd, (dreg),(disp),(basereg),(indexreg),(scale));
2006 }
2007
2008
2009 void emit_movq_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
2010         *(cd->mcodeptr++) = 0xf3;
2011         emit_rex(0,(dreg),0,(reg));
2012         *(cd->mcodeptr++) = 0x0f;
2013         *(cd->mcodeptr++) = 0x7e;
2014         emit_reg((dreg),(reg));
2015 }
2016
2017
2018 void emit_movq_reg_membase(codegendata *cd, s8 reg, s8 basereg, s8 disp) {
2019         *(cd->mcodeptr++) = 0x66;
2020         emit_rex(0,(reg),0,(basereg));
2021         *(cd->mcodeptr++) = 0x0f;
2022         *(cd->mcodeptr++) = 0xd6;
2023         emit_membase(cd, (basereg),(disp),(reg));
2024 }
2025
2026
2027 void emit_movq_membase_reg(codegendata *cd, s8 basereg, s8 disp, s8 dreg) {
2028         *(cd->mcodeptr++) = 0xf3;
2029         emit_rex(0,(dreg),0,(basereg));
2030         *(cd->mcodeptr++) = 0x0f;
2031         *(cd->mcodeptr++) = 0x7e;
2032         emit_membase(cd, (basereg),(disp),(dreg));
2033 }
2034
2035
2036 void emit_movss_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
2037         *(cd->mcodeptr++) = 0xf3;
2038         emit_rex(0,(reg),0,(dreg));
2039         *(cd->mcodeptr++) = 0x0f;
2040         *(cd->mcodeptr++) = 0x10;
2041         emit_reg((reg),(dreg));
2042 }
2043
2044
2045 void emit_movsd_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
2046         *(cd->mcodeptr++) = 0xf2;
2047         emit_rex(0,(reg),0,(dreg));
2048         *(cd->mcodeptr++) = 0x0f;
2049         *(cd->mcodeptr++) = 0x10;
2050         emit_reg((reg),(dreg));
2051 }
2052
2053
2054 void emit_movss_reg_membase(codegendata *cd, s8 reg, s8 basereg, s8 disp) {
2055         *(cd->mcodeptr++) = 0xf3;
2056         emit_rex(0,(reg),0,(basereg));
2057         *(cd->mcodeptr++) = 0x0f;
2058         *(cd->mcodeptr++) = 0x11;
2059         emit_membase(cd, (basereg),(disp),(reg));
2060 }
2061
2062
2063 /* Always emit a REX byte, because the instruction size can be smaller when   */
2064 /* all register indexes are smaller than 7.                                   */
2065 void emit_movss_reg_membase32(codegendata *cd, s8 reg, s8 basereg, s8 disp) {
2066         *(cd->mcodeptr++) = 0xf3;
2067         emit_byte_rex((reg),0,(basereg));
2068         *(cd->mcodeptr++) = 0x0f;
2069         *(cd->mcodeptr++) = 0x11;
2070         emit_membase32(cd, (basereg),(disp),(reg));
2071 }
2072
2073
2074 void emit_movsd_reg_membase(codegendata *cd, s8 reg, s8 basereg, s8 disp) {
2075         *(cd->mcodeptr++) = 0xf2;
2076         emit_rex(0,(reg),0,(basereg));
2077         *(cd->mcodeptr++) = 0x0f;
2078         *(cd->mcodeptr++) = 0x11;
2079         emit_membase(cd, (basereg),(disp),(reg));
2080 }
2081
2082
2083 /* Always emit a REX byte, because the instruction size can be smaller when   */
2084 /* all register indexes are smaller than 7.                                   */
2085 void emit_movsd_reg_membase32(codegendata *cd, s8 reg, s8 basereg, s8 disp) {
2086         *(cd->mcodeptr++) = 0xf2;
2087         emit_byte_rex((reg),0,(basereg));
2088         *(cd->mcodeptr++) = 0x0f;
2089         *(cd->mcodeptr++) = 0x11;
2090         emit_membase32(cd, (basereg),(disp),(reg));
2091 }
2092
2093
2094 void emit_movss_membase_reg(codegendata *cd, s8 basereg, s8 disp, s8 dreg) {
2095         *(cd->mcodeptr++) = 0xf3;
2096         emit_rex(0,(dreg),0,(basereg));
2097         *(cd->mcodeptr++) = 0x0f;
2098         *(cd->mcodeptr++) = 0x10;
2099         emit_membase(cd, (basereg),(disp),(dreg));
2100 }
2101
2102
2103 /* Always emit a REX byte, because the instruction size can be smaller when   */
2104 /* all register indexes are smaller than 7.                                   */
2105 void emit_movss_membase32_reg(codegendata *cd, s8 basereg, s8 disp, s8 dreg) {
2106         *(cd->mcodeptr++) = 0xf3;
2107         emit_byte_rex((dreg),0,(basereg));
2108         *(cd->mcodeptr++) = 0x0f;
2109         *(cd->mcodeptr++) = 0x10;
2110         emit_membase32(cd, (basereg),(disp),(dreg));
2111 }
2112
2113
2114 void emit_movlps_membase_reg(codegendata *cd, s8 basereg, s8 disp, s8 dreg)
2115 {
2116         emit_rex(0,(dreg),0,(basereg));
2117         *(cd->mcodeptr++) = 0x0f;
2118         *(cd->mcodeptr++) = 0x12;
2119         emit_membase(cd, (basereg),(disp),(dreg));
2120 }
2121
2122
2123 void emit_movlps_reg_membase(codegendata *cd, s8 reg, s8 basereg, s8 disp)
2124 {
2125         emit_rex(0,(reg),0,(basereg));
2126         *(cd->mcodeptr++) = 0x0f;
2127         *(cd->mcodeptr++) = 0x13;
2128         emit_membase(cd, (basereg),(disp),(reg));
2129 }
2130
2131
2132 void emit_movsd_membase_reg(codegendata *cd, s8 basereg, s8 disp, s8 dreg) {
2133         *(cd->mcodeptr++) = 0xf2;
2134         emit_rex(0,(dreg),0,(basereg));
2135         *(cd->mcodeptr++) = 0x0f;
2136         *(cd->mcodeptr++) = 0x10;
2137         emit_membase(cd, (basereg),(disp),(dreg));
2138 }
2139
2140
2141 /* Always emit a REX byte, because the instruction size can be smaller when   */
2142 /* all register indexes are smaller than 7.                                   */
2143 void emit_movsd_membase32_reg(codegendata *cd, s8 basereg, s8 disp, s8 dreg) {
2144         *(cd->mcodeptr++) = 0xf2;
2145         emit_byte_rex((dreg),0,(basereg));
2146         *(cd->mcodeptr++) = 0x0f;
2147         *(cd->mcodeptr++) = 0x10;
2148         emit_membase32(cd, (basereg),(disp),(dreg));
2149 }
2150
2151
2152 void emit_movlpd_membase_reg(codegendata *cd, s8 basereg, s8 disp, s8 dreg)
2153 {
2154         *(cd->mcodeptr++) = 0x66;
2155         emit_rex(0,(dreg),0,(basereg));
2156         *(cd->mcodeptr++) = 0x0f;
2157         *(cd->mcodeptr++) = 0x12;
2158         emit_membase(cd, (basereg),(disp),(dreg));
2159 }
2160
2161
2162 void emit_movlpd_reg_membase(codegendata *cd, s8 reg, s8 basereg, s8 disp)
2163 {
2164         *(cd->mcodeptr++) = 0x66;
2165         emit_rex(0,(reg),0,(basereg));
2166         *(cd->mcodeptr++) = 0x0f;
2167         *(cd->mcodeptr++) = 0x13;
2168         emit_membase(cd, (basereg),(disp),(reg));
2169 }
2170
2171
2172 void emit_movss_reg_memindex(codegendata *cd, s8 reg, s8 disp, s8 basereg, s8 indexreg, s8 scale) {
2173         *(cd->mcodeptr++) = 0xf3;
2174         emit_rex(0,(reg),(indexreg),(basereg));
2175         *(cd->mcodeptr++) = 0x0f;
2176         *(cd->mcodeptr++) = 0x11;
2177         emit_memindex(cd, (reg),(disp),(basereg),(indexreg),(scale));
2178 }
2179
2180
2181 void emit_movsd_reg_memindex(codegendata *cd, s8 reg, s8 disp, s8 basereg, s8 indexreg, s8 scale) {
2182         *(cd->mcodeptr++) = 0xf2;
2183         emit_rex(0,(reg),(indexreg),(basereg));
2184         *(cd->mcodeptr++) = 0x0f;
2185         *(cd->mcodeptr++) = 0x11;
2186         emit_memindex(cd, (reg),(disp),(basereg),(indexreg),(scale));
2187 }
2188
2189
2190 void emit_movss_memindex_reg(codegendata *cd, s8 disp, s8 basereg, s8 indexreg, s8 scale, s8 dreg) {
2191         *(cd->mcodeptr++) = 0xf3;
2192         emit_rex(0,(dreg),(indexreg),(basereg));
2193         *(cd->mcodeptr++) = 0x0f;
2194         *(cd->mcodeptr++) = 0x10;
2195         emit_memindex(cd, (dreg),(disp),(basereg),(indexreg),(scale));
2196 }
2197
2198
2199 void emit_movsd_memindex_reg(codegendata *cd, s8 disp, s8 basereg, s8 indexreg, s8 scale, s8 dreg) {
2200         *(cd->mcodeptr++) = 0xf2;
2201         emit_rex(0,(dreg),(indexreg),(basereg));
2202         *(cd->mcodeptr++) = 0x0f;
2203         *(cd->mcodeptr++) = 0x10;
2204         emit_memindex(cd, (dreg),(disp),(basereg),(indexreg),(scale));
2205 }
2206
2207
2208 void emit_mulss_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
2209         *(cd->mcodeptr++) = 0xf3;
2210         emit_rex(0,(dreg),0,(reg));
2211         *(cd->mcodeptr++) = 0x0f;
2212         *(cd->mcodeptr++) = 0x59;
2213         emit_reg((dreg),(reg));
2214 }
2215
2216
2217 void emit_mulsd_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
2218         *(cd->mcodeptr++) = 0xf2;
2219         emit_rex(0,(dreg),0,(reg));
2220         *(cd->mcodeptr++) = 0x0f;
2221         *(cd->mcodeptr++) = 0x59;
2222         emit_reg((dreg),(reg));
2223 }
2224
2225
2226 void emit_subss_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
2227         *(cd->mcodeptr++) = 0xf3;
2228         emit_rex(0,(dreg),0,(reg));
2229         *(cd->mcodeptr++) = 0x0f;
2230         *(cd->mcodeptr++) = 0x5c;
2231         emit_reg((dreg),(reg));
2232 }
2233
2234
2235 void emit_subsd_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
2236         *(cd->mcodeptr++) = 0xf2;
2237         emit_rex(0,(dreg),0,(reg));
2238         *(cd->mcodeptr++) = 0x0f;
2239         *(cd->mcodeptr++) = 0x5c;
2240         emit_reg((dreg),(reg));
2241 }
2242
2243
2244 void emit_ucomiss_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
2245         emit_rex(0,(dreg),0,(reg));
2246         *(cd->mcodeptr++) = 0x0f;
2247         *(cd->mcodeptr++) = 0x2e;
2248         emit_reg((dreg),(reg));
2249 }
2250
2251
2252 void emit_ucomisd_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
2253         *(cd->mcodeptr++) = 0x66;
2254         emit_rex(0,(dreg),0,(reg));
2255         *(cd->mcodeptr++) = 0x0f;
2256         *(cd->mcodeptr++) = 0x2e;
2257         emit_reg((dreg),(reg));
2258 }
2259
2260
2261 void emit_xorps_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
2262         emit_rex(0,(dreg),0,(reg));
2263         *(cd->mcodeptr++) = 0x0f;
2264         *(cd->mcodeptr++) = 0x57;
2265         emit_reg((dreg),(reg));
2266 }
2267
2268
2269 void emit_xorps_membase_reg(codegendata *cd, s8 basereg, s8 disp, s8 dreg) {
2270         emit_rex(0,(dreg),0,(basereg));
2271         *(cd->mcodeptr++) = 0x0f;
2272         *(cd->mcodeptr++) = 0x57;
2273         emit_membase(cd, (basereg),(disp),(dreg));
2274 }
2275
2276
2277 void emit_xorpd_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
2278         *(cd->mcodeptr++) = 0x66;
2279         emit_rex(0,(dreg),0,(reg));
2280         *(cd->mcodeptr++) = 0x0f;
2281         *(cd->mcodeptr++) = 0x57;
2282         emit_reg((dreg),(reg));
2283 }
2284
2285
2286 void emit_xorpd_membase_reg(codegendata *cd, s8 basereg, s8 disp, s8 dreg) {
2287         *(cd->mcodeptr++) = 0x66;
2288         emit_rex(0,(dreg),0,(basereg));
2289         *(cd->mcodeptr++) = 0x0f;
2290         *(cd->mcodeptr++) = 0x57;
2291         emit_membase(cd, (basereg),(disp),(dreg));
2292 }
2293
2294
2295 /* system instructions ********************************************************/
2296
2297 void emit_rdtsc(codegendata *cd)
2298 {
2299         *(cd->mcodeptr++) = 0x0f;
2300         *(cd->mcodeptr++) = 0x31;
2301 }
2302
2303
2304 /*
2305  * These are local overrides for various environment variables in Emacs.
2306  * Please do not remove this and leave it at the end of the file, where
2307  * Emacs will automagically detect them.
2308  * ---------------------------------------------------------------------
2309  * Local variables:
2310  * mode: c
2311  * indent-tabs-mode: t
2312  * c-basic-offset: 4
2313  * tab-width: 4
2314  * End:
2315  */