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