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