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