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