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