* src/vm/jit/x86_64/codegen.h: Use multi-byte NOP for code alignment.
[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, 2008, 2009
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_mov_reg_reg(codegendata *cd, s8 reg, s8 dreg)
1279 {
1280         emit_rex(1,(reg),0,(dreg));
1281         *(cd->mcodeptr++) = 0x89;
1282         emit_reg((reg),(dreg));
1283 }
1284
1285
1286 void emit_mov_imm_reg(codegendata *cd, s8 imm, s8 reg)
1287 {
1288         emit_rex(1,0,0,(reg));
1289         *(cd->mcodeptr++) = 0xb8 + ((reg) & 0x07);
1290         emit_imm64((imm));
1291 }
1292
1293
1294 void emit_movl_reg_reg(codegendata *cd, s8 reg, s8 dreg)
1295 {
1296         emit_rex(0,(reg),0,(dreg));
1297         *(cd->mcodeptr++) = 0x89;
1298         emit_reg((reg),(dreg));
1299 }
1300
1301
1302 void emit_movl_imm_reg(codegendata *cd, s8 imm, s8 reg) {
1303         emit_rex(0,0,0,(reg));
1304         *(cd->mcodeptr++) = 0xb8 + ((reg) & 0x07);
1305         emit_imm32((imm));
1306 }
1307
1308
1309 void emit_mov_membase_reg(codegendata *cd, s8 basereg, s8 disp, s8 reg) {
1310         emit_rex(1,(reg),0,(basereg));
1311         *(cd->mcodeptr++) = 0x8b;
1312         emit_membase(cd, (basereg),(disp),(reg));
1313 }
1314
1315
1316 /*
1317  * this one is for INVOKEVIRTUAL/INVOKEINTERFACE to have a
1318  * constant membase immediate length of 32bit
1319  */
1320 void emit_mov_membase32_reg(codegendata *cd, s8 basereg, s8 disp, s8 reg) {
1321         emit_rex(1,(reg),0,(basereg));
1322         *(cd->mcodeptr++) = 0x8b;
1323         emit_membase32(cd, (basereg),(disp),(reg));
1324 }
1325
1326
1327 void emit_movl_membase_reg(codegendata *cd, s8 basereg, s8 disp, s8 reg)
1328 {
1329         emit_rex(0,(reg),0,(basereg));
1330         *(cd->mcodeptr++) = 0x8b;
1331         emit_membase(cd, (basereg),(disp),(reg));
1332 }
1333
1334
1335 /* ATTENTION: Always emit a REX byte, because the instruction size can
1336    be smaller when all register indexes are smaller than 7. */
1337 void emit_movl_membase32_reg(codegendata *cd, s8 basereg, s8 disp, s8 reg)
1338 {
1339         emit_byte_rex((reg),0,(basereg));
1340         *(cd->mcodeptr++) = 0x8b;
1341         emit_membase32(cd, (basereg),(disp),(reg));
1342 }
1343
1344
1345 void emit_mov_reg_membase(codegendata *cd, s8 reg, s8 basereg, s8 disp) {
1346         emit_rex(1,(reg),0,(basereg));
1347         *(cd->mcodeptr++) = 0x89;
1348         emit_membase(cd, (basereg),(disp),(reg));
1349 }
1350
1351
1352 void emit_mov_reg_membase32(codegendata *cd, s8 reg, s8 basereg, s8 disp) {
1353         emit_rex(1,(reg),0,(basereg));
1354         *(cd->mcodeptr++) = 0x89;
1355         emit_membase32(cd, (basereg),(disp),(reg));
1356 }
1357
1358
1359 void emit_movl_reg_membase(codegendata *cd, s8 reg, s8 basereg, s8 disp) {
1360         emit_rex(0,(reg),0,(basereg));
1361         *(cd->mcodeptr++) = 0x89;
1362         emit_membase(cd, (basereg),(disp),(reg));
1363 }
1364
1365
1366 /* Always emit a REX byte, because the instruction size can be smaller when   */
1367 /* all register indexes are smaller than 7.                                   */
1368 void emit_movl_reg_membase32(codegendata *cd, s8 reg, s8 basereg, s8 disp) {
1369         emit_byte_rex((reg),0,(basereg));
1370         *(cd->mcodeptr++) = 0x89;
1371         emit_membase32(cd, (basereg),(disp),(reg));
1372 }
1373
1374
1375 void emit_mov_memindex_reg(codegendata *cd, s8 disp, s8 basereg, s8 indexreg, s8 scale, s8 reg) {
1376         emit_rex(1,(reg),(indexreg),(basereg));
1377         *(cd->mcodeptr++) = 0x8b;
1378         emit_memindex(cd, (reg),(disp),(basereg),(indexreg),(scale));
1379 }
1380
1381
1382 void emit_movl_memindex_reg(codegendata *cd, s8 disp, s8 basereg, s8 indexreg, s8 scale, s8 reg) {
1383         emit_rex(0,(reg),(indexreg),(basereg));
1384         *(cd->mcodeptr++) = 0x8b;
1385         emit_memindex(cd, (reg),(disp),(basereg),(indexreg),(scale));
1386 }
1387
1388
1389 void emit_mov_reg_memindex(codegendata *cd, s8 reg, s8 disp, s8 basereg, s8 indexreg, s8 scale) {
1390         emit_rex(1,(reg),(indexreg),(basereg));
1391         *(cd->mcodeptr++) = 0x89;
1392         emit_memindex(cd, (reg),(disp),(basereg),(indexreg),(scale));
1393 }
1394
1395
1396 void emit_movl_reg_memindex(codegendata *cd, s8 reg, s8 disp, s8 basereg, s8 indexreg, s8 scale) {
1397         emit_rex(0,(reg),(indexreg),(basereg));
1398         *(cd->mcodeptr++) = 0x89;
1399         emit_memindex(cd, (reg),(disp),(basereg),(indexreg),(scale));
1400 }
1401
1402
1403 void emit_movw_reg_memindex(codegendata *cd, s8 reg, s8 disp, s8 basereg, s8 indexreg, s8 scale) {
1404         *(cd->mcodeptr++) = 0x66;
1405         emit_rex(0,(reg),(indexreg),(basereg));
1406         *(cd->mcodeptr++) = 0x89;
1407         emit_memindex(cd, (reg),(disp),(basereg),(indexreg),(scale));
1408 }
1409
1410
1411 void emit_movb_reg_memindex(codegendata *cd, s8 reg, s8 disp, s8 basereg, s8 indexreg, s8 scale) {
1412         emit_byte_rex((reg),(indexreg),(basereg));
1413         *(cd->mcodeptr++) = 0x88;
1414         emit_memindex(cd, (reg),(disp),(basereg),(indexreg),(scale));
1415 }
1416
1417
1418 void emit_mov_imm_membase(codegendata *cd, s8 imm, s8 basereg, s8 disp) {
1419         emit_rex(1,0,0,(basereg));
1420         *(cd->mcodeptr++) = 0xc7;
1421         emit_membase(cd, (basereg),(disp),0);
1422         emit_imm32((imm));
1423 }
1424
1425
1426 void emit_mov_imm_membase32(codegendata *cd, s8 imm, s8 basereg, s8 disp) {
1427         emit_rex(1,0,0,(basereg));
1428         *(cd->mcodeptr++) = 0xc7;
1429         emit_membase32(cd, (basereg),(disp),0);
1430         emit_imm32((imm));
1431 }
1432
1433
1434 void emit_movl_imm_membase(codegendata *cd, s8 imm, s8 basereg, s8 disp) {
1435         emit_rex(0,0,0,(basereg));
1436         *(cd->mcodeptr++) = 0xc7;
1437         emit_membase(cd, (basereg),(disp),0);
1438         emit_imm32((imm));
1439 }
1440
1441
1442 /* Always emit a REX byte, because the instruction size can be smaller when   */
1443 /* all register indexes are smaller than 7.                                   */
1444 void emit_movl_imm_membase32(codegendata *cd, s8 imm, s8 basereg, s8 disp) {
1445         emit_byte_rex(0,0,(basereg));
1446         *(cd->mcodeptr++) = 0xc7;
1447         emit_membase32(cd, (basereg),(disp),0);
1448         emit_imm32((imm));
1449 }
1450
1451
1452 void emit_movsbq_reg_reg(codegendata *cd, s8 reg, s8 dreg)
1453 {
1454         emit_rex(1,(dreg),0,(reg));
1455         *(cd->mcodeptr++) = 0x0f;
1456         *(cd->mcodeptr++) = 0xbe;
1457         /* XXX: why do reg and dreg have to be exchanged */
1458         emit_reg((dreg),(reg));
1459 }
1460
1461
1462 void emit_movswq_reg_reg(codegendata *cd, s8 reg, s8 dreg)
1463 {
1464         emit_rex(1,(dreg),0,(reg));
1465         *(cd->mcodeptr++) = 0x0f;
1466         *(cd->mcodeptr++) = 0xbf;
1467         /* XXX: why do reg and dreg have to be exchanged */
1468         emit_reg((dreg),(reg));
1469 }
1470
1471
1472 void emit_movslq_reg_reg(codegendata *cd, s8 reg, s8 dreg)
1473 {
1474         emit_rex(1,(dreg),0,(reg));
1475         *(cd->mcodeptr++) = 0x63;
1476         /* XXX: why do reg and dreg have to be exchanged */
1477         emit_reg((dreg),(reg));
1478 }
1479
1480
1481 void emit_movzbq_reg_reg(codegendata *cd, s8 reg, s8 dreg)
1482 {
1483         emit_rex(1,(dreg),0,(reg));
1484         *(cd->mcodeptr++) = 0x0f;
1485         *(cd->mcodeptr++) = 0xb6;
1486         /* XXX: why do reg and dreg have to be exchanged */
1487         emit_reg((dreg),(reg));
1488 }
1489
1490
1491 void emit_movzwq_reg_reg(codegendata *cd, s8 reg, s8 dreg)
1492 {
1493         emit_rex(1,(dreg),0,(reg));
1494         *(cd->mcodeptr++) = 0x0f;
1495         *(cd->mcodeptr++) = 0xb7;
1496         /* XXX: why do reg and dreg have to be exchanged */
1497         emit_reg((dreg),(reg));
1498 }
1499
1500
1501 void emit_movswq_memindex_reg(codegendata *cd, s8 disp, s8 basereg, s8 indexreg, s8 scale, s8 reg) {
1502         emit_rex(1,(reg),(indexreg),(basereg));
1503         *(cd->mcodeptr++) = 0x0f;
1504         *(cd->mcodeptr++) = 0xbf;
1505         emit_memindex(cd, (reg),(disp),(basereg),(indexreg),(scale));
1506 }
1507
1508
1509 void emit_movsbq_memindex_reg(codegendata *cd, s8 disp, s8 basereg, s8 indexreg, s8 scale, s8 reg) {
1510         emit_rex(1,(reg),(indexreg),(basereg));
1511         *(cd->mcodeptr++) = 0x0f;
1512         *(cd->mcodeptr++) = 0xbe;
1513         emit_memindex(cd, (reg),(disp),(basereg),(indexreg),(scale));
1514 }
1515
1516
1517 void emit_movzwq_memindex_reg(codegendata *cd, s8 disp, s8 basereg, s8 indexreg, s8 scale, s8 reg) {
1518         emit_rex(1,(reg),(indexreg),(basereg));
1519         *(cd->mcodeptr++) = 0x0f;
1520         *(cd->mcodeptr++) = 0xb7;
1521         emit_memindex(cd, (reg),(disp),(basereg),(indexreg),(scale));
1522 }
1523
1524
1525 void emit_mov_imm_memindex(codegendata *cd, s4 imm, s4 disp, s4 basereg, s4 indexreg, s4 scale)
1526 {
1527         emit_rex(1,0,(indexreg),(basereg));
1528         *(cd->mcodeptr++) = 0xc7;
1529         emit_memindex(cd, 0,(disp),(basereg),(indexreg),(scale));
1530         emit_imm32((imm));
1531 }
1532
1533
1534 void emit_movl_imm_memindex(codegendata *cd, s4 imm, s4 disp, s4 basereg, s4 indexreg, s4 scale)
1535 {
1536         emit_rex(0,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_movw_imm_memindex(codegendata *cd, s4 imm, s4 disp, s4 basereg, s4 indexreg, s4 scale)
1544 {
1545         *(cd->mcodeptr++) = 0x66;
1546         emit_rex(0,0,(indexreg),(basereg));
1547         *(cd->mcodeptr++) = 0xc7;
1548         emit_memindex(cd, 0,(disp),(basereg),(indexreg),(scale));
1549         emit_imm16((imm));
1550 }
1551
1552
1553 void emit_movb_imm_memindex(codegendata *cd, s4 imm, s4 disp, s4 basereg, s4 indexreg, s4 scale)
1554 {
1555         emit_rex(0,0,(indexreg),(basereg));
1556         *(cd->mcodeptr++) = 0xc6;
1557         emit_memindex(cd, 0,(disp),(basereg),(indexreg),(scale));
1558         emit_imm8((imm));
1559 }
1560
1561
1562 void emit_mov_mem_reg(codegendata *cd, s4 disp, s4 dreg)
1563 {
1564         emit_rex(1, dreg, 0, 0);
1565         *(cd->mcodeptr++) = 0x8b;
1566         emit_address_byte(0, dreg, 4);
1567         emit_mem(4, disp);
1568 }
1569
1570
1571 /*
1572  * alu operations
1573  */
1574 void emit_alu_reg_reg(codegendata *cd, s8 opc, s8 reg, s8 dreg)
1575 {
1576         emit_rex(1,(reg),0,(dreg));
1577         *(cd->mcodeptr++) = (((opc)) << 3) + 1;
1578         emit_reg((reg),(dreg));
1579 }
1580
1581
1582 void emit_alul_reg_reg(codegendata *cd, s8 opc, s8 reg, s8 dreg)
1583 {
1584         emit_rex(0,(reg),0,(dreg));
1585         *(cd->mcodeptr++) = (((opc)) << 3) + 1;
1586         emit_reg((reg),(dreg));
1587 }
1588
1589
1590 void emit_alu_reg_membase(codegendata *cd, s8 opc, s8 reg, s8 basereg, s8 disp)
1591 {
1592         emit_rex(1,(reg),0,(basereg));
1593         *(cd->mcodeptr++) = (((opc)) << 3) + 1;
1594         emit_membase(cd, (basereg),(disp),(reg));
1595 }
1596
1597
1598 void emit_alul_reg_membase(codegendata *cd, s8 opc, s8 reg, s8 basereg, s8 disp)
1599 {
1600         emit_rex(0,(reg),0,(basereg));
1601         *(cd->mcodeptr++) = (((opc)) << 3) + 1;
1602         emit_membase(cd, (basereg),(disp),(reg));
1603 }
1604
1605
1606 void emit_alu_membase_reg(codegendata *cd, s8 opc, s8 basereg, s8 disp, s8 reg)
1607 {
1608         emit_rex(1,(reg),0,(basereg));
1609         *(cd->mcodeptr++) = (((opc)) << 3) + 3;
1610         emit_membase(cd, (basereg),(disp),(reg));
1611 }
1612
1613
1614 void emit_alul_membase_reg(codegendata *cd, s8 opc, s8 basereg, s8 disp, s8 reg)
1615 {
1616         emit_rex(0,(reg),0,(basereg));
1617         *(cd->mcodeptr++) = (((opc)) << 3) + 3;
1618         emit_membase(cd, (basereg),(disp),(reg));
1619 }
1620
1621
1622 void emit_alu_imm_reg(codegendata *cd, s8 opc, s8 imm, s8 dreg) {
1623         if (IS_IMM8(imm)) {
1624                 emit_rex(1,0,0,(dreg));
1625                 *(cd->mcodeptr++) = 0x83;
1626                 emit_reg((opc),(dreg));
1627                 emit_imm8((imm));
1628         } else {
1629                 emit_rex(1,0,0,(dreg));
1630                 *(cd->mcodeptr++) = 0x81;
1631                 emit_reg((opc),(dreg));
1632                 emit_imm32((imm));
1633         }
1634 }
1635
1636
1637 void emit_alu_imm32_reg(codegendata *cd, s4 opc, s4 imm, s4 dreg)
1638 {
1639         emit_rex(1,0,0,(dreg));
1640         *(cd->mcodeptr++) = 0x81;
1641         emit_reg((opc),(dreg));
1642         emit_imm32((imm));
1643 }
1644
1645
1646 void emit_alul_imm32_reg(codegendata *cd, s4 opc, s4 imm, s4 dreg)
1647 {
1648         emit_rex(0,0,0,(dreg));
1649         *(cd->mcodeptr++) = 0x81;
1650         emit_reg((opc),(dreg));
1651         emit_imm32((imm));
1652 }
1653
1654
1655 void emit_alul_imm_reg(codegendata *cd, s8 opc, s8 imm, s8 dreg) {
1656         if (IS_IMM8(imm)) {
1657                 emit_rex(0,0,0,(dreg));
1658                 *(cd->mcodeptr++) = 0x83;
1659                 emit_reg((opc),(dreg));
1660                 emit_imm8((imm));
1661         } else {
1662                 emit_rex(0,0,0,(dreg));
1663                 *(cd->mcodeptr++) = 0x81;
1664                 emit_reg((opc),(dreg));
1665                 emit_imm32((imm));
1666         }
1667 }
1668
1669
1670 void emit_alu_imm_membase(codegendata *cd, s8 opc, s8 imm, s8 basereg, s8 disp) {
1671         if (IS_IMM8(imm)) {
1672                 emit_rex(1,0,0,(basereg));
1673                 *(cd->mcodeptr++) = 0x83;
1674                 emit_membase(cd, (basereg),(disp),(opc));
1675                 emit_imm8((imm));
1676         } else {
1677                 emit_rex(1,0,0,(basereg));
1678                 *(cd->mcodeptr++) = 0x81;
1679                 emit_membase(cd, (basereg),(disp),(opc));
1680                 emit_imm32((imm));
1681         }
1682 }
1683
1684
1685 void emit_alul_imm_membase(codegendata *cd, s8 opc, s8 imm, s8 basereg, s8 disp) {
1686         if (IS_IMM8(imm)) {
1687                 emit_rex(0,0,0,(basereg));
1688                 *(cd->mcodeptr++) = 0x83;
1689                 emit_membase(cd, (basereg),(disp),(opc));
1690                 emit_imm8((imm));
1691         } else {
1692                 emit_rex(0,0,0,(basereg));
1693                 *(cd->mcodeptr++) = 0x81;
1694                 emit_membase(cd, (basereg),(disp),(opc));
1695                 emit_imm32((imm));
1696         }
1697 }
1698
1699 void emit_alu_memindex_reg(codegendata *cd, s8 opc, s8 disp, s8 basereg, s8 indexreg, s8 scale, s8 reg)
1700 {
1701         emit_rex(1,(reg),(indexreg),(basereg));
1702         *(cd->mcodeptr++) = (((opc)) << 3) + 3;
1703         emit_memindex(cd, (reg),(disp),(basereg),(indexreg),(scale));
1704 }
1705
1706 void emit_alul_memindex_reg(codegendata *cd, s8 opc, s8 disp, s8 basereg, s8 indexreg, s8 scale, s8 reg)
1707 {
1708         emit_rex(0,(reg),(indexreg),(basereg));
1709         *(cd->mcodeptr++) = (((opc)) << 3) + 3;
1710         emit_memindex(cd, (reg),(disp),(basereg),(indexreg),(scale));
1711 }
1712
1713 void emit_test_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
1714         emit_rex(1,(reg),0,(dreg));
1715         *(cd->mcodeptr++) = 0x85;
1716         emit_reg((reg),(dreg));
1717 }
1718
1719
1720 void emit_testl_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
1721         emit_rex(0,(reg),0,(dreg));
1722         *(cd->mcodeptr++) = 0x85;
1723         emit_reg((reg),(dreg));
1724 }
1725
1726
1727 void emit_test_imm_reg(codegendata *cd, s8 imm, s8 reg) {
1728         *(cd->mcodeptr++) = 0xf7;
1729         emit_reg(0,(reg));
1730         emit_imm32((imm));
1731 }
1732
1733
1734 void emit_testw_imm_reg(codegendata *cd, s8 imm, s8 reg) {
1735         *(cd->mcodeptr++) = 0x66;
1736         *(cd->mcodeptr++) = 0xf7;
1737         emit_reg(0,(reg));
1738         emit_imm16((imm));
1739 }
1740
1741
1742 void emit_testb_imm_reg(codegendata *cd, s8 imm, s8 reg) {
1743         *(cd->mcodeptr++) = 0xf6;
1744         emit_reg(0,(reg));
1745         emit_imm8((imm));
1746 }
1747
1748
1749 void emit_lea_membase_reg(codegendata *cd, s8 basereg, s8 disp, s8 reg) {
1750         emit_rex(1,(reg),0,(basereg));
1751         *(cd->mcodeptr++) = 0x8d;
1752         emit_membase(cd, (basereg),(disp),(reg));
1753 }
1754
1755
1756 void emit_leal_membase_reg(codegendata *cd, s8 basereg, s8 disp, s8 reg) {
1757         emit_rex(0,(reg),0,(basereg));
1758         *(cd->mcodeptr++) = 0x8d;
1759         emit_membase(cd, (basereg),(disp),(reg));
1760 }
1761
1762
1763 void emit_incl_reg(codegendata *cd, s8 reg)
1764 {
1765         *(cd->mcodeptr++) = 0xff;
1766         emit_reg(0,(reg));
1767 }
1768
1769 void emit_incq_reg(codegendata *cd, s8 reg)
1770 {
1771         emit_rex(1,0,0,(reg));
1772         *(cd->mcodeptr++) = 0xff;
1773         emit_reg(0,(reg));
1774 }
1775
1776 void emit_incl_membase(codegendata *cd, s8 basereg, s8 disp)
1777 {
1778         emit_rex(0,0,0,(basereg));
1779         *(cd->mcodeptr++) = 0xff;
1780         emit_membase(cd, (basereg),(disp),0);
1781 }
1782
1783 void emit_incq_membase(codegendata *cd, s8 basereg, s8 disp)
1784 {
1785         emit_rex(1,0,0,(basereg));
1786         *(cd->mcodeptr++) = 0xff;
1787         emit_membase(cd, (basereg),(disp),0);
1788 }
1789
1790
1791
1792 void emit_cltd(codegendata *cd) {
1793     *(cd->mcodeptr++) = 0x99;
1794 }
1795
1796
1797 void emit_cqto(codegendata *cd) {
1798         emit_rex(1,0,0,0);
1799         *(cd->mcodeptr++) = 0x99;
1800 }
1801
1802
1803
1804 void emit_imul_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
1805         emit_rex(1,(dreg),0,(reg));
1806         *(cd->mcodeptr++) = 0x0f;
1807         *(cd->mcodeptr++) = 0xaf;
1808         emit_reg((dreg),(reg));
1809 }
1810
1811
1812 void emit_imull_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
1813         emit_rex(0,(dreg),0,(reg));
1814         *(cd->mcodeptr++) = 0x0f;
1815         *(cd->mcodeptr++) = 0xaf;
1816         emit_reg((dreg),(reg));
1817 }
1818
1819
1820 void emit_imul_membase_reg(codegendata *cd, s8 basereg, s8 disp, s8 dreg) {
1821         emit_rex(1,(dreg),0,(basereg));
1822         *(cd->mcodeptr++) = 0x0f;
1823         *(cd->mcodeptr++) = 0xaf;
1824         emit_membase(cd, (basereg),(disp),(dreg));
1825 }
1826
1827
1828 void emit_imull_membase_reg(codegendata *cd, s8 basereg, s8 disp, s8 dreg) {
1829         emit_rex(0,(dreg),0,(basereg));
1830         *(cd->mcodeptr++) = 0x0f;
1831         *(cd->mcodeptr++) = 0xaf;
1832         emit_membase(cd, (basereg),(disp),(dreg));
1833 }
1834
1835
1836 void emit_imul_imm_reg(codegendata *cd, s8 imm, s8 dreg) {
1837         if (IS_IMM8((imm))) {
1838                 emit_rex(1,0,0,(dreg));
1839                 *(cd->mcodeptr++) = 0x6b;
1840                 emit_reg(0,(dreg));
1841                 emit_imm8((imm));
1842         } else {
1843                 emit_rex(1,0,0,(dreg));
1844                 *(cd->mcodeptr++) = 0x69;
1845                 emit_reg(0,(dreg));
1846                 emit_imm32((imm));
1847         }
1848 }
1849
1850
1851 void emit_imul_imm_reg_reg(codegendata *cd, s8 imm, s8 reg, s8 dreg) {
1852         if (IS_IMM8((imm))) {
1853                 emit_rex(1,(dreg),0,(reg));
1854                 *(cd->mcodeptr++) = 0x6b;
1855                 emit_reg((dreg),(reg));
1856                 emit_imm8((imm));
1857         } else {
1858                 emit_rex(1,(dreg),0,(reg));
1859                 *(cd->mcodeptr++) = 0x69;
1860                 emit_reg((dreg),(reg));
1861                 emit_imm32((imm));
1862         }
1863 }
1864
1865
1866 void emit_imull_imm_reg_reg(codegendata *cd, s8 imm, s8 reg, s8 dreg) {
1867         if (IS_IMM8((imm))) {
1868                 emit_rex(0,(dreg),0,(reg));
1869                 *(cd->mcodeptr++) = 0x6b;
1870                 emit_reg((dreg),(reg));
1871                 emit_imm8((imm));
1872         } else {
1873                 emit_rex(0,(dreg),0,(reg));
1874                 *(cd->mcodeptr++) = 0x69;
1875                 emit_reg((dreg),(reg));
1876                 emit_imm32((imm));
1877         }
1878 }
1879
1880
1881 void emit_imul_imm_membase_reg(codegendata *cd, s8 imm, s8 basereg, s8 disp, s8 dreg) {
1882         if (IS_IMM8((imm))) {
1883                 emit_rex(1,(dreg),0,(basereg));
1884                 *(cd->mcodeptr++) = 0x6b;
1885                 emit_membase(cd, (basereg),(disp),(dreg));
1886                 emit_imm8((imm));
1887         } else {
1888                 emit_rex(1,(dreg),0,(basereg));
1889                 *(cd->mcodeptr++) = 0x69;
1890                 emit_membase(cd, (basereg),(disp),(dreg));
1891                 emit_imm32((imm));
1892         }
1893 }
1894
1895
1896 void emit_imull_imm_membase_reg(codegendata *cd, s8 imm, s8 basereg, s8 disp, s8 dreg) {
1897         if (IS_IMM8((imm))) {
1898                 emit_rex(0,(dreg),0,(basereg));
1899                 *(cd->mcodeptr++) = 0x6b;
1900                 emit_membase(cd, (basereg),(disp),(dreg));
1901                 emit_imm8((imm));
1902         } else {
1903                 emit_rex(0,(dreg),0,(basereg));
1904                 *(cd->mcodeptr++) = 0x69;
1905                 emit_membase(cd, (basereg),(disp),(dreg));
1906                 emit_imm32((imm));
1907         }
1908 }
1909
1910
1911 void emit_idiv_reg(codegendata *cd, s8 reg) {
1912         emit_rex(1,0,0,(reg));
1913         *(cd->mcodeptr++) = 0xf7;
1914         emit_reg(7,(reg));
1915 }
1916
1917
1918 void emit_idivl_reg(codegendata *cd, s8 reg) {
1919         emit_rex(0,0,0,(reg));
1920         *(cd->mcodeptr++) = 0xf7;
1921         emit_reg(7,(reg));
1922 }
1923
1924
1925
1926 /*
1927  * shift ops
1928  */
1929 void emit_shift_reg(codegendata *cd, s8 opc, s8 reg) {
1930         emit_rex(1,0,0,(reg));
1931         *(cd->mcodeptr++) = 0xd3;
1932         emit_reg((opc),(reg));
1933 }
1934
1935
1936 void emit_shiftl_reg(codegendata *cd, s8 opc, s8 reg) {
1937         emit_rex(0,0,0,(reg));
1938         *(cd->mcodeptr++) = 0xd3;
1939         emit_reg((opc),(reg));
1940 }
1941
1942
1943 void emit_shift_membase(codegendata *cd, s8 opc, s8 basereg, s8 disp) {
1944         emit_rex(1,0,0,(basereg));
1945         *(cd->mcodeptr++) = 0xd3;
1946         emit_membase(cd, (basereg),(disp),(opc));
1947 }
1948
1949
1950 void emit_shiftl_membase(codegendata *cd, s8 opc, s8 basereg, s8 disp) {
1951         emit_rex(0,0,0,(basereg));
1952         *(cd->mcodeptr++) = 0xd3;
1953         emit_membase(cd, (basereg),(disp),(opc));
1954 }
1955
1956
1957 void emit_shift_imm_reg(codegendata *cd, s8 opc, s8 imm, s8 dreg) {
1958         if ((imm) == 1) {
1959                 emit_rex(1,0,0,(dreg));
1960                 *(cd->mcodeptr++) = 0xd1;
1961                 emit_reg((opc),(dreg));
1962         } else {
1963                 emit_rex(1,0,0,(dreg));
1964                 *(cd->mcodeptr++) = 0xc1;
1965                 emit_reg((opc),(dreg));
1966                 emit_imm8((imm));
1967         }
1968 }
1969
1970
1971 void emit_shiftl_imm_reg(codegendata *cd, s8 opc, s8 imm, s8 dreg) {
1972         if ((imm) == 1) {
1973                 emit_rex(0,0,0,(dreg));
1974                 *(cd->mcodeptr++) = 0xd1;
1975                 emit_reg((opc),(dreg));
1976         } else {
1977                 emit_rex(0,0,0,(dreg));
1978                 *(cd->mcodeptr++) = 0xc1;
1979                 emit_reg((opc),(dreg));
1980                 emit_imm8((imm));
1981         }
1982 }
1983
1984
1985 void emit_shift_imm_membase(codegendata *cd, s8 opc, s8 imm, s8 basereg, s8 disp) {
1986         if ((imm) == 1) {
1987                 emit_rex(1,0,0,(basereg));
1988                 *(cd->mcodeptr++) = 0xd1;
1989                 emit_membase(cd, (basereg),(disp),(opc));
1990         } else {
1991                 emit_rex(1,0,0,(basereg));
1992                 *(cd->mcodeptr++) = 0xc1;
1993                 emit_membase(cd, (basereg),(disp),(opc));
1994                 emit_imm8((imm));
1995         }
1996 }
1997
1998
1999 void emit_shiftl_imm_membase(codegendata *cd, s8 opc, s8 imm, s8 basereg, s8 disp) {
2000         if ((imm) == 1) {
2001                 emit_rex(0,0,0,(basereg));
2002                 *(cd->mcodeptr++) = 0xd1;
2003                 emit_membase(cd, (basereg),(disp),(opc));
2004         } else {
2005                 emit_rex(0,0,0,(basereg));
2006                 *(cd->mcodeptr++) = 0xc1;
2007                 emit_membase(cd, (basereg),(disp),(opc));
2008                 emit_imm8((imm));
2009         }
2010 }
2011
2012
2013
2014 /*
2015  * jump operations
2016  */
2017 void emit_jmp_imm(codegendata *cd, s8 imm) {
2018         *(cd->mcodeptr++) = 0xe9;
2019         emit_imm32((imm));
2020 }
2021
2022 /* like emit_jmp_imm but allows 8 bit optimization */
2023 void emit_jmp_imm2(codegendata *cd, s8 imm) {
2024         if (IS_IMM8(imm)) {
2025                 *(cd->mcodeptr++) = 0xeb;
2026                 emit_imm8((imm));
2027         }
2028         else {
2029                 *(cd->mcodeptr++) = 0xe9;
2030                 emit_imm32((imm));
2031         }
2032 }
2033
2034
2035 void emit_jmp_reg(codegendata *cd, s8 reg) {
2036         emit_rex(0,0,0,(reg));
2037         *(cd->mcodeptr++) = 0xff;
2038         emit_reg(4,(reg));
2039 }
2040
2041
2042 void emit_jcc(codegendata *cd, s8 opc, s8 imm) {
2043         *(cd->mcodeptr++) = 0x0f;
2044         *(cd->mcodeptr++) = (0x80 + (opc));
2045         emit_imm32((imm));
2046 }
2047
2048
2049
2050 /*
2051  * conditional set and move operations
2052  */
2053
2054 /* we need the rex byte to get all low bytes */
2055 void emit_setcc_reg(codegendata *cd, s4 opc, s4 reg)
2056 {
2057         *(cd->mcodeptr++) = (0x40 | (((reg) >> 3) & 0x01));
2058         *(cd->mcodeptr++) = 0x0f;
2059         *(cd->mcodeptr++) = (0x90 + (opc));
2060         emit_reg(0,(reg));
2061 }
2062
2063
2064 /* we need the rex byte to get all low bytes */
2065 void emit_setcc_membase(codegendata *cd, s4 opc, s4 basereg, s4 disp)
2066 {
2067         *(cd->mcodeptr++) = (0x40 | (((basereg) >> 3) & 0x01));
2068         *(cd->mcodeptr++) = 0x0f;
2069         *(cd->mcodeptr++) = (0x90 + (opc));
2070         emit_membase(cd, (basereg),(disp),0);
2071 }
2072
2073
2074 void emit_cmovcc_reg_reg(codegendata *cd, s4 opc, s4 reg, s4 dreg)
2075 {
2076         emit_rex(1,(dreg),0,(reg));
2077         *(cd->mcodeptr++) = 0x0f;
2078         *(cd->mcodeptr++) = (0x40 + (opc));
2079         emit_reg((dreg),(reg));
2080 }
2081
2082
2083 void emit_cmovccl_reg_reg(codegendata *cd, s4 opc, s4 reg, s4 dreg)
2084 {
2085         emit_rex(0,(dreg),0,(reg));
2086         *(cd->mcodeptr++) = 0x0f;
2087         *(cd->mcodeptr++) = (0x40 + (opc));
2088         emit_reg((dreg),(reg));
2089 }
2090
2091
2092 void emit_neg_reg(codegendata *cd, s8 reg)
2093 {
2094         emit_rex(1,0,0,(reg));
2095         *(cd->mcodeptr++) = 0xf7;
2096         emit_reg(3,(reg));
2097 }
2098
2099
2100 void emit_negl_reg(codegendata *cd, s8 reg)
2101 {
2102         emit_rex(0,0,0,(reg));
2103         *(cd->mcodeptr++) = 0xf7;
2104         emit_reg(3,(reg));
2105 }
2106
2107
2108 void emit_push_reg(codegendata *cd, s8 reg) {
2109         emit_rex(0,0,0,(reg));
2110         *(cd->mcodeptr++) = 0x50 + (0x07 & (reg));
2111 }
2112
2113
2114 void emit_push_imm(codegendata *cd, s8 imm) {
2115         *(cd->mcodeptr++) = 0x68;
2116         emit_imm32((imm));
2117 }
2118
2119
2120 void emit_pop_reg(codegendata *cd, s8 reg) {
2121         emit_rex(0,0,0,(reg));
2122         *(cd->mcodeptr++) = 0x58 + (0x07 & (reg));
2123 }
2124
2125
2126 void emit_xchg_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
2127         emit_rex(1,(reg),0,(dreg));
2128         *(cd->mcodeptr++) = 0x87;
2129         emit_reg((reg),(dreg));
2130 }
2131
2132
2133
2134 /*
2135  * call instructions
2136  */
2137 void emit_call_reg(codegendata *cd, s8 reg)
2138 {
2139         emit_rex(0,0,0,(reg));
2140         *(cd->mcodeptr++) = 0xff;
2141         emit_reg(2,(reg));
2142 }
2143
2144
2145 void emit_call_imm(codegendata *cd, s8 imm)
2146 {
2147         *(cd->mcodeptr++) = 0xe8;
2148         emit_imm32((imm));
2149 }
2150
2151
2152 void emit_call_mem(codegendata *cd, ptrint mem)
2153 {
2154         *(cd->mcodeptr++) = 0xff;
2155         emit_mem(2,(mem));
2156 }
2157
2158
2159
2160 /*
2161  * floating point instructions (SSE2)
2162  */
2163 void emit_addsd_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
2164         *(cd->mcodeptr++) = 0xf2;
2165         emit_rex(0,(dreg),0,(reg));
2166         *(cd->mcodeptr++) = 0x0f;
2167         *(cd->mcodeptr++) = 0x58;
2168         emit_reg((dreg),(reg));
2169 }
2170
2171
2172 void emit_addss_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
2173         *(cd->mcodeptr++) = 0xf3;
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_cvtsi2ssq_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
2182         *(cd->mcodeptr++) = 0xf3;
2183         emit_rex(1,(dreg),0,(reg));
2184         *(cd->mcodeptr++) = 0x0f;
2185         *(cd->mcodeptr++) = 0x2a;
2186         emit_reg((dreg),(reg));
2187 }
2188
2189
2190 void emit_cvtsi2ss_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
2191         *(cd->mcodeptr++) = 0xf3;
2192         emit_rex(0,(dreg),0,(reg));
2193         *(cd->mcodeptr++) = 0x0f;
2194         *(cd->mcodeptr++) = 0x2a;
2195         emit_reg((dreg),(reg));
2196 }
2197
2198
2199 void emit_cvtsi2sdq_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
2200         *(cd->mcodeptr++) = 0xf2;
2201         emit_rex(1,(dreg),0,(reg));
2202         *(cd->mcodeptr++) = 0x0f;
2203         *(cd->mcodeptr++) = 0x2a;
2204         emit_reg((dreg),(reg));
2205 }
2206
2207
2208 void emit_cvtsi2sd_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
2209         *(cd->mcodeptr++) = 0xf2;
2210         emit_rex(0,(dreg),0,(reg));
2211         *(cd->mcodeptr++) = 0x0f;
2212         *(cd->mcodeptr++) = 0x2a;
2213         emit_reg((dreg),(reg));
2214 }
2215
2216
2217 void emit_cvtss2sd_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
2218         *(cd->mcodeptr++) = 0xf3;
2219         emit_rex(0,(dreg),0,(reg));
2220         *(cd->mcodeptr++) = 0x0f;
2221         *(cd->mcodeptr++) = 0x5a;
2222         emit_reg((dreg),(reg));
2223 }
2224
2225
2226 void emit_cvtsd2ss_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
2227         *(cd->mcodeptr++) = 0xf2;
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_cvttss2siq_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
2236         *(cd->mcodeptr++) = 0xf3;
2237         emit_rex(1,(dreg),0,(reg));
2238         *(cd->mcodeptr++) = 0x0f;
2239         *(cd->mcodeptr++) = 0x2c;
2240         emit_reg((dreg),(reg));
2241 }
2242
2243
2244 void emit_cvttss2si_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
2245         *(cd->mcodeptr++) = 0xf3;
2246         emit_rex(0,(dreg),0,(reg));
2247         *(cd->mcodeptr++) = 0x0f;
2248         *(cd->mcodeptr++) = 0x2c;
2249         emit_reg((dreg),(reg));
2250 }
2251
2252
2253 void emit_cvttsd2siq_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
2254         *(cd->mcodeptr++) = 0xf2;
2255         emit_rex(1,(dreg),0,(reg));
2256         *(cd->mcodeptr++) = 0x0f;
2257         *(cd->mcodeptr++) = 0x2c;
2258         emit_reg((dreg),(reg));
2259 }
2260
2261
2262 void emit_cvttsd2si_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
2263         *(cd->mcodeptr++) = 0xf2;
2264         emit_rex(0,(dreg),0,(reg));
2265         *(cd->mcodeptr++) = 0x0f;
2266         *(cd->mcodeptr++) = 0x2c;
2267         emit_reg((dreg),(reg));
2268 }
2269
2270
2271 void emit_divss_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
2272         *(cd->mcodeptr++) = 0xf3;
2273         emit_rex(0,(dreg),0,(reg));
2274         *(cd->mcodeptr++) = 0x0f;
2275         *(cd->mcodeptr++) = 0x5e;
2276         emit_reg((dreg),(reg));
2277 }
2278
2279
2280 void emit_divsd_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
2281         *(cd->mcodeptr++) = 0xf2;
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_movd_reg_freg(codegendata *cd, s8 reg, s8 freg) {
2290         *(cd->mcodeptr++) = 0x66;
2291         emit_rex(1,(freg),0,(reg));
2292         *(cd->mcodeptr++) = 0x0f;
2293         *(cd->mcodeptr++) = 0x6e;
2294         emit_reg((freg),(reg));
2295 }
2296
2297
2298 void emit_movd_freg_reg(codegendata *cd, s8 freg, s8 reg) {
2299         *(cd->mcodeptr++) = 0x66;
2300         emit_rex(1,(freg),0,(reg));
2301         *(cd->mcodeptr++) = 0x0f;
2302         *(cd->mcodeptr++) = 0x7e;
2303         emit_reg((freg),(reg));
2304 }
2305
2306
2307 void emit_movd_reg_membase(codegendata *cd, s8 reg, s8 basereg, s8 disp) {
2308         *(cd->mcodeptr++) = 0x66;
2309         emit_rex(0,(reg),0,(basereg));
2310         *(cd->mcodeptr++) = 0x0f;
2311         *(cd->mcodeptr++) = 0x7e;
2312         emit_membase(cd, (basereg),(disp),(reg));
2313 }
2314
2315
2316 void emit_movd_reg_memindex(codegendata *cd, s8 reg, s8 disp, s8 basereg, s8 indexreg, s8 scale) {
2317         *(cd->mcodeptr++) = 0x66;
2318         emit_rex(0,(reg),(indexreg),(basereg));
2319         *(cd->mcodeptr++) = 0x0f;
2320         *(cd->mcodeptr++) = 0x7e;
2321         emit_memindex(cd, (reg),(disp),(basereg),(indexreg),(scale));
2322 }
2323
2324
2325 void emit_movd_membase_reg(codegendata *cd, s8 basereg, s8 disp, s8 dreg) {
2326         *(cd->mcodeptr++) = 0x66;
2327         emit_rex(1,(dreg),0,(basereg));
2328         *(cd->mcodeptr++) = 0x0f;
2329         *(cd->mcodeptr++) = 0x6e;
2330         emit_membase(cd, (basereg),(disp),(dreg));
2331 }
2332
2333
2334 void emit_movdl_membase_reg(codegendata *cd, s8 basereg, s8 disp, s8 dreg) {
2335         *(cd->mcodeptr++) = 0x66;
2336         emit_rex(0,(dreg),0,(basereg));
2337         *(cd->mcodeptr++) = 0x0f;
2338         *(cd->mcodeptr++) = 0x6e;
2339         emit_membase(cd, (basereg),(disp),(dreg));
2340 }
2341
2342
2343 void emit_movd_memindex_reg(codegendata *cd, s8 disp, s8 basereg, s8 indexreg, s8 scale, s8 dreg) {
2344         *(cd->mcodeptr++) = 0x66;
2345         emit_rex(0,(dreg),(indexreg),(basereg));
2346         *(cd->mcodeptr++) = 0x0f;
2347         *(cd->mcodeptr++) = 0x6e;
2348         emit_memindex(cd, (dreg),(disp),(basereg),(indexreg),(scale));
2349 }
2350
2351
2352 void emit_movq_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
2353         *(cd->mcodeptr++) = 0xf3;
2354         emit_rex(0,(dreg),0,(reg));
2355         *(cd->mcodeptr++) = 0x0f;
2356         *(cd->mcodeptr++) = 0x7e;
2357         emit_reg((dreg),(reg));
2358 }
2359
2360
2361 void emit_movq_reg_membase(codegendata *cd, s8 reg, s8 basereg, s8 disp) {
2362         *(cd->mcodeptr++) = 0x66;
2363         emit_rex(0,(reg),0,(basereg));
2364         *(cd->mcodeptr++) = 0x0f;
2365         *(cd->mcodeptr++) = 0xd6;
2366         emit_membase(cd, (basereg),(disp),(reg));
2367 }
2368
2369
2370 void emit_movq_membase_reg(codegendata *cd, s8 basereg, s8 disp, s8 dreg) {
2371         *(cd->mcodeptr++) = 0xf3;
2372         emit_rex(0,(dreg),0,(basereg));
2373         *(cd->mcodeptr++) = 0x0f;
2374         *(cd->mcodeptr++) = 0x7e;
2375         emit_membase(cd, (basereg),(disp),(dreg));
2376 }
2377
2378
2379 void emit_movss_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
2380         *(cd->mcodeptr++) = 0xf3;
2381         emit_rex(0,(reg),0,(dreg));
2382         *(cd->mcodeptr++) = 0x0f;
2383         *(cd->mcodeptr++) = 0x10;
2384         emit_reg((reg),(dreg));
2385 }
2386
2387
2388 void emit_movsd_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
2389         *(cd->mcodeptr++) = 0xf2;
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_movss_reg_membase(codegendata *cd, s8 reg, s8 basereg, s8 disp) {
2398         *(cd->mcodeptr++) = 0xf3;
2399         emit_rex(0,(reg),0,(basereg));
2400         *(cd->mcodeptr++) = 0x0f;
2401         *(cd->mcodeptr++) = 0x11;
2402         emit_membase(cd, (basereg),(disp),(reg));
2403 }
2404
2405
2406 /* Always emit a REX byte, because the instruction size can be smaller when   */
2407 /* all register indexes are smaller than 7.                                   */
2408 void emit_movss_reg_membase32(codegendata *cd, s8 reg, s8 basereg, s8 disp) {
2409         *(cd->mcodeptr++) = 0xf3;
2410         emit_byte_rex((reg),0,(basereg));
2411         *(cd->mcodeptr++) = 0x0f;
2412         *(cd->mcodeptr++) = 0x11;
2413         emit_membase32(cd, (basereg),(disp),(reg));
2414 }
2415
2416
2417 void emit_movsd_reg_membase(codegendata *cd, s8 reg, s8 basereg, s8 disp) {
2418         *(cd->mcodeptr++) = 0xf2;
2419         emit_rex(0,(reg),0,(basereg));
2420         *(cd->mcodeptr++) = 0x0f;
2421         *(cd->mcodeptr++) = 0x11;
2422         emit_membase(cd, (basereg),(disp),(reg));
2423 }
2424
2425
2426 /* Always emit a REX byte, because the instruction size can be smaller when   */
2427 /* all register indexes are smaller than 7.                                   */
2428 void emit_movsd_reg_membase32(codegendata *cd, s8 reg, s8 basereg, s8 disp) {
2429         *(cd->mcodeptr++) = 0xf2;
2430         emit_byte_rex((reg),0,(basereg));
2431         *(cd->mcodeptr++) = 0x0f;
2432         *(cd->mcodeptr++) = 0x11;
2433         emit_membase32(cd, (basereg),(disp),(reg));
2434 }
2435
2436
2437 void emit_movss_membase_reg(codegendata *cd, s8 basereg, s8 disp, s8 dreg) {
2438         *(cd->mcodeptr++) = 0xf3;
2439         emit_rex(0,(dreg),0,(basereg));
2440         *(cd->mcodeptr++) = 0x0f;
2441         *(cd->mcodeptr++) = 0x10;
2442         emit_membase(cd, (basereg),(disp),(dreg));
2443 }
2444
2445
2446 /* Always emit a REX byte, because the instruction size can be smaller when   */
2447 /* all register indexes are smaller than 7.                                   */
2448 void emit_movss_membase32_reg(codegendata *cd, s8 basereg, s8 disp, s8 dreg) {
2449         *(cd->mcodeptr++) = 0xf3;
2450         emit_byte_rex((dreg),0,(basereg));
2451         *(cd->mcodeptr++) = 0x0f;
2452         *(cd->mcodeptr++) = 0x10;
2453         emit_membase32(cd, (basereg),(disp),(dreg));
2454 }
2455
2456
2457 void emit_movlps_membase_reg(codegendata *cd, s8 basereg, s8 disp, s8 dreg)
2458 {
2459         emit_rex(0,(dreg),0,(basereg));
2460         *(cd->mcodeptr++) = 0x0f;
2461         *(cd->mcodeptr++) = 0x12;
2462         emit_membase(cd, (basereg),(disp),(dreg));
2463 }
2464
2465
2466 void emit_movlps_reg_membase(codegendata *cd, s8 reg, s8 basereg, s8 disp)
2467 {
2468         emit_rex(0,(reg),0,(basereg));
2469         *(cd->mcodeptr++) = 0x0f;
2470         *(cd->mcodeptr++) = 0x13;
2471         emit_membase(cd, (basereg),(disp),(reg));
2472 }
2473
2474
2475 void emit_movsd_membase_reg(codegendata *cd, s8 basereg, s8 disp, s8 dreg) {
2476         *(cd->mcodeptr++) = 0xf2;
2477         emit_rex(0,(dreg),0,(basereg));
2478         *(cd->mcodeptr++) = 0x0f;
2479         *(cd->mcodeptr++) = 0x10;
2480         emit_membase(cd, (basereg),(disp),(dreg));
2481 }
2482
2483
2484 /* Always emit a REX byte, because the instruction size can be smaller when   */
2485 /* all register indexes are smaller than 7.                                   */
2486 void emit_movsd_membase32_reg(codegendata *cd, s8 basereg, s8 disp, s8 dreg) {
2487         *(cd->mcodeptr++) = 0xf2;
2488         emit_byte_rex((dreg),0,(basereg));
2489         *(cd->mcodeptr++) = 0x0f;
2490         *(cd->mcodeptr++) = 0x10;
2491         emit_membase32(cd, (basereg),(disp),(dreg));
2492 }
2493
2494
2495 void emit_movlpd_membase_reg(codegendata *cd, s8 basereg, s8 disp, s8 dreg)
2496 {
2497         *(cd->mcodeptr++) = 0x66;
2498         emit_rex(0,(dreg),0,(basereg));
2499         *(cd->mcodeptr++) = 0x0f;
2500         *(cd->mcodeptr++) = 0x12;
2501         emit_membase(cd, (basereg),(disp),(dreg));
2502 }
2503
2504
2505 void emit_movlpd_reg_membase(codegendata *cd, s8 reg, s8 basereg, s8 disp)
2506 {
2507         *(cd->mcodeptr++) = 0x66;
2508         emit_rex(0,(reg),0,(basereg));
2509         *(cd->mcodeptr++) = 0x0f;
2510         *(cd->mcodeptr++) = 0x13;
2511         emit_membase(cd, (basereg),(disp),(reg));
2512 }
2513
2514
2515 void emit_movss_reg_memindex(codegendata *cd, s8 reg, s8 disp, s8 basereg, s8 indexreg, s8 scale) {
2516         *(cd->mcodeptr++) = 0xf3;
2517         emit_rex(0,(reg),(indexreg),(basereg));
2518         *(cd->mcodeptr++) = 0x0f;
2519         *(cd->mcodeptr++) = 0x11;
2520         emit_memindex(cd, (reg),(disp),(basereg),(indexreg),(scale));
2521 }
2522
2523
2524 void emit_movsd_reg_memindex(codegendata *cd, s8 reg, s8 disp, s8 basereg, s8 indexreg, s8 scale) {
2525         *(cd->mcodeptr++) = 0xf2;
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_movss_memindex_reg(codegendata *cd, s8 disp, s8 basereg, s8 indexreg, s8 scale, s8 dreg) {
2534         *(cd->mcodeptr++) = 0xf3;
2535         emit_rex(0,(dreg),(indexreg),(basereg));
2536         *(cd->mcodeptr++) = 0x0f;
2537         *(cd->mcodeptr++) = 0x10;
2538         emit_memindex(cd, (dreg),(disp),(basereg),(indexreg),(scale));
2539 }
2540
2541
2542 void emit_movsd_memindex_reg(codegendata *cd, s8 disp, s8 basereg, s8 indexreg, s8 scale, s8 dreg) {
2543         *(cd->mcodeptr++) = 0xf2;
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_mulss_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
2552         *(cd->mcodeptr++) = 0xf3;
2553         emit_rex(0,(dreg),0,(reg));
2554         *(cd->mcodeptr++) = 0x0f;
2555         *(cd->mcodeptr++) = 0x59;
2556         emit_reg((dreg),(reg));
2557 }
2558
2559
2560 void emit_mulsd_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
2561         *(cd->mcodeptr++) = 0xf2;
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_subss_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
2570         *(cd->mcodeptr++) = 0xf3;
2571         emit_rex(0,(dreg),0,(reg));
2572         *(cd->mcodeptr++) = 0x0f;
2573         *(cd->mcodeptr++) = 0x5c;
2574         emit_reg((dreg),(reg));
2575 }
2576
2577
2578 void emit_subsd_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
2579         *(cd->mcodeptr++) = 0xf2;
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_ucomiss_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
2588         emit_rex(0,(dreg),0,(reg));
2589         *(cd->mcodeptr++) = 0x0f;
2590         *(cd->mcodeptr++) = 0x2e;
2591         emit_reg((dreg),(reg));
2592 }
2593
2594
2595 void emit_ucomisd_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
2596         *(cd->mcodeptr++) = 0x66;
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_xorps_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
2605         emit_rex(0,(dreg),0,(reg));
2606         *(cd->mcodeptr++) = 0x0f;
2607         *(cd->mcodeptr++) = 0x57;
2608         emit_reg((dreg),(reg));
2609 }
2610
2611
2612 void emit_xorps_membase_reg(codegendata *cd, s8 basereg, s8 disp, s8 dreg) {
2613         emit_rex(0,(dreg),0,(basereg));
2614         *(cd->mcodeptr++) = 0x0f;
2615         *(cd->mcodeptr++) = 0x57;
2616         emit_membase(cd, (basereg),(disp),(dreg));
2617 }
2618
2619
2620 void emit_xorpd_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
2621         *(cd->mcodeptr++) = 0x66;
2622         emit_rex(0,(dreg),0,(reg));
2623         *(cd->mcodeptr++) = 0x0f;
2624         *(cd->mcodeptr++) = 0x57;
2625         emit_reg((dreg),(reg));
2626 }
2627
2628
2629 void emit_xorpd_membase_reg(codegendata *cd, s8 basereg, s8 disp, s8 dreg) {
2630         *(cd->mcodeptr++) = 0x66;
2631         emit_rex(0,(dreg),0,(basereg));
2632         *(cd->mcodeptr++) = 0x0f;
2633         *(cd->mcodeptr++) = 0x57;
2634         emit_membase(cd, (basereg),(disp),(dreg));
2635 }
2636
2637
2638 /* system instructions ********************************************************/
2639
2640 void emit_rdtsc(codegendata *cd)
2641 {
2642         *(cd->mcodeptr++) = 0x0f;
2643         *(cd->mcodeptr++) = 0x31;
2644 }
2645
2646 void emit_mfence(codegendata *cd)
2647 {
2648         *(cd->mcodeptr++) = 0x0f;
2649         *(cd->mcodeptr++) = 0xae;
2650         *(cd->mcodeptr++) = 0xf0;
2651 }
2652
2653
2654 /*
2655  * These are local overrides for various environment variables in Emacs.
2656  * Please do not remove this and leave it at the end of the file, where
2657  * Emacs will automagically detect them.
2658  * ---------------------------------------------------------------------
2659  * Local variables:
2660  * mode: c
2661  * indent-tabs-mode: t
2662  * c-basic-offset: 4
2663  * tab-width: 4
2664  * End:
2665  * vim:noexpandtab:sw=4:ts=4:
2666  */