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