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