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