* src/toolbox/list.hpp (DumpList): Made sort function accessible.
[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 synchronization code to enter a monitor.
476  */
477 #if defined(ENABLE_THREADS)
478 void emit_monitor_enter(jitdata* jd, int32_t syncslot_offset)
479 {
480         int32_t p;
481
482         // Get required compiler data.
483         methodinfo*  m  = jd->m;
484         codegendata* cd = jd->cd;
485
486 # if !defined(NDEBUG)
487         if (JITDATA_HAS_FLAG_VERBOSECALL(jd)) {
488                 M_LSUB_IMM((INT_ARG_CNT + FLT_ARG_CNT) * 8, REG_SP);
489
490                 for (p = 0; p < INT_ARG_CNT; p++)
491                         M_LST(abi_registers_integer_argument[p], REG_SP, p * 8);
492
493                 for (p = 0; p < FLT_ARG_CNT; p++)
494                         M_DST(abi_registers_float_argument[p], REG_SP, (INT_ARG_CNT + p) * 8);
495
496                 syncslot_offset += (INT_ARG_CNT + FLT_ARG_CNT) * 8;
497         }
498 # endif
499
500         /* decide which monitor enter function to call */
501
502         if (m->flags & ACC_STATIC) {
503                 M_MOV_IMM(&m->clazz->object.header, REG_A0);
504         }
505         else {
506                 M_TEST(REG_A0);
507                 M_BNE(8);
508                 M_ALD_MEM(REG_A0, TRAP_NullPointerException);
509         }
510
511         M_AST(REG_A0, REG_SP, syncslot_offset);
512         M_MOV_IMM(LOCK_monitor_enter, REG_ITMP1);
513         M_CALL(REG_ITMP1);
514
515 # if !defined(NDEBUG)
516         if (JITDATA_HAS_FLAG_VERBOSECALL(jd)) {
517
518                 for (p = 0; p < INT_ARG_CNT; p++)
519                         M_LLD(abi_registers_integer_argument[p], REG_SP, p * 8);
520
521                 for (p = 0; p < FLT_ARG_CNT; p++)
522                         M_DLD(abi_registers_float_argument[p], REG_SP, (INT_ARG_CNT + p) * 8);
523
524                 M_LADD_IMM((INT_ARG_CNT + FLT_ARG_CNT) * 8, REG_SP);
525         }
526 # endif
527 }
528 #endif
529
530
531 /**
532  * Generates synchronization code to leave a monitor.
533  */
534 #if defined(ENABLE_THREADS)
535 void emit_monitor_exit(jitdata* jd, int32_t syncslot_offset)
536 {
537         // Get required compiler data.
538         methodinfo*  m  = jd->m;
539         codegendata* cd = jd->cd;
540
541         M_ALD(REG_A0, REG_SP, syncslot_offset);
542
543         /* we need to save the proper return value */
544
545         methoddesc* md = m->parseddesc;
546
547         switch (md->returntype.type) {
548         case TYPE_INT:
549         case TYPE_ADR:
550         case TYPE_LNG:
551                 M_LST(REG_RESULT, REG_SP, syncslot_offset);
552                 break;
553         case TYPE_FLT:
554         case TYPE_DBL:
555                 M_DST(REG_FRESULT, REG_SP, syncslot_offset);
556                 break;
557         }
558
559         M_MOV_IMM(LOCK_monitor_exit, REG_ITMP1);
560         M_CALL(REG_ITMP1);
561
562         /* and now restore the proper return value */
563
564         switch (md->returntype.type) {
565         case TYPE_INT:
566         case TYPE_ADR:
567         case TYPE_LNG:
568                 M_LLD(REG_RESULT, REG_SP, syncslot_offset);
569                 break;
570         case TYPE_FLT:
571         case TYPE_DBL:
572                 M_DLD(REG_FRESULT, REG_SP, syncslot_offset);
573                 break;
574         }
575 }
576 #endif
577
578
579 /**
580  * Emit profiling code for method frequency counting.
581  */
582 #if defined(ENABLE_PROFILING)
583 void emit_profile_method(codegendata* cd, codeinfo* code)
584 {
585         M_MOV_IMM(code, REG_ITMP3);
586         M_IINC_MEMBASE(REG_ITMP3, OFFSET(codeinfo, frequency));
587 }
588 #endif
589
590
591 /**
592  * Emit profiling code for basicblock frequency counting.
593  */
594 #if defined(ENABLE_PROFILING)
595 void emit_profile_basicblock(codegendata* cd, codeinfo* code, basicblock* bptr)
596 {
597         M_MOV_IMM(code->bbfrequency, REG_ITMP3);
598         M_IINC_MEMBASE(REG_ITMP3, bptr->nr * 4);
599 }
600 #endif
601
602
603 /**
604  * Emit profiling code to start CPU cycle counting.
605  */
606 #if defined(ENABLE_PROFILING)
607 void emit_profile_cycle_start(codegendata* cd, codeinfo* code)
608 {
609         M_PUSH(RAX);
610         M_PUSH(RDX);
611
612         M_MOV_IMM(code, REG_ITMP3);
613         M_RDTSC;
614         M_ISUB_MEMBASE(RAX, REG_ITMP3, OFFSET(codeinfo, cycles));
615         M_ISBB_MEMBASE(RDX, REG_ITMP3, OFFSET(codeinfo, cycles) + 4);
616
617         M_POP(RDX);
618         M_POP(RAX);
619 }
620 #endif
621
622
623 /**
624  * Emit profiling code to stop CPU cycle counting.
625  */
626 #if defined(ENABLE_PROFILING)
627 void emit_profile_cycle_stop(codegendata* cd, codeinfo* code)
628 {
629         M_PUSH(RAX);
630         M_PUSH(RDX);
631
632         M_MOV_IMM(code, REG_ITMP3);
633         M_RDTSC;
634         M_IADD_MEMBASE(RAX, REG_ITMP3, OFFSET(codeinfo, cycles));
635         M_IADC_MEMBASE(RDX, REG_ITMP3, OFFSET(codeinfo, cycles) + 4);
636
637         M_POP(RDX);
638         M_POP(RAX);
639 }
640 #endif
641
642
643 /* emit_verbosecall_enter ******************************************************
644
645    Generates the code for the call trace.
646
647 *******************************************************************************/
648
649 #if !defined(NDEBUG)
650 void emit_verbosecall_enter(jitdata *jd)
651 {
652         methodinfo   *m;
653         codeinfo     *code;
654         codegendata  *cd;
655         registerdata *rd;
656         methoddesc   *md;
657         s4            stackframesize;
658         s4            i, s;
659
660         /* get required compiler data */
661
662         m    = jd->m;
663         code = jd->code;
664         cd   = jd->cd;
665         rd   = jd->rd;
666
667         md = m->parseddesc;
668
669         /* mark trace code */
670
671         M_NOP;
672
673         /* keep 16-byte stack alignment */
674
675         stackframesize = md->paramcount + ARG_CNT + TMP_CNT;
676         ALIGN_2(stackframesize);
677
678         M_LSUB_IMM(stackframesize * 8, REG_SP);
679
680         /* save argument registers */
681
682         for (i = 0; i < md->paramcount; i++) {
683                 if (!md->params[i].inmemory) {
684                         s = md->params[i].regoff;
685
686                         switch (md->paramtypes[i].type) {
687                         case TYPE_ADR:
688                         case TYPE_INT:
689                         case TYPE_LNG:
690                                 M_LST(s, REG_SP, i * 8);
691                                 break;
692                         case TYPE_FLT:
693                         case TYPE_DBL:
694                                 M_DST(s, REG_SP, i * 8);
695                                 break;
696                         }
697                 }
698         }
699
700         /* save all argument and temporary registers for leaf methods */
701
702         if (code_is_leafmethod(code)) {
703                 for (i = 0; i < INT_ARG_CNT; i++)
704                         M_LST(abi_registers_integer_argument[i], REG_SP, (md->paramcount + i) * 8);
705
706                 for (i = 0; i < FLT_ARG_CNT; i++)
707                         M_DST(abi_registers_float_argument[i], REG_SP, (md->paramcount + INT_ARG_CNT + i) * 8);
708
709                 for (i = 0; i < INT_TMP_CNT; i++)
710                         M_LST(rd->tmpintregs[i], REG_SP, (md->paramcount + ARG_CNT + i) * 8);
711
712                 for (i = 0; i < FLT_TMP_CNT; i++)
713                         M_DST(rd->tmpfltregs[i], REG_SP, (md->paramcount + ARG_CNT + INT_TMP_CNT + i) * 8);
714         }
715
716         M_MOV_IMM(m, REG_A0);
717         M_MOV(REG_SP, REG_A1);
718         M_MOV(REG_SP, REG_A2);
719         M_AADD_IMM((stackframesize + cd->stackframesize + 1) * 8, REG_A2);
720         M_MOV_IMM(trace_java_call_enter, REG_ITMP1);
721         M_CALL(REG_ITMP1);
722
723         /* restore argument registers */
724
725         for (i = 0; i < md->paramcount; i++) {
726                 if (!md->params[i].inmemory) {
727                         s = md->params[i].regoff;
728
729                         switch (md->paramtypes[i].type) {
730                         case TYPE_ADR:
731                         case TYPE_INT:
732                         case TYPE_LNG:
733                                 M_LLD(s, REG_SP, i * 8);
734                                 break;
735                         case TYPE_FLT:
736                         case TYPE_DBL:
737                                 M_DLD(s, REG_SP, i * 8);
738                                 break;
739                         }
740                 }
741         }
742
743
744         /* restore all argument and temporary registers for leaf methods */
745
746         if (code_is_leafmethod(code)) {
747                 for (i = 0; i < INT_ARG_CNT; i++)
748                         M_LLD(abi_registers_integer_argument[i], REG_SP, (md->paramcount + i) * 8);
749
750                 for (i = 0; i < FLT_ARG_CNT; i++)
751                         M_DLD(abi_registers_float_argument[i], REG_SP, (md->paramcount + INT_ARG_CNT + i) * 8);
752
753                 for (i = 0; i < INT_TMP_CNT; i++)
754                         M_LLD(rd->tmpintregs[i], REG_SP, (md->paramcount + ARG_CNT + i) * 8);
755
756                 for (i = 0; i < FLT_TMP_CNT; i++)
757                         M_DLD(rd->tmpfltregs[i], REG_SP, (md->paramcount + ARG_CNT + INT_TMP_CNT + i) * 8);
758         }
759
760         M_LADD_IMM(stackframesize * 8, REG_SP);
761
762         /* mark trace code */
763
764         M_NOP;
765 }
766 #endif /* !defined(NDEBUG) */
767
768
769 /* emit_verbosecall_exit *******************************************************
770
771    Generates the code for the call trace.
772
773 *******************************************************************************/
774
775 #if !defined(NDEBUG)
776 void emit_verbosecall_exit(jitdata *jd)
777 {
778         methodinfo   *m;
779         codegendata  *cd;
780         registerdata *rd;
781         methoddesc   *md;
782
783         /* get required compiler data */
784
785         m  = jd->m;
786         cd = jd->cd;
787         rd = jd->rd;
788
789         md = m->parseddesc;
790
791         /* mark trace code */
792
793         M_NOP;
794
795         /* keep 16-byte stack alignment */
796
797         M_ASUB_IMM(2 * 8, REG_SP);
798
799         /* save return value */
800
801         switch (md->returntype.type) {
802         case TYPE_ADR:
803         case TYPE_INT:
804         case TYPE_LNG:
805                 M_LST(REG_RESULT, REG_SP, 0 * 8);
806                 break;
807         case TYPE_FLT:
808         case TYPE_DBL:
809                 M_DST(REG_FRESULT, REG_SP, 0 * 8);
810                 break;
811         }
812
813         M_MOV_IMM(m, REG_A0);
814         M_MOV(REG_SP, REG_A1);
815
816         M_MOV_IMM(trace_java_call_exit, REG_ITMP1);
817         M_CALL(REG_ITMP1);
818
819         /* restore return value */
820
821         switch (md->returntype.type) {
822         case TYPE_ADR:
823         case TYPE_INT:
824         case TYPE_LNG:
825                 M_LLD(REG_RESULT, REG_SP, 0 * 8);
826                 break;
827         case TYPE_FLT:
828         case TYPE_DBL:
829                 M_DLD(REG_FRESULT, REG_SP, 0 * 8);
830                 break;
831         }
832
833         M_AADD_IMM(2 * 8, REG_SP);
834
835         /* mark trace code */
836
837         M_NOP;
838 }
839 #endif /* !defined(NDEBUG) */
840
841
842 /* code generation functions **************************************************/
843
844 static void emit_membase(codegendata *cd, s4 basereg, s4 disp, s4 dreg)
845 {
846         if ((basereg == REG_SP) || (basereg == R12)) {
847                 if (disp == 0) {
848                         emit_address_byte(0, dreg, REG_SP);
849                         emit_address_byte(0, REG_SP, REG_SP);
850
851                 } else if (IS_IMM8(disp)) {
852                         emit_address_byte(1, dreg, REG_SP);
853                         emit_address_byte(0, REG_SP, REG_SP);
854                         emit_imm8(disp);
855
856                 } else {
857                         emit_address_byte(2, dreg, REG_SP);
858                         emit_address_byte(0, REG_SP, REG_SP);
859                         emit_imm32(disp);
860                 }
861
862         } else if ((disp) == 0 && (basereg) != RBP && (basereg) != R13) {
863                 emit_address_byte(0,(dreg),(basereg));
864
865         } else if ((basereg) == RIP) {
866                 emit_address_byte(0, dreg, RBP);
867                 emit_imm32(disp);
868
869         } else {
870                 if (IS_IMM8(disp)) {
871                         emit_address_byte(1, dreg, basereg);
872                         emit_imm8(disp);
873
874                 } else {
875                         emit_address_byte(2, dreg, basereg);
876                         emit_imm32(disp);
877                 }
878         }
879 }
880
881
882 static void emit_membase32(codegendata *cd, s4 basereg, s4 disp, s4 dreg)
883 {
884         if ((basereg == REG_SP) || (basereg == R12)) {
885                 emit_address_byte(2, dreg, REG_SP);
886                 emit_address_byte(0, REG_SP, REG_SP);
887                 emit_imm32(disp);
888         }
889         else {
890                 emit_address_byte(2, dreg, basereg);
891                 emit_imm32(disp);
892         }
893 }
894
895
896 static void emit_memindex(codegendata *cd, s4 reg, s4 disp, s4 basereg, s4 indexreg, s4 scale)
897 {
898         if (basereg == -1) {
899                 emit_address_byte(0, reg, 4);
900                 emit_address_byte(scale, indexreg, 5);
901                 emit_imm32(disp);
902         }
903         else if ((disp == 0) && (basereg != RBP) && (basereg != R13)) {
904                 emit_address_byte(0, reg, 4);
905                 emit_address_byte(scale, indexreg, basereg);
906         }
907         else if (IS_IMM8(disp)) {
908                 emit_address_byte(1, reg, 4);
909                 emit_address_byte(scale, indexreg, basereg);
910                 emit_imm8(disp);
911         }
912         else {
913                 emit_address_byte(2, reg, 4);
914                 emit_address_byte(scale, indexreg, basereg);
915                 emit_imm32(disp);
916         }
917 }
918
919
920 void emit_ishift(jitdata *jd, s4 shift_op, instruction *iptr)
921 {
922         s4 s1, s2, d, d_old;
923         varinfo *v_s1,*v_s2,*v_dst;
924         codegendata *cd;
925
926         /* get required compiler data */
927
928         cd = jd->cd;
929
930         v_s1  = VAROP(iptr->s1);
931         v_s2  = VAROP(iptr->sx.s23.s2);
932         v_dst = VAROP(iptr->dst);
933
934         s1 = v_s1->vv.regoff;
935         s2 = v_s2->vv.regoff;
936         d  = v_dst->vv.regoff;
937
938         M_INTMOVE(RCX, REG_ITMP1);                                    /* save RCX */
939
940         if (IS_INMEMORY(v_dst->flags)) {
941                 if (IS_INMEMORY(v_s2->flags) && IS_INMEMORY(v_s1->flags)) {
942                         if (s1 == d) {
943                                 M_ILD(RCX, REG_SP, s2);
944                                 emit_shiftl_membase(cd, shift_op, REG_SP, d);
945
946                         } else {
947                                 M_ILD(RCX, REG_SP, s2);
948                                 M_ILD(REG_ITMP2, REG_SP, s1);
949                                 emit_shiftl_reg(cd, shift_op, REG_ITMP2);
950                                 M_IST(REG_ITMP2, REG_SP, d);
951                         }
952
953                 } else if (IS_INMEMORY(v_s2->flags) && !IS_INMEMORY(v_s1->flags)) {
954                         /* s1 may be equal to RCX */
955                         if (s1 == RCX) {
956                                 if (s2 == d) {
957                                         M_ILD(REG_ITMP1, REG_SP, s2);
958                                         M_IST(s1, REG_SP, d);
959                                         M_INTMOVE(REG_ITMP1, RCX);
960
961                                 } else {
962                                         M_IST(s1, REG_SP, d);
963                                         M_ILD(RCX, REG_SP, s2);
964                                 }
965
966                         } else {
967                                 M_ILD(RCX, REG_SP, s2);
968                                 M_IST(s1, REG_SP, d);
969                         }
970
971                         emit_shiftl_membase(cd, shift_op, REG_SP, d);
972
973                 } else if (!IS_INMEMORY(v_s2->flags) && IS_INMEMORY(v_s1->flags)) {
974                         if (s1 == d) {
975                                 M_INTMOVE(s2, RCX);
976                                 emit_shiftl_membase(cd, shift_op, REG_SP, d);
977
978                         } else {
979                                 M_INTMOVE(s2, RCX);
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 {
986                         /* s1 may be equal to RCX */
987                         M_IST(s1, REG_SP, d);
988                         M_INTMOVE(s2, RCX);
989                         emit_shiftl_membase(cd, shift_op, REG_SP, d);
990                 }
991
992                 M_INTMOVE(REG_ITMP1, RCX);                             /* restore RCX */
993
994         } else {
995                 d_old = d;
996                 if (d == RCX) {
997                         d = REG_ITMP3;
998                 }
999                                         
1000                 if (IS_INMEMORY(v_s2->flags) && IS_INMEMORY(v_s1->flags)) {
1001                         M_ILD(RCX, REG_SP, s2);
1002                         M_ILD(d, REG_SP, s1);
1003                         emit_shiftl_reg(cd, shift_op, d);
1004
1005                 } else if (IS_INMEMORY(v_s2->flags) && !IS_INMEMORY(v_s1->flags)) {
1006                         /* s1 may be equal to RCX */
1007                         M_INTMOVE(s1, d);
1008                         M_ILD(RCX, REG_SP, s2);
1009                         emit_shiftl_reg(cd, shift_op, d);
1010
1011                 } else if (!IS_INMEMORY(v_s2->flags) && IS_INMEMORY(v_s1->flags)) {
1012                         M_INTMOVE(s2, RCX);
1013                         M_ILD(d, REG_SP, s1);
1014                         emit_shiftl_reg(cd, shift_op, d);
1015
1016                 } else {
1017                         /* s1 may be equal to RCX */
1018                         if (s1 == RCX) {
1019                                 if (s2 == d) {
1020                                         /* d cannot be used to backup s1 since this would
1021                                            overwrite s2. */
1022                                         M_INTMOVE(s1, REG_ITMP3);
1023                                         M_INTMOVE(s2, RCX);
1024                                         M_INTMOVE(REG_ITMP3, d);
1025
1026                                 } else {
1027                                         M_INTMOVE(s1, d);
1028                                         M_INTMOVE(s2, RCX);
1029                                 }
1030
1031                         } else {
1032                                 /* d may be equal to s2 */
1033                                 M_INTMOVE(s2, RCX);
1034                                 M_INTMOVE(s1, d);
1035                         }
1036                         emit_shiftl_reg(cd, shift_op, d);
1037                 }
1038
1039                 if (d_old == RCX)
1040                         M_INTMOVE(REG_ITMP3, RCX);
1041                 else
1042                         M_INTMOVE(REG_ITMP1, RCX);                         /* restore RCX */
1043         }
1044 }
1045
1046
1047 void emit_lshift(jitdata *jd, s4 shift_op, instruction *iptr)
1048 {
1049         s4 s1, s2, d, d_old;
1050         varinfo *v_s1,*v_s2,*v_dst;
1051         codegendata *cd;
1052
1053         /* get required compiler data */
1054
1055         cd = jd->cd;
1056
1057         v_s1  = VAROP(iptr->s1);
1058         v_s2  = VAROP(iptr->sx.s23.s2);
1059         v_dst = VAROP(iptr->dst);
1060
1061         s1 = v_s1->vv.regoff;
1062         s2 = v_s2->vv.regoff;
1063         d  = v_dst->vv.regoff;
1064         
1065         M_INTMOVE(RCX, REG_ITMP1);                                    /* save RCX */
1066
1067         if (IS_INMEMORY(v_dst->flags)) {
1068                 if (IS_INMEMORY(v_s2->flags) && IS_INMEMORY(v_s1->flags)) {
1069                         if (s1 == d) {
1070                                 M_ILD(RCX, REG_SP, s2);
1071                                 emit_shift_membase(cd, shift_op, REG_SP, d);
1072
1073                         } else {
1074                                 M_ILD(RCX, REG_SP, s2);
1075                                 M_LLD(REG_ITMP2, REG_SP, s1);
1076                                 emit_shift_reg(cd, shift_op, REG_ITMP2);
1077                                 M_LST(REG_ITMP2, REG_SP, d);
1078                         }
1079
1080                 } else if (IS_INMEMORY(v_s2->flags) && !IS_INMEMORY(v_s1->flags)) {
1081                         /* s1 may be equal to RCX */
1082                         if (s1 == RCX) {
1083                                 if (s2 == d) {
1084                                         M_ILD(REG_ITMP1, REG_SP, s2);
1085                                         M_LST(s1, REG_SP, d);
1086                                         M_INTMOVE(REG_ITMP1, RCX);
1087
1088                                 } else {
1089                                         M_LST(s1, REG_SP, d);
1090                                         M_ILD(RCX, REG_SP, s2);
1091                                 }
1092
1093                         } else {
1094                                 M_ILD(RCX, REG_SP, s2);
1095                                 M_LST(s1, REG_SP, d);
1096                         }
1097
1098                         emit_shift_membase(cd, shift_op, REG_SP, d);
1099
1100                 } else if (!IS_INMEMORY(v_s2->flags) && IS_INMEMORY(v_s1->flags)) {
1101                         if (s1 == d) {
1102                                 M_INTMOVE(s2, RCX);
1103                                 emit_shift_membase(cd, shift_op, REG_SP, d);
1104
1105                         } else {
1106                                 M_INTMOVE(s2, RCX);
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 {
1113                         /* s1 may be equal to RCX */
1114                         M_LST(s1, REG_SP, d);
1115                         M_INTMOVE(s2, RCX);
1116                         emit_shift_membase(cd, shift_op, REG_SP, d);
1117                 }
1118
1119                 M_INTMOVE(REG_ITMP1, RCX);                             /* restore RCX */
1120
1121         } else {
1122                 d_old = d;
1123                 if (d == RCX) {
1124                         d = REG_ITMP3;
1125                 }
1126
1127                 if (IS_INMEMORY(v_s2->flags) && IS_INMEMORY(v_s1->flags)) {
1128                         M_ILD(RCX, REG_SP, s2);
1129                         M_LLD(d, REG_SP, s1);
1130                         emit_shift_reg(cd, shift_op, d);
1131
1132                 } else if (IS_INMEMORY(v_s2->flags) && !IS_INMEMORY(v_s1->flags)) {
1133                         /* s1 may be equal to RCX */
1134                         M_INTMOVE(s1, d);
1135                         M_ILD(RCX, REG_SP, s2);
1136                         emit_shift_reg(cd, shift_op, d);
1137
1138                 } else if (!IS_INMEMORY(v_s2->flags) && IS_INMEMORY(v_s1->flags)) {
1139                         M_INTMOVE(s2, RCX);
1140                         M_LLD(d, REG_SP, s1);
1141                         emit_shift_reg(cd, shift_op, d);
1142
1143                 } else {
1144                         /* s1 may be equal to RCX */
1145                         if (s1 == RCX) {
1146                                 if (s2 == d) {
1147                                         /* d cannot be used to backup s1 since this would
1148                                            overwrite s2. */
1149                                         M_INTMOVE(s1, REG_ITMP3);
1150                                         M_INTMOVE(s2, RCX);
1151                                         M_INTMOVE(REG_ITMP3, d);
1152
1153                                 } else {
1154                                         M_INTMOVE(s1, d);
1155                                         M_INTMOVE(s2, RCX);
1156                                 }
1157
1158                         } else {
1159                                 /* d may be equal to s2 */
1160                                 M_INTMOVE(s2, RCX);
1161                                 M_INTMOVE(s1, d);
1162                         }
1163                         emit_shift_reg(cd, shift_op, d);
1164                 }
1165
1166                 if (d_old == RCX)
1167                         M_INTMOVE(REG_ITMP3, RCX);
1168                 else
1169                         M_INTMOVE(REG_ITMP1, RCX);                         /* restore RCX */
1170         }
1171 }
1172
1173
1174 /* low-level code emitter functions *******************************************/
1175
1176 void emit_mov_reg_reg(codegendata *cd, s8 reg, s8 dreg)
1177 {
1178         emit_rex(1,(reg),0,(dreg));
1179         *(cd->mcodeptr++) = 0x89;
1180         emit_reg((reg),(dreg));
1181 }
1182
1183
1184 void emit_mov_imm_reg(codegendata *cd, s8 imm, s8 reg)
1185 {
1186         emit_rex(1,0,0,(reg));
1187         *(cd->mcodeptr++) = 0xb8 + ((reg) & 0x07);
1188         emit_imm64((imm));
1189 }
1190
1191
1192 void emit_movl_reg_reg(codegendata *cd, s8 reg, s8 dreg)
1193 {
1194         emit_rex(0,(reg),0,(dreg));
1195         *(cd->mcodeptr++) = 0x89;
1196         emit_reg((reg),(dreg));
1197 }
1198
1199
1200 void emit_movl_imm_reg(codegendata *cd, s8 imm, s8 reg) {
1201         emit_rex(0,0,0,(reg));
1202         *(cd->mcodeptr++) = 0xb8 + ((reg) & 0x07);
1203         emit_imm32((imm));
1204 }
1205
1206
1207 void emit_mov_membase_reg(codegendata *cd, s8 basereg, s8 disp, s8 reg) {
1208         emit_rex(1,(reg),0,(basereg));
1209         *(cd->mcodeptr++) = 0x8b;
1210         emit_membase(cd, (basereg),(disp),(reg));
1211 }
1212
1213
1214 /*
1215  * this one is for INVOKEVIRTUAL/INVOKEINTERFACE to have a
1216  * constant membase immediate length of 32bit
1217  */
1218 void emit_mov_membase32_reg(codegendata *cd, s8 basereg, s8 disp, s8 reg) {
1219         emit_rex(1,(reg),0,(basereg));
1220         *(cd->mcodeptr++) = 0x8b;
1221         emit_membase32(cd, (basereg),(disp),(reg));
1222 }
1223
1224
1225 void emit_movl_membase_reg(codegendata *cd, s8 basereg, s8 disp, s8 reg)
1226 {
1227         emit_rex(0,(reg),0,(basereg));
1228         *(cd->mcodeptr++) = 0x8b;
1229         emit_membase(cd, (basereg),(disp),(reg));
1230 }
1231
1232
1233 /* ATTENTION: Always emit a REX byte, because the instruction size can
1234    be smaller when all register indexes are smaller than 7. */
1235 void emit_movl_membase32_reg(codegendata *cd, s8 basereg, s8 disp, s8 reg)
1236 {
1237         emit_byte_rex((reg),0,(basereg));
1238         *(cd->mcodeptr++) = 0x8b;
1239         emit_membase32(cd, (basereg),(disp),(reg));
1240 }
1241
1242
1243 void emit_mov_reg_membase(codegendata *cd, s8 reg, s8 basereg, s8 disp) {
1244         emit_rex(1,(reg),0,(basereg));
1245         *(cd->mcodeptr++) = 0x89;
1246         emit_membase(cd, (basereg),(disp),(reg));
1247 }
1248
1249
1250 void emit_mov_reg_membase32(codegendata *cd, s8 reg, s8 basereg, s8 disp) {
1251         emit_rex(1,(reg),0,(basereg));
1252         *(cd->mcodeptr++) = 0x89;
1253         emit_membase32(cd, (basereg),(disp),(reg));
1254 }
1255
1256
1257 void emit_movl_reg_membase(codegendata *cd, s8 reg, s8 basereg, s8 disp) {
1258         emit_rex(0,(reg),0,(basereg));
1259         *(cd->mcodeptr++) = 0x89;
1260         emit_membase(cd, (basereg),(disp),(reg));
1261 }
1262
1263
1264 /* Always emit a REX byte, because the instruction size can be smaller when   */
1265 /* all register indexes are smaller than 7.                                   */
1266 void emit_movl_reg_membase32(codegendata *cd, s8 reg, s8 basereg, s8 disp) {
1267         emit_byte_rex((reg),0,(basereg));
1268         *(cd->mcodeptr++) = 0x89;
1269         emit_membase32(cd, (basereg),(disp),(reg));
1270 }
1271
1272
1273 void emit_mov_memindex_reg(codegendata *cd, s8 disp, s8 basereg, s8 indexreg, s8 scale, s8 reg) {
1274         emit_rex(1,(reg),(indexreg),(basereg));
1275         *(cd->mcodeptr++) = 0x8b;
1276         emit_memindex(cd, (reg),(disp),(basereg),(indexreg),(scale));
1277 }
1278
1279
1280 void emit_movl_memindex_reg(codegendata *cd, s8 disp, s8 basereg, s8 indexreg, s8 scale, s8 reg) {
1281         emit_rex(0,(reg),(indexreg),(basereg));
1282         *(cd->mcodeptr++) = 0x8b;
1283         emit_memindex(cd, (reg),(disp),(basereg),(indexreg),(scale));
1284 }
1285
1286
1287 void emit_mov_reg_memindex(codegendata *cd, s8 reg, s8 disp, s8 basereg, s8 indexreg, s8 scale) {
1288         emit_rex(1,(reg),(indexreg),(basereg));
1289         *(cd->mcodeptr++) = 0x89;
1290         emit_memindex(cd, (reg),(disp),(basereg),(indexreg),(scale));
1291 }
1292
1293
1294 void emit_movl_reg_memindex(codegendata *cd, s8 reg, s8 disp, s8 basereg, s8 indexreg, s8 scale) {
1295         emit_rex(0,(reg),(indexreg),(basereg));
1296         *(cd->mcodeptr++) = 0x89;
1297         emit_memindex(cd, (reg),(disp),(basereg),(indexreg),(scale));
1298 }
1299
1300
1301 void emit_movw_reg_memindex(codegendata *cd, s8 reg, s8 disp, s8 basereg, s8 indexreg, s8 scale) {
1302         *(cd->mcodeptr++) = 0x66;
1303         emit_rex(0,(reg),(indexreg),(basereg));
1304         *(cd->mcodeptr++) = 0x89;
1305         emit_memindex(cd, (reg),(disp),(basereg),(indexreg),(scale));
1306 }
1307
1308
1309 void emit_movb_reg_memindex(codegendata *cd, s8 reg, s8 disp, s8 basereg, s8 indexreg, s8 scale) {
1310         emit_byte_rex((reg),(indexreg),(basereg));
1311         *(cd->mcodeptr++) = 0x88;
1312         emit_memindex(cd, (reg),(disp),(basereg),(indexreg),(scale));
1313 }
1314
1315
1316 void emit_mov_imm_membase(codegendata *cd, s8 imm, s8 basereg, s8 disp) {
1317         emit_rex(1,0,0,(basereg));
1318         *(cd->mcodeptr++) = 0xc7;
1319         emit_membase(cd, (basereg),(disp),0);
1320         emit_imm32((imm));
1321 }
1322
1323
1324 void emit_mov_imm_membase32(codegendata *cd, s8 imm, s8 basereg, s8 disp) {
1325         emit_rex(1,0,0,(basereg));
1326         *(cd->mcodeptr++) = 0xc7;
1327         emit_membase32(cd, (basereg),(disp),0);
1328         emit_imm32((imm));
1329 }
1330
1331
1332 void emit_movl_imm_membase(codegendata *cd, s8 imm, s8 basereg, s8 disp) {
1333         emit_rex(0,0,0,(basereg));
1334         *(cd->mcodeptr++) = 0xc7;
1335         emit_membase(cd, (basereg),(disp),0);
1336         emit_imm32((imm));
1337 }
1338
1339
1340 /* Always emit a REX byte, because the instruction size can be smaller when   */
1341 /* all register indexes are smaller than 7.                                   */
1342 void emit_movl_imm_membase32(codegendata *cd, s8 imm, s8 basereg, s8 disp) {
1343         emit_byte_rex(0,0,(basereg));
1344         *(cd->mcodeptr++) = 0xc7;
1345         emit_membase32(cd, (basereg),(disp),0);
1346         emit_imm32((imm));
1347 }
1348
1349
1350 void emit_movsbq_reg_reg(codegendata *cd, s8 reg, s8 dreg)
1351 {
1352         emit_rex(1,(dreg),0,(reg));
1353         *(cd->mcodeptr++) = 0x0f;
1354         *(cd->mcodeptr++) = 0xbe;
1355         /* XXX: why do reg and dreg have to be exchanged */
1356         emit_reg((dreg),(reg));
1357 }
1358
1359
1360 void emit_movswq_reg_reg(codegendata *cd, s8 reg, s8 dreg)
1361 {
1362         emit_rex(1,(dreg),0,(reg));
1363         *(cd->mcodeptr++) = 0x0f;
1364         *(cd->mcodeptr++) = 0xbf;
1365         /* XXX: why do reg and dreg have to be exchanged */
1366         emit_reg((dreg),(reg));
1367 }
1368
1369
1370 void emit_movslq_reg_reg(codegendata *cd, s8 reg, s8 dreg)
1371 {
1372         emit_rex(1,(dreg),0,(reg));
1373         *(cd->mcodeptr++) = 0x63;
1374         /* XXX: why do reg and dreg have to be exchanged */
1375         emit_reg((dreg),(reg));
1376 }
1377
1378
1379 void emit_movzbq_reg_reg(codegendata *cd, s8 reg, s8 dreg)
1380 {
1381         emit_rex(1,(dreg),0,(reg));
1382         *(cd->mcodeptr++) = 0x0f;
1383         *(cd->mcodeptr++) = 0xb6;
1384         /* XXX: why do reg and dreg have to be exchanged */
1385         emit_reg((dreg),(reg));
1386 }
1387
1388
1389 void emit_movzwq_reg_reg(codegendata *cd, s8 reg, s8 dreg)
1390 {
1391         emit_rex(1,(dreg),0,(reg));
1392         *(cd->mcodeptr++) = 0x0f;
1393         *(cd->mcodeptr++) = 0xb7;
1394         /* XXX: why do reg and dreg have to be exchanged */
1395         emit_reg((dreg),(reg));
1396 }
1397
1398
1399 void emit_movswq_memindex_reg(codegendata *cd, s8 disp, s8 basereg, s8 indexreg, s8 scale, s8 reg) {
1400         emit_rex(1,(reg),(indexreg),(basereg));
1401         *(cd->mcodeptr++) = 0x0f;
1402         *(cd->mcodeptr++) = 0xbf;
1403         emit_memindex(cd, (reg),(disp),(basereg),(indexreg),(scale));
1404 }
1405
1406
1407 void emit_movsbq_memindex_reg(codegendata *cd, s8 disp, s8 basereg, s8 indexreg, s8 scale, s8 reg) {
1408         emit_rex(1,(reg),(indexreg),(basereg));
1409         *(cd->mcodeptr++) = 0x0f;
1410         *(cd->mcodeptr++) = 0xbe;
1411         emit_memindex(cd, (reg),(disp),(basereg),(indexreg),(scale));
1412 }
1413
1414
1415 void emit_movzwq_memindex_reg(codegendata *cd, s8 disp, s8 basereg, s8 indexreg, s8 scale, s8 reg) {
1416         emit_rex(1,(reg),(indexreg),(basereg));
1417         *(cd->mcodeptr++) = 0x0f;
1418         *(cd->mcodeptr++) = 0xb7;
1419         emit_memindex(cd, (reg),(disp),(basereg),(indexreg),(scale));
1420 }
1421
1422
1423 void emit_mov_imm_memindex(codegendata *cd, s4 imm, s4 disp, s4 basereg, s4 indexreg, s4 scale)
1424 {
1425         emit_rex(1,0,(indexreg),(basereg));
1426         *(cd->mcodeptr++) = 0xc7;
1427         emit_memindex(cd, 0,(disp),(basereg),(indexreg),(scale));
1428         emit_imm32((imm));
1429 }
1430
1431
1432 void emit_movl_imm_memindex(codegendata *cd, s4 imm, s4 disp, s4 basereg, s4 indexreg, s4 scale)
1433 {
1434         emit_rex(0,0,(indexreg),(basereg));
1435         *(cd->mcodeptr++) = 0xc7;
1436         emit_memindex(cd, 0,(disp),(basereg),(indexreg),(scale));
1437         emit_imm32((imm));
1438 }
1439
1440
1441 void emit_movw_imm_memindex(codegendata *cd, s4 imm, s4 disp, s4 basereg, s4 indexreg, s4 scale)
1442 {
1443         *(cd->mcodeptr++) = 0x66;
1444         emit_rex(0,0,(indexreg),(basereg));
1445         *(cd->mcodeptr++) = 0xc7;
1446         emit_memindex(cd, 0,(disp),(basereg),(indexreg),(scale));
1447         emit_imm16((imm));
1448 }
1449
1450
1451 void emit_movb_imm_memindex(codegendata *cd, s4 imm, s4 disp, s4 basereg, s4 indexreg, s4 scale)
1452 {
1453         emit_rex(0,0,(indexreg),(basereg));
1454         *(cd->mcodeptr++) = 0xc6;
1455         emit_memindex(cd, 0,(disp),(basereg),(indexreg),(scale));
1456         emit_imm8((imm));
1457 }
1458
1459
1460 void emit_mov_mem_reg(codegendata *cd, s4 disp, s4 dreg)
1461 {
1462         emit_rex(1, dreg, 0, 0);
1463         *(cd->mcodeptr++) = 0x8b;
1464         emit_address_byte(0, dreg, 4);
1465         emit_mem(4, disp);
1466 }
1467
1468
1469 /*
1470  * alu operations
1471  */
1472 void emit_alu_reg_reg(codegendata *cd, s8 opc, s8 reg, s8 dreg)
1473 {
1474         emit_rex(1,(reg),0,(dreg));
1475         *(cd->mcodeptr++) = (((opc)) << 3) + 1;
1476         emit_reg((reg),(dreg));
1477 }
1478
1479
1480 void emit_alul_reg_reg(codegendata *cd, s8 opc, s8 reg, s8 dreg)
1481 {
1482         emit_rex(0,(reg),0,(dreg));
1483         *(cd->mcodeptr++) = (((opc)) << 3) + 1;
1484         emit_reg((reg),(dreg));
1485 }
1486
1487
1488 void emit_alu_reg_membase(codegendata *cd, s8 opc, s8 reg, s8 basereg, s8 disp)
1489 {
1490         emit_rex(1,(reg),0,(basereg));
1491         *(cd->mcodeptr++) = (((opc)) << 3) + 1;
1492         emit_membase(cd, (basereg),(disp),(reg));
1493 }
1494
1495
1496 void emit_alul_reg_membase(codegendata *cd, s8 opc, s8 reg, s8 basereg, s8 disp)
1497 {
1498         emit_rex(0,(reg),0,(basereg));
1499         *(cd->mcodeptr++) = (((opc)) << 3) + 1;
1500         emit_membase(cd, (basereg),(disp),(reg));
1501 }
1502
1503
1504 void emit_alu_membase_reg(codegendata *cd, s8 opc, s8 basereg, s8 disp, s8 reg)
1505 {
1506         emit_rex(1,(reg),0,(basereg));
1507         *(cd->mcodeptr++) = (((opc)) << 3) + 3;
1508         emit_membase(cd, (basereg),(disp),(reg));
1509 }
1510
1511
1512 void emit_alul_membase_reg(codegendata *cd, s8 opc, s8 basereg, s8 disp, s8 reg)
1513 {
1514         emit_rex(0,(reg),0,(basereg));
1515         *(cd->mcodeptr++) = (((opc)) << 3) + 3;
1516         emit_membase(cd, (basereg),(disp),(reg));
1517 }
1518
1519
1520 void emit_alu_imm_reg(codegendata *cd, s8 opc, s8 imm, s8 dreg) {
1521         if (IS_IMM8(imm)) {
1522                 emit_rex(1,0,0,(dreg));
1523                 *(cd->mcodeptr++) = 0x83;
1524                 emit_reg((opc),(dreg));
1525                 emit_imm8((imm));
1526         } else {
1527                 emit_rex(1,0,0,(dreg));
1528                 *(cd->mcodeptr++) = 0x81;
1529                 emit_reg((opc),(dreg));
1530                 emit_imm32((imm));
1531         }
1532 }
1533
1534
1535 void emit_alu_imm32_reg(codegendata *cd, s4 opc, s4 imm, s4 dreg)
1536 {
1537         emit_rex(1,0,0,(dreg));
1538         *(cd->mcodeptr++) = 0x81;
1539         emit_reg((opc),(dreg));
1540         emit_imm32((imm));
1541 }
1542
1543
1544 void emit_alul_imm32_reg(codegendata *cd, s4 opc, s4 imm, s4 dreg)
1545 {
1546         emit_rex(0,0,0,(dreg));
1547         *(cd->mcodeptr++) = 0x81;
1548         emit_reg((opc),(dreg));
1549         emit_imm32((imm));
1550 }
1551
1552
1553 void emit_alul_imm_reg(codegendata *cd, s8 opc, s8 imm, s8 dreg) {
1554         if (IS_IMM8(imm)) {
1555                 emit_rex(0,0,0,(dreg));
1556                 *(cd->mcodeptr++) = 0x83;
1557                 emit_reg((opc),(dreg));
1558                 emit_imm8((imm));
1559         } else {
1560                 emit_rex(0,0,0,(dreg));
1561                 *(cd->mcodeptr++) = 0x81;
1562                 emit_reg((opc),(dreg));
1563                 emit_imm32((imm));
1564         }
1565 }
1566
1567
1568 void emit_alu_imm_membase(codegendata *cd, s8 opc, s8 imm, s8 basereg, s8 disp) {
1569         if (IS_IMM8(imm)) {
1570                 emit_rex(1,0,0,(basereg));
1571                 *(cd->mcodeptr++) = 0x83;
1572                 emit_membase(cd, (basereg),(disp),(opc));
1573                 emit_imm8((imm));
1574         } else {
1575                 emit_rex(1,0,0,(basereg));
1576                 *(cd->mcodeptr++) = 0x81;
1577                 emit_membase(cd, (basereg),(disp),(opc));
1578                 emit_imm32((imm));
1579         }
1580 }
1581
1582
1583 void emit_alul_imm_membase(codegendata *cd, s8 opc, s8 imm, s8 basereg, s8 disp) {
1584         if (IS_IMM8(imm)) {
1585                 emit_rex(0,0,0,(basereg));
1586                 *(cd->mcodeptr++) = 0x83;
1587                 emit_membase(cd, (basereg),(disp),(opc));
1588                 emit_imm8((imm));
1589         } else {
1590                 emit_rex(0,0,0,(basereg));
1591                 *(cd->mcodeptr++) = 0x81;
1592                 emit_membase(cd, (basereg),(disp),(opc));
1593                 emit_imm32((imm));
1594         }
1595 }
1596
1597 void emit_alu_memindex_reg(codegendata *cd, s8 opc, s8 disp, s8 basereg, s8 indexreg, s8 scale, s8 reg)
1598 {
1599         emit_rex(1,(reg),(indexreg),(basereg));
1600         *(cd->mcodeptr++) = (((opc)) << 3) + 3;
1601         emit_memindex(cd, (reg),(disp),(basereg),(indexreg),(scale));
1602 }
1603
1604 void emit_alul_memindex_reg(codegendata *cd, s8 opc, s8 disp, s8 basereg, s8 indexreg, s8 scale, s8 reg)
1605 {
1606         emit_rex(0,(reg),(indexreg),(basereg));
1607         *(cd->mcodeptr++) = (((opc)) << 3) + 3;
1608         emit_memindex(cd, (reg),(disp),(basereg),(indexreg),(scale));
1609 }
1610
1611 void emit_test_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
1612         emit_rex(1,(reg),0,(dreg));
1613         *(cd->mcodeptr++) = 0x85;
1614         emit_reg((reg),(dreg));
1615 }
1616
1617
1618 void emit_testl_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
1619         emit_rex(0,(reg),0,(dreg));
1620         *(cd->mcodeptr++) = 0x85;
1621         emit_reg((reg),(dreg));
1622 }
1623
1624
1625 void emit_test_imm_reg(codegendata *cd, s8 imm, s8 reg) {
1626         *(cd->mcodeptr++) = 0xf7;
1627         emit_reg(0,(reg));
1628         emit_imm32((imm));
1629 }
1630
1631
1632 void emit_testw_imm_reg(codegendata *cd, s8 imm, s8 reg) {
1633         *(cd->mcodeptr++) = 0x66;
1634         *(cd->mcodeptr++) = 0xf7;
1635         emit_reg(0,(reg));
1636         emit_imm16((imm));
1637 }
1638
1639
1640 void emit_testb_imm_reg(codegendata *cd, s8 imm, s8 reg) {
1641         *(cd->mcodeptr++) = 0xf6;
1642         emit_reg(0,(reg));
1643         emit_imm8((imm));
1644 }
1645
1646
1647 void emit_lea_membase_reg(codegendata *cd, s8 basereg, s8 disp, s8 reg) {
1648         emit_rex(1,(reg),0,(basereg));
1649         *(cd->mcodeptr++) = 0x8d;
1650         emit_membase(cd, (basereg),(disp),(reg));
1651 }
1652
1653
1654 void emit_leal_membase_reg(codegendata *cd, s8 basereg, s8 disp, s8 reg) {
1655         emit_rex(0,(reg),0,(basereg));
1656         *(cd->mcodeptr++) = 0x8d;
1657         emit_membase(cd, (basereg),(disp),(reg));
1658 }
1659
1660
1661 void emit_incl_reg(codegendata *cd, s8 reg)
1662 {
1663         *(cd->mcodeptr++) = 0xff;
1664         emit_reg(0,(reg));
1665 }
1666
1667 void emit_incq_reg(codegendata *cd, s8 reg)
1668 {
1669         emit_rex(1,0,0,(reg));
1670         *(cd->mcodeptr++) = 0xff;
1671         emit_reg(0,(reg));
1672 }
1673
1674 void emit_incl_membase(codegendata *cd, s8 basereg, s8 disp)
1675 {
1676         emit_rex(0,0,0,(basereg));
1677         *(cd->mcodeptr++) = 0xff;
1678         emit_membase(cd, (basereg),(disp),0);
1679 }
1680
1681 void emit_incq_membase(codegendata *cd, s8 basereg, s8 disp)
1682 {
1683         emit_rex(1,0,0,(basereg));
1684         *(cd->mcodeptr++) = 0xff;
1685         emit_membase(cd, (basereg),(disp),0);
1686 }
1687
1688
1689
1690 void emit_cltd(codegendata *cd) {
1691     *(cd->mcodeptr++) = 0x99;
1692 }
1693
1694
1695 void emit_cqto(codegendata *cd) {
1696         emit_rex(1,0,0,0);
1697         *(cd->mcodeptr++) = 0x99;
1698 }
1699
1700
1701
1702 void emit_imul_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
1703         emit_rex(1,(dreg),0,(reg));
1704         *(cd->mcodeptr++) = 0x0f;
1705         *(cd->mcodeptr++) = 0xaf;
1706         emit_reg((dreg),(reg));
1707 }
1708
1709
1710 void emit_imull_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
1711         emit_rex(0,(dreg),0,(reg));
1712         *(cd->mcodeptr++) = 0x0f;
1713         *(cd->mcodeptr++) = 0xaf;
1714         emit_reg((dreg),(reg));
1715 }
1716
1717
1718 void emit_imul_membase_reg(codegendata *cd, s8 basereg, s8 disp, s8 dreg) {
1719         emit_rex(1,(dreg),0,(basereg));
1720         *(cd->mcodeptr++) = 0x0f;
1721         *(cd->mcodeptr++) = 0xaf;
1722         emit_membase(cd, (basereg),(disp),(dreg));
1723 }
1724
1725
1726 void emit_imull_membase_reg(codegendata *cd, s8 basereg, s8 disp, s8 dreg) {
1727         emit_rex(0,(dreg),0,(basereg));
1728         *(cd->mcodeptr++) = 0x0f;
1729         *(cd->mcodeptr++) = 0xaf;
1730         emit_membase(cd, (basereg),(disp),(dreg));
1731 }
1732
1733
1734 void emit_imul_imm_reg(codegendata *cd, s8 imm, s8 dreg) {
1735         if (IS_IMM8((imm))) {
1736                 emit_rex(1,0,0,(dreg));
1737                 *(cd->mcodeptr++) = 0x6b;
1738                 emit_reg(0,(dreg));
1739                 emit_imm8((imm));
1740         } else {
1741                 emit_rex(1,0,0,(dreg));
1742                 *(cd->mcodeptr++) = 0x69;
1743                 emit_reg(0,(dreg));
1744                 emit_imm32((imm));
1745         }
1746 }
1747
1748
1749 void emit_imul_imm_reg_reg(codegendata *cd, s8 imm, s8 reg, s8 dreg) {
1750         if (IS_IMM8((imm))) {
1751                 emit_rex(1,(dreg),0,(reg));
1752                 *(cd->mcodeptr++) = 0x6b;
1753                 emit_reg((dreg),(reg));
1754                 emit_imm8((imm));
1755         } else {
1756                 emit_rex(1,(dreg),0,(reg));
1757                 *(cd->mcodeptr++) = 0x69;
1758                 emit_reg((dreg),(reg));
1759                 emit_imm32((imm));
1760         }
1761 }
1762
1763
1764 void emit_imull_imm_reg_reg(codegendata *cd, s8 imm, s8 reg, s8 dreg) {
1765         if (IS_IMM8((imm))) {
1766                 emit_rex(0,(dreg),0,(reg));
1767                 *(cd->mcodeptr++) = 0x6b;
1768                 emit_reg((dreg),(reg));
1769                 emit_imm8((imm));
1770         } else {
1771                 emit_rex(0,(dreg),0,(reg));
1772                 *(cd->mcodeptr++) = 0x69;
1773                 emit_reg((dreg),(reg));
1774                 emit_imm32((imm));
1775         }
1776 }
1777
1778
1779 void emit_imul_imm_membase_reg(codegendata *cd, s8 imm, s8 basereg, s8 disp, s8 dreg) {
1780         if (IS_IMM8((imm))) {
1781                 emit_rex(1,(dreg),0,(basereg));
1782                 *(cd->mcodeptr++) = 0x6b;
1783                 emit_membase(cd, (basereg),(disp),(dreg));
1784                 emit_imm8((imm));
1785         } else {
1786                 emit_rex(1,(dreg),0,(basereg));
1787                 *(cd->mcodeptr++) = 0x69;
1788                 emit_membase(cd, (basereg),(disp),(dreg));
1789                 emit_imm32((imm));
1790         }
1791 }
1792
1793
1794 void emit_imull_imm_membase_reg(codegendata *cd, s8 imm, s8 basereg, s8 disp, s8 dreg) {
1795         if (IS_IMM8((imm))) {
1796                 emit_rex(0,(dreg),0,(basereg));
1797                 *(cd->mcodeptr++) = 0x6b;
1798                 emit_membase(cd, (basereg),(disp),(dreg));
1799                 emit_imm8((imm));
1800         } else {
1801                 emit_rex(0,(dreg),0,(basereg));
1802                 *(cd->mcodeptr++) = 0x69;
1803                 emit_membase(cd, (basereg),(disp),(dreg));
1804                 emit_imm32((imm));
1805         }
1806 }
1807
1808
1809 void emit_idiv_reg(codegendata *cd, s8 reg) {
1810         emit_rex(1,0,0,(reg));
1811         *(cd->mcodeptr++) = 0xf7;
1812         emit_reg(7,(reg));
1813 }
1814
1815
1816 void emit_idivl_reg(codegendata *cd, s8 reg) {
1817         emit_rex(0,0,0,(reg));
1818         *(cd->mcodeptr++) = 0xf7;
1819         emit_reg(7,(reg));
1820 }
1821
1822
1823
1824 /*
1825  * shift ops
1826  */
1827 void emit_shift_reg(codegendata *cd, s8 opc, s8 reg) {
1828         emit_rex(1,0,0,(reg));
1829         *(cd->mcodeptr++) = 0xd3;
1830         emit_reg((opc),(reg));
1831 }
1832
1833
1834 void emit_shiftl_reg(codegendata *cd, s8 opc, s8 reg) {
1835         emit_rex(0,0,0,(reg));
1836         *(cd->mcodeptr++) = 0xd3;
1837         emit_reg((opc),(reg));
1838 }
1839
1840
1841 void emit_shift_membase(codegendata *cd, s8 opc, s8 basereg, s8 disp) {
1842         emit_rex(1,0,0,(basereg));
1843         *(cd->mcodeptr++) = 0xd3;
1844         emit_membase(cd, (basereg),(disp),(opc));
1845 }
1846
1847
1848 void emit_shiftl_membase(codegendata *cd, s8 opc, s8 basereg, s8 disp) {
1849         emit_rex(0,0,0,(basereg));
1850         *(cd->mcodeptr++) = 0xd3;
1851         emit_membase(cd, (basereg),(disp),(opc));
1852 }
1853
1854
1855 void emit_shift_imm_reg(codegendata *cd, s8 opc, s8 imm, s8 dreg) {
1856         if ((imm) == 1) {
1857                 emit_rex(1,0,0,(dreg));
1858                 *(cd->mcodeptr++) = 0xd1;
1859                 emit_reg((opc),(dreg));
1860         } else {
1861                 emit_rex(1,0,0,(dreg));
1862                 *(cd->mcodeptr++) = 0xc1;
1863                 emit_reg((opc),(dreg));
1864                 emit_imm8((imm));
1865         }
1866 }
1867
1868
1869 void emit_shiftl_imm_reg(codegendata *cd, s8 opc, s8 imm, s8 dreg) {
1870         if ((imm) == 1) {
1871                 emit_rex(0,0,0,(dreg));
1872                 *(cd->mcodeptr++) = 0xd1;
1873                 emit_reg((opc),(dreg));
1874         } else {
1875                 emit_rex(0,0,0,(dreg));
1876                 *(cd->mcodeptr++) = 0xc1;
1877                 emit_reg((opc),(dreg));
1878                 emit_imm8((imm));
1879         }
1880 }
1881
1882
1883 void emit_shift_imm_membase(codegendata *cd, s8 opc, s8 imm, s8 basereg, s8 disp) {
1884         if ((imm) == 1) {
1885                 emit_rex(1,0,0,(basereg));
1886                 *(cd->mcodeptr++) = 0xd1;
1887                 emit_membase(cd, (basereg),(disp),(opc));
1888         } else {
1889                 emit_rex(1,0,0,(basereg));
1890                 *(cd->mcodeptr++) = 0xc1;
1891                 emit_membase(cd, (basereg),(disp),(opc));
1892                 emit_imm8((imm));
1893         }
1894 }
1895
1896
1897 void emit_shiftl_imm_membase(codegendata *cd, s8 opc, s8 imm, s8 basereg, s8 disp) {
1898         if ((imm) == 1) {
1899                 emit_rex(0,0,0,(basereg));
1900                 *(cd->mcodeptr++) = 0xd1;
1901                 emit_membase(cd, (basereg),(disp),(opc));
1902         } else {
1903                 emit_rex(0,0,0,(basereg));
1904                 *(cd->mcodeptr++) = 0xc1;
1905                 emit_membase(cd, (basereg),(disp),(opc));
1906                 emit_imm8((imm));
1907         }
1908 }
1909
1910
1911
1912 /*
1913  * jump operations
1914  */
1915 void emit_jmp_imm(codegendata *cd, s8 imm) {
1916         *(cd->mcodeptr++) = 0xe9;
1917         emit_imm32((imm));
1918 }
1919
1920 /* like emit_jmp_imm but allows 8 bit optimization */
1921 void emit_jmp_imm2(codegendata *cd, s8 imm) {
1922         if (IS_IMM8(imm)) {
1923                 *(cd->mcodeptr++) = 0xeb;
1924                 emit_imm8((imm));
1925         }
1926         else {
1927                 *(cd->mcodeptr++) = 0xe9;
1928                 emit_imm32((imm));
1929         }
1930 }
1931
1932
1933 void emit_jmp_reg(codegendata *cd, s8 reg) {
1934         emit_rex(0,0,0,(reg));
1935         *(cd->mcodeptr++) = 0xff;
1936         emit_reg(4,(reg));
1937 }
1938
1939
1940 void emit_jcc(codegendata *cd, s8 opc, s8 imm) {
1941         *(cd->mcodeptr++) = 0x0f;
1942         *(cd->mcodeptr++) = (0x80 + (opc));
1943         emit_imm32((imm));
1944 }
1945
1946
1947
1948 /*
1949  * conditional set and move operations
1950  */
1951
1952 /* we need the rex byte to get all low bytes */
1953 void emit_setcc_reg(codegendata *cd, s4 opc, s4 reg)
1954 {
1955         *(cd->mcodeptr++) = (0x40 | (((reg) >> 3) & 0x01));
1956         *(cd->mcodeptr++) = 0x0f;
1957         *(cd->mcodeptr++) = (0x90 + (opc));
1958         emit_reg(0,(reg));
1959 }
1960
1961
1962 /* we need the rex byte to get all low bytes */
1963 void emit_setcc_membase(codegendata *cd, s4 opc, s4 basereg, s4 disp)
1964 {
1965         *(cd->mcodeptr++) = (0x40 | (((basereg) >> 3) & 0x01));
1966         *(cd->mcodeptr++) = 0x0f;
1967         *(cd->mcodeptr++) = (0x90 + (opc));
1968         emit_membase(cd, (basereg),(disp),0);
1969 }
1970
1971
1972 void emit_cmovcc_reg_reg(codegendata *cd, s4 opc, s4 reg, s4 dreg)
1973 {
1974         emit_rex(1,(dreg),0,(reg));
1975         *(cd->mcodeptr++) = 0x0f;
1976         *(cd->mcodeptr++) = (0x40 + (opc));
1977         emit_reg((dreg),(reg));
1978 }
1979
1980
1981 void emit_cmovccl_reg_reg(codegendata *cd, s4 opc, s4 reg, s4 dreg)
1982 {
1983         emit_rex(0,(dreg),0,(reg));
1984         *(cd->mcodeptr++) = 0x0f;
1985         *(cd->mcodeptr++) = (0x40 + (opc));
1986         emit_reg((dreg),(reg));
1987 }
1988
1989
1990 void emit_neg_reg(codegendata *cd, s8 reg)
1991 {
1992         emit_rex(1,0,0,(reg));
1993         *(cd->mcodeptr++) = 0xf7;
1994         emit_reg(3,(reg));
1995 }
1996
1997
1998 void emit_negl_reg(codegendata *cd, s8 reg)
1999 {
2000         emit_rex(0,0,0,(reg));
2001         *(cd->mcodeptr++) = 0xf7;
2002         emit_reg(3,(reg));
2003 }
2004
2005
2006 void emit_push_reg(codegendata *cd, s8 reg) {
2007         emit_rex(0,0,0,(reg));
2008         *(cd->mcodeptr++) = 0x50 + (0x07 & (reg));
2009 }
2010
2011
2012 void emit_push_imm(codegendata *cd, s8 imm) {
2013         *(cd->mcodeptr++) = 0x68;
2014         emit_imm32((imm));
2015 }
2016
2017
2018 void emit_pop_reg(codegendata *cd, s8 reg) {
2019         emit_rex(0,0,0,(reg));
2020         *(cd->mcodeptr++) = 0x58 + (0x07 & (reg));
2021 }
2022
2023
2024 void emit_xchg_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
2025         emit_rex(1,(reg),0,(dreg));
2026         *(cd->mcodeptr++) = 0x87;
2027         emit_reg((reg),(dreg));
2028 }
2029
2030
2031
2032 /*
2033  * call instructions
2034  */
2035 void emit_call_reg(codegendata *cd, s8 reg)
2036 {
2037         emit_rex(0,0,0,(reg));
2038         *(cd->mcodeptr++) = 0xff;
2039         emit_reg(2,(reg));
2040 }
2041
2042
2043 void emit_call_imm(codegendata *cd, s8 imm)
2044 {
2045         *(cd->mcodeptr++) = 0xe8;
2046         emit_imm32((imm));
2047 }
2048
2049
2050 void emit_call_mem(codegendata *cd, ptrint mem)
2051 {
2052         *(cd->mcodeptr++) = 0xff;
2053         emit_mem(2,(mem));
2054 }
2055
2056
2057
2058 /*
2059  * floating point instructions (SSE2)
2060  */
2061 void emit_addsd_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
2062         *(cd->mcodeptr++) = 0xf2;
2063         emit_rex(0,(dreg),0,(reg));
2064         *(cd->mcodeptr++) = 0x0f;
2065         *(cd->mcodeptr++) = 0x58;
2066         emit_reg((dreg),(reg));
2067 }
2068
2069
2070 void emit_addss_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
2071         *(cd->mcodeptr++) = 0xf3;
2072         emit_rex(0,(dreg),0,(reg));
2073         *(cd->mcodeptr++) = 0x0f;
2074         *(cd->mcodeptr++) = 0x58;
2075         emit_reg((dreg),(reg));
2076 }
2077
2078
2079 void emit_cvtsi2ssq_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
2080         *(cd->mcodeptr++) = 0xf3;
2081         emit_rex(1,(dreg),0,(reg));
2082         *(cd->mcodeptr++) = 0x0f;
2083         *(cd->mcodeptr++) = 0x2a;
2084         emit_reg((dreg),(reg));
2085 }
2086
2087
2088 void emit_cvtsi2ss_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
2089         *(cd->mcodeptr++) = 0xf3;
2090         emit_rex(0,(dreg),0,(reg));
2091         *(cd->mcodeptr++) = 0x0f;
2092         *(cd->mcodeptr++) = 0x2a;
2093         emit_reg((dreg),(reg));
2094 }
2095
2096
2097 void emit_cvtsi2sdq_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
2098         *(cd->mcodeptr++) = 0xf2;
2099         emit_rex(1,(dreg),0,(reg));
2100         *(cd->mcodeptr++) = 0x0f;
2101         *(cd->mcodeptr++) = 0x2a;
2102         emit_reg((dreg),(reg));
2103 }
2104
2105
2106 void emit_cvtsi2sd_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
2107         *(cd->mcodeptr++) = 0xf2;
2108         emit_rex(0,(dreg),0,(reg));
2109         *(cd->mcodeptr++) = 0x0f;
2110         *(cd->mcodeptr++) = 0x2a;
2111         emit_reg((dreg),(reg));
2112 }
2113
2114
2115 void emit_cvtss2sd_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
2116         *(cd->mcodeptr++) = 0xf3;
2117         emit_rex(0,(dreg),0,(reg));
2118         *(cd->mcodeptr++) = 0x0f;
2119         *(cd->mcodeptr++) = 0x5a;
2120         emit_reg((dreg),(reg));
2121 }
2122
2123
2124 void emit_cvtsd2ss_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
2125         *(cd->mcodeptr++) = 0xf2;
2126         emit_rex(0,(dreg),0,(reg));
2127         *(cd->mcodeptr++) = 0x0f;
2128         *(cd->mcodeptr++) = 0x5a;
2129         emit_reg((dreg),(reg));
2130 }
2131
2132
2133 void emit_cvttss2siq_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
2134         *(cd->mcodeptr++) = 0xf3;
2135         emit_rex(1,(dreg),0,(reg));
2136         *(cd->mcodeptr++) = 0x0f;
2137         *(cd->mcodeptr++) = 0x2c;
2138         emit_reg((dreg),(reg));
2139 }
2140
2141
2142 void emit_cvttss2si_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
2143         *(cd->mcodeptr++) = 0xf3;
2144         emit_rex(0,(dreg),0,(reg));
2145         *(cd->mcodeptr++) = 0x0f;
2146         *(cd->mcodeptr++) = 0x2c;
2147         emit_reg((dreg),(reg));
2148 }
2149
2150
2151 void emit_cvttsd2siq_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
2152         *(cd->mcodeptr++) = 0xf2;
2153         emit_rex(1,(dreg),0,(reg));
2154         *(cd->mcodeptr++) = 0x0f;
2155         *(cd->mcodeptr++) = 0x2c;
2156         emit_reg((dreg),(reg));
2157 }
2158
2159
2160 void emit_cvttsd2si_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
2161         *(cd->mcodeptr++) = 0xf2;
2162         emit_rex(0,(dreg),0,(reg));
2163         *(cd->mcodeptr++) = 0x0f;
2164         *(cd->mcodeptr++) = 0x2c;
2165         emit_reg((dreg),(reg));
2166 }
2167
2168
2169 void emit_divss_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
2170         *(cd->mcodeptr++) = 0xf3;
2171         emit_rex(0,(dreg),0,(reg));
2172         *(cd->mcodeptr++) = 0x0f;
2173         *(cd->mcodeptr++) = 0x5e;
2174         emit_reg((dreg),(reg));
2175 }
2176
2177
2178 void emit_divsd_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
2179         *(cd->mcodeptr++) = 0xf2;
2180         emit_rex(0,(dreg),0,(reg));
2181         *(cd->mcodeptr++) = 0x0f;
2182         *(cd->mcodeptr++) = 0x5e;
2183         emit_reg((dreg),(reg));
2184 }
2185
2186
2187 void emit_movd_reg_freg(codegendata *cd, s8 reg, s8 freg) {
2188         *(cd->mcodeptr++) = 0x66;
2189         emit_rex(1,(freg),0,(reg));
2190         *(cd->mcodeptr++) = 0x0f;
2191         *(cd->mcodeptr++) = 0x6e;
2192         emit_reg((freg),(reg));
2193 }
2194
2195
2196 void emit_movd_freg_reg(codegendata *cd, s8 freg, s8 reg) {
2197         *(cd->mcodeptr++) = 0x66;
2198         emit_rex(1,(freg),0,(reg));
2199         *(cd->mcodeptr++) = 0x0f;
2200         *(cd->mcodeptr++) = 0x7e;
2201         emit_reg((freg),(reg));
2202 }
2203
2204
2205 void emit_movd_reg_membase(codegendata *cd, s8 reg, s8 basereg, s8 disp) {
2206         *(cd->mcodeptr++) = 0x66;
2207         emit_rex(0,(reg),0,(basereg));
2208         *(cd->mcodeptr++) = 0x0f;
2209         *(cd->mcodeptr++) = 0x7e;
2210         emit_membase(cd, (basereg),(disp),(reg));
2211 }
2212
2213
2214 void emit_movd_reg_memindex(codegendata *cd, s8 reg, s8 disp, s8 basereg, s8 indexreg, s8 scale) {
2215         *(cd->mcodeptr++) = 0x66;
2216         emit_rex(0,(reg),(indexreg),(basereg));
2217         *(cd->mcodeptr++) = 0x0f;
2218         *(cd->mcodeptr++) = 0x7e;
2219         emit_memindex(cd, (reg),(disp),(basereg),(indexreg),(scale));
2220 }
2221
2222
2223 void emit_movd_membase_reg(codegendata *cd, s8 basereg, s8 disp, s8 dreg) {
2224         *(cd->mcodeptr++) = 0x66;
2225         emit_rex(1,(dreg),0,(basereg));
2226         *(cd->mcodeptr++) = 0x0f;
2227         *(cd->mcodeptr++) = 0x6e;
2228         emit_membase(cd, (basereg),(disp),(dreg));
2229 }
2230
2231
2232 void emit_movdl_membase_reg(codegendata *cd, s8 basereg, s8 disp, s8 dreg) {
2233         *(cd->mcodeptr++) = 0x66;
2234         emit_rex(0,(dreg),0,(basereg));
2235         *(cd->mcodeptr++) = 0x0f;
2236         *(cd->mcodeptr++) = 0x6e;
2237         emit_membase(cd, (basereg),(disp),(dreg));
2238 }
2239
2240
2241 void emit_movd_memindex_reg(codegendata *cd, s8 disp, s8 basereg, s8 indexreg, s8 scale, s8 dreg) {
2242         *(cd->mcodeptr++) = 0x66;
2243         emit_rex(0,(dreg),(indexreg),(basereg));
2244         *(cd->mcodeptr++) = 0x0f;
2245         *(cd->mcodeptr++) = 0x6e;
2246         emit_memindex(cd, (dreg),(disp),(basereg),(indexreg),(scale));
2247 }
2248
2249
2250 void emit_movq_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
2251         *(cd->mcodeptr++) = 0xf3;
2252         emit_rex(0,(dreg),0,(reg));
2253         *(cd->mcodeptr++) = 0x0f;
2254         *(cd->mcodeptr++) = 0x7e;
2255         emit_reg((dreg),(reg));
2256 }
2257
2258
2259 void emit_movq_reg_membase(codegendata *cd, s8 reg, s8 basereg, s8 disp) {
2260         *(cd->mcodeptr++) = 0x66;
2261         emit_rex(0,(reg),0,(basereg));
2262         *(cd->mcodeptr++) = 0x0f;
2263         *(cd->mcodeptr++) = 0xd6;
2264         emit_membase(cd, (basereg),(disp),(reg));
2265 }
2266
2267
2268 void emit_movq_membase_reg(codegendata *cd, s8 basereg, s8 disp, s8 dreg) {
2269         *(cd->mcodeptr++) = 0xf3;
2270         emit_rex(0,(dreg),0,(basereg));
2271         *(cd->mcodeptr++) = 0x0f;
2272         *(cd->mcodeptr++) = 0x7e;
2273         emit_membase(cd, (basereg),(disp),(dreg));
2274 }
2275
2276
2277 void emit_movss_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
2278         *(cd->mcodeptr++) = 0xf3;
2279         emit_rex(0,(reg),0,(dreg));
2280         *(cd->mcodeptr++) = 0x0f;
2281         *(cd->mcodeptr++) = 0x10;
2282         emit_reg((reg),(dreg));
2283 }
2284
2285
2286 void emit_movsd_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
2287         *(cd->mcodeptr++) = 0xf2;
2288         emit_rex(0,(reg),0,(dreg));
2289         *(cd->mcodeptr++) = 0x0f;
2290         *(cd->mcodeptr++) = 0x10;
2291         emit_reg((reg),(dreg));
2292 }
2293
2294
2295 void emit_movss_reg_membase(codegendata *cd, s8 reg, s8 basereg, s8 disp) {
2296         *(cd->mcodeptr++) = 0xf3;
2297         emit_rex(0,(reg),0,(basereg));
2298         *(cd->mcodeptr++) = 0x0f;
2299         *(cd->mcodeptr++) = 0x11;
2300         emit_membase(cd, (basereg),(disp),(reg));
2301 }
2302
2303
2304 /* Always emit a REX byte, because the instruction size can be smaller when   */
2305 /* all register indexes are smaller than 7.                                   */
2306 void emit_movss_reg_membase32(codegendata *cd, s8 reg, s8 basereg, s8 disp) {
2307         *(cd->mcodeptr++) = 0xf3;
2308         emit_byte_rex((reg),0,(basereg));
2309         *(cd->mcodeptr++) = 0x0f;
2310         *(cd->mcodeptr++) = 0x11;
2311         emit_membase32(cd, (basereg),(disp),(reg));
2312 }
2313
2314
2315 void emit_movsd_reg_membase(codegendata *cd, s8 reg, s8 basereg, s8 disp) {
2316         *(cd->mcodeptr++) = 0xf2;
2317         emit_rex(0,(reg),0,(basereg));
2318         *(cd->mcodeptr++) = 0x0f;
2319         *(cd->mcodeptr++) = 0x11;
2320         emit_membase(cd, (basereg),(disp),(reg));
2321 }
2322
2323
2324 /* Always emit a REX byte, because the instruction size can be smaller when   */
2325 /* all register indexes are smaller than 7.                                   */
2326 void emit_movsd_reg_membase32(codegendata *cd, s8 reg, s8 basereg, s8 disp) {
2327         *(cd->mcodeptr++) = 0xf2;
2328         emit_byte_rex((reg),0,(basereg));
2329         *(cd->mcodeptr++) = 0x0f;
2330         *(cd->mcodeptr++) = 0x11;
2331         emit_membase32(cd, (basereg),(disp),(reg));
2332 }
2333
2334
2335 void emit_movss_membase_reg(codegendata *cd, s8 basereg, s8 disp, s8 dreg) {
2336         *(cd->mcodeptr++) = 0xf3;
2337         emit_rex(0,(dreg),0,(basereg));
2338         *(cd->mcodeptr++) = 0x0f;
2339         *(cd->mcodeptr++) = 0x10;
2340         emit_membase(cd, (basereg),(disp),(dreg));
2341 }
2342
2343
2344 /* Always emit a REX byte, because the instruction size can be smaller when   */
2345 /* all register indexes are smaller than 7.                                   */
2346 void emit_movss_membase32_reg(codegendata *cd, s8 basereg, s8 disp, s8 dreg) {
2347         *(cd->mcodeptr++) = 0xf3;
2348         emit_byte_rex((dreg),0,(basereg));
2349         *(cd->mcodeptr++) = 0x0f;
2350         *(cd->mcodeptr++) = 0x10;
2351         emit_membase32(cd, (basereg),(disp),(dreg));
2352 }
2353
2354
2355 void emit_movlps_membase_reg(codegendata *cd, s8 basereg, s8 disp, s8 dreg)
2356 {
2357         emit_rex(0,(dreg),0,(basereg));
2358         *(cd->mcodeptr++) = 0x0f;
2359         *(cd->mcodeptr++) = 0x12;
2360         emit_membase(cd, (basereg),(disp),(dreg));
2361 }
2362
2363
2364 void emit_movlps_reg_membase(codegendata *cd, s8 reg, s8 basereg, s8 disp)
2365 {
2366         emit_rex(0,(reg),0,(basereg));
2367         *(cd->mcodeptr++) = 0x0f;
2368         *(cd->mcodeptr++) = 0x13;
2369         emit_membase(cd, (basereg),(disp),(reg));
2370 }
2371
2372
2373 void emit_movsd_membase_reg(codegendata *cd, s8 basereg, s8 disp, s8 dreg) {
2374         *(cd->mcodeptr++) = 0xf2;
2375         emit_rex(0,(dreg),0,(basereg));
2376         *(cd->mcodeptr++) = 0x0f;
2377         *(cd->mcodeptr++) = 0x10;
2378         emit_membase(cd, (basereg),(disp),(dreg));
2379 }
2380
2381
2382 /* Always emit a REX byte, because the instruction size can be smaller when   */
2383 /* all register indexes are smaller than 7.                                   */
2384 void emit_movsd_membase32_reg(codegendata *cd, s8 basereg, s8 disp, s8 dreg) {
2385         *(cd->mcodeptr++) = 0xf2;
2386         emit_byte_rex((dreg),0,(basereg));
2387         *(cd->mcodeptr++) = 0x0f;
2388         *(cd->mcodeptr++) = 0x10;
2389         emit_membase32(cd, (basereg),(disp),(dreg));
2390 }
2391
2392
2393 void emit_movlpd_membase_reg(codegendata *cd, s8 basereg, s8 disp, s8 dreg)
2394 {
2395         *(cd->mcodeptr++) = 0x66;
2396         emit_rex(0,(dreg),0,(basereg));
2397         *(cd->mcodeptr++) = 0x0f;
2398         *(cd->mcodeptr++) = 0x12;
2399         emit_membase(cd, (basereg),(disp),(dreg));
2400 }
2401
2402
2403 void emit_movlpd_reg_membase(codegendata *cd, s8 reg, s8 basereg, s8 disp)
2404 {
2405         *(cd->mcodeptr++) = 0x66;
2406         emit_rex(0,(reg),0,(basereg));
2407         *(cd->mcodeptr++) = 0x0f;
2408         *(cd->mcodeptr++) = 0x13;
2409         emit_membase(cd, (basereg),(disp),(reg));
2410 }
2411
2412
2413 void emit_movss_reg_memindex(codegendata *cd, s8 reg, s8 disp, s8 basereg, s8 indexreg, s8 scale) {
2414         *(cd->mcodeptr++) = 0xf3;
2415         emit_rex(0,(reg),(indexreg),(basereg));
2416         *(cd->mcodeptr++) = 0x0f;
2417         *(cd->mcodeptr++) = 0x11;
2418         emit_memindex(cd, (reg),(disp),(basereg),(indexreg),(scale));
2419 }
2420
2421
2422 void emit_movsd_reg_memindex(codegendata *cd, s8 reg, s8 disp, s8 basereg, s8 indexreg, s8 scale) {
2423         *(cd->mcodeptr++) = 0xf2;
2424         emit_rex(0,(reg),(indexreg),(basereg));
2425         *(cd->mcodeptr++) = 0x0f;
2426         *(cd->mcodeptr++) = 0x11;
2427         emit_memindex(cd, (reg),(disp),(basereg),(indexreg),(scale));
2428 }
2429
2430
2431 void emit_movss_memindex_reg(codegendata *cd, s8 disp, s8 basereg, s8 indexreg, s8 scale, s8 dreg) {
2432         *(cd->mcodeptr++) = 0xf3;
2433         emit_rex(0,(dreg),(indexreg),(basereg));
2434         *(cd->mcodeptr++) = 0x0f;
2435         *(cd->mcodeptr++) = 0x10;
2436         emit_memindex(cd, (dreg),(disp),(basereg),(indexreg),(scale));
2437 }
2438
2439
2440 void emit_movsd_memindex_reg(codegendata *cd, s8 disp, s8 basereg, s8 indexreg, s8 scale, s8 dreg) {
2441         *(cd->mcodeptr++) = 0xf2;
2442         emit_rex(0,(dreg),(indexreg),(basereg));
2443         *(cd->mcodeptr++) = 0x0f;
2444         *(cd->mcodeptr++) = 0x10;
2445         emit_memindex(cd, (dreg),(disp),(basereg),(indexreg),(scale));
2446 }
2447
2448
2449 void emit_mulss_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
2450         *(cd->mcodeptr++) = 0xf3;
2451         emit_rex(0,(dreg),0,(reg));
2452         *(cd->mcodeptr++) = 0x0f;
2453         *(cd->mcodeptr++) = 0x59;
2454         emit_reg((dreg),(reg));
2455 }
2456
2457
2458 void emit_mulsd_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
2459         *(cd->mcodeptr++) = 0xf2;
2460         emit_rex(0,(dreg),0,(reg));
2461         *(cd->mcodeptr++) = 0x0f;
2462         *(cd->mcodeptr++) = 0x59;
2463         emit_reg((dreg),(reg));
2464 }
2465
2466
2467 void emit_subss_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
2468         *(cd->mcodeptr++) = 0xf3;
2469         emit_rex(0,(dreg),0,(reg));
2470         *(cd->mcodeptr++) = 0x0f;
2471         *(cd->mcodeptr++) = 0x5c;
2472         emit_reg((dreg),(reg));
2473 }
2474
2475
2476 void emit_subsd_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
2477         *(cd->mcodeptr++) = 0xf2;
2478         emit_rex(0,(dreg),0,(reg));
2479         *(cd->mcodeptr++) = 0x0f;
2480         *(cd->mcodeptr++) = 0x5c;
2481         emit_reg((dreg),(reg));
2482 }
2483
2484
2485 void emit_ucomiss_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
2486         emit_rex(0,(dreg),0,(reg));
2487         *(cd->mcodeptr++) = 0x0f;
2488         *(cd->mcodeptr++) = 0x2e;
2489         emit_reg((dreg),(reg));
2490 }
2491
2492
2493 void emit_ucomisd_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
2494         *(cd->mcodeptr++) = 0x66;
2495         emit_rex(0,(dreg),0,(reg));
2496         *(cd->mcodeptr++) = 0x0f;
2497         *(cd->mcodeptr++) = 0x2e;
2498         emit_reg((dreg),(reg));
2499 }
2500
2501
2502 void emit_xorps_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
2503         emit_rex(0,(dreg),0,(reg));
2504         *(cd->mcodeptr++) = 0x0f;
2505         *(cd->mcodeptr++) = 0x57;
2506         emit_reg((dreg),(reg));
2507 }
2508
2509
2510 void emit_xorps_membase_reg(codegendata *cd, s8 basereg, s8 disp, s8 dreg) {
2511         emit_rex(0,(dreg),0,(basereg));
2512         *(cd->mcodeptr++) = 0x0f;
2513         *(cd->mcodeptr++) = 0x57;
2514         emit_membase(cd, (basereg),(disp),(dreg));
2515 }
2516
2517
2518 void emit_xorpd_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
2519         *(cd->mcodeptr++) = 0x66;
2520         emit_rex(0,(dreg),0,(reg));
2521         *(cd->mcodeptr++) = 0x0f;
2522         *(cd->mcodeptr++) = 0x57;
2523         emit_reg((dreg),(reg));
2524 }
2525
2526
2527 void emit_xorpd_membase_reg(codegendata *cd, s8 basereg, s8 disp, s8 dreg) {
2528         *(cd->mcodeptr++) = 0x66;
2529         emit_rex(0,(dreg),0,(basereg));
2530         *(cd->mcodeptr++) = 0x0f;
2531         *(cd->mcodeptr++) = 0x57;
2532         emit_membase(cd, (basereg),(disp),(dreg));
2533 }
2534
2535
2536 /* system instructions ********************************************************/
2537
2538 void emit_rdtsc(codegendata *cd)
2539 {
2540         *(cd->mcodeptr++) = 0x0f;
2541         *(cd->mcodeptr++) = 0x31;
2542 }
2543
2544
2545 /*
2546  * These are local overrides for various environment variables in Emacs.
2547  * Please do not remove this and leave it at the end of the file, where
2548  * Emacs will automagically detect them.
2549  * ---------------------------------------------------------------------
2550  * Local variables:
2551  * mode: c
2552  * indent-tabs-mode: t
2553  * c-basic-offset: 4
2554  * tab-width: 4
2555  * End:
2556  */