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