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