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