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