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