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