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