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