Merged comment cleanup (forgot this before).
[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
1405 void emit_test_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
1406         emit_rex(1,(reg),0,(dreg));
1407         *(cd->mcodeptr++) = 0x85;
1408         emit_reg((reg),(dreg));
1409 }
1410
1411
1412 void emit_testl_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
1413         emit_rex(0,(reg),0,(dreg));
1414         *(cd->mcodeptr++) = 0x85;
1415         emit_reg((reg),(dreg));
1416 }
1417
1418
1419 void emit_test_imm_reg(codegendata *cd, s8 imm, s8 reg) {
1420         *(cd->mcodeptr++) = 0xf7;
1421         emit_reg(0,(reg));
1422         emit_imm32((imm));
1423 }
1424
1425
1426 void emit_testw_imm_reg(codegendata *cd, s8 imm, s8 reg) {
1427         *(cd->mcodeptr++) = 0x66;
1428         *(cd->mcodeptr++) = 0xf7;
1429         emit_reg(0,(reg));
1430         emit_imm16((imm));
1431 }
1432
1433
1434 void emit_testb_imm_reg(codegendata *cd, s8 imm, s8 reg) {
1435         *(cd->mcodeptr++) = 0xf6;
1436         emit_reg(0,(reg));
1437         emit_imm8((imm));
1438 }
1439
1440
1441 void emit_lea_membase_reg(codegendata *cd, s8 basereg, s8 disp, s8 reg) {
1442         emit_rex(1,(reg),0,(basereg));
1443         *(cd->mcodeptr++) = 0x8d;
1444         emit_membase(cd, (basereg),(disp),(reg));
1445 }
1446
1447
1448 void emit_leal_membase_reg(codegendata *cd, s8 basereg, s8 disp, s8 reg) {
1449         emit_rex(0,(reg),0,(basereg));
1450         *(cd->mcodeptr++) = 0x8d;
1451         emit_membase(cd, (basereg),(disp),(reg));
1452 }
1453
1454
1455 void emit_incl_reg(codegendata *cd, s8 reg)
1456 {
1457         *(cd->mcodeptr++) = 0xff;
1458         emit_reg(0,(reg));
1459 }
1460
1461 void emit_incq_reg(codegendata *cd, s8 reg)
1462 {
1463         emit_rex(1,0,0,(reg));
1464         *(cd->mcodeptr++) = 0xff;
1465         emit_reg(0,(reg));
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 void emit_incq_membase(codegendata *cd, s8 basereg, s8 disp)
1476 {
1477         emit_rex(1,0,0,(basereg));
1478         *(cd->mcodeptr++) = 0xff;
1479         emit_membase(cd, (basereg),(disp),0);
1480 }
1481
1482
1483
1484 void emit_cltd(codegendata *cd) {
1485     *(cd->mcodeptr++) = 0x99;
1486 }
1487
1488
1489 void emit_cqto(codegendata *cd) {
1490         emit_rex(1,0,0,0);
1491         *(cd->mcodeptr++) = 0x99;
1492 }
1493
1494
1495
1496 void emit_imul_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
1497         emit_rex(1,(dreg),0,(reg));
1498         *(cd->mcodeptr++) = 0x0f;
1499         *(cd->mcodeptr++) = 0xaf;
1500         emit_reg((dreg),(reg));
1501 }
1502
1503
1504 void emit_imull_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
1505         emit_rex(0,(dreg),0,(reg));
1506         *(cd->mcodeptr++) = 0x0f;
1507         *(cd->mcodeptr++) = 0xaf;
1508         emit_reg((dreg),(reg));
1509 }
1510
1511
1512 void emit_imul_membase_reg(codegendata *cd, s8 basereg, s8 disp, s8 dreg) {
1513         emit_rex(1,(dreg),0,(basereg));
1514         *(cd->mcodeptr++) = 0x0f;
1515         *(cd->mcodeptr++) = 0xaf;
1516         emit_membase(cd, (basereg),(disp),(dreg));
1517 }
1518
1519
1520 void emit_imull_membase_reg(codegendata *cd, s8 basereg, s8 disp, s8 dreg) {
1521         emit_rex(0,(dreg),0,(basereg));
1522         *(cd->mcodeptr++) = 0x0f;
1523         *(cd->mcodeptr++) = 0xaf;
1524         emit_membase(cd, (basereg),(disp),(dreg));
1525 }
1526
1527
1528 void emit_imul_imm_reg(codegendata *cd, s8 imm, s8 dreg) {
1529         if (IS_IMM8((imm))) {
1530                 emit_rex(1,0,0,(dreg));
1531                 *(cd->mcodeptr++) = 0x6b;
1532                 emit_reg(0,(dreg));
1533                 emit_imm8((imm));
1534         } else {
1535                 emit_rex(1,0,0,(dreg));
1536                 *(cd->mcodeptr++) = 0x69;
1537                 emit_reg(0,(dreg));
1538                 emit_imm32((imm));
1539         }
1540 }
1541
1542
1543 void emit_imul_imm_reg_reg(codegendata *cd, s8 imm, s8 reg, s8 dreg) {
1544         if (IS_IMM8((imm))) {
1545                 emit_rex(1,(dreg),0,(reg));
1546                 *(cd->mcodeptr++) = 0x6b;
1547                 emit_reg((dreg),(reg));
1548                 emit_imm8((imm));
1549         } else {
1550                 emit_rex(1,(dreg),0,(reg));
1551                 *(cd->mcodeptr++) = 0x69;
1552                 emit_reg((dreg),(reg));
1553                 emit_imm32((imm));
1554         }
1555 }
1556
1557
1558 void emit_imull_imm_reg_reg(codegendata *cd, s8 imm, s8 reg, s8 dreg) {
1559         if (IS_IMM8((imm))) {
1560                 emit_rex(0,(dreg),0,(reg));
1561                 *(cd->mcodeptr++) = 0x6b;
1562                 emit_reg((dreg),(reg));
1563                 emit_imm8((imm));
1564         } else {
1565                 emit_rex(0,(dreg),0,(reg));
1566                 *(cd->mcodeptr++) = 0x69;
1567                 emit_reg((dreg),(reg));
1568                 emit_imm32((imm));
1569         }
1570 }
1571
1572
1573 void emit_imul_imm_membase_reg(codegendata *cd, s8 imm, s8 basereg, s8 disp, s8 dreg) {
1574         if (IS_IMM8((imm))) {
1575                 emit_rex(1,(dreg),0,(basereg));
1576                 *(cd->mcodeptr++) = 0x6b;
1577                 emit_membase(cd, (basereg),(disp),(dreg));
1578                 emit_imm8((imm));
1579         } else {
1580                 emit_rex(1,(dreg),0,(basereg));
1581                 *(cd->mcodeptr++) = 0x69;
1582                 emit_membase(cd, (basereg),(disp),(dreg));
1583                 emit_imm32((imm));
1584         }
1585 }
1586
1587
1588 void emit_imull_imm_membase_reg(codegendata *cd, s8 imm, s8 basereg, s8 disp, s8 dreg) {
1589         if (IS_IMM8((imm))) {
1590                 emit_rex(0,(dreg),0,(basereg));
1591                 *(cd->mcodeptr++) = 0x6b;
1592                 emit_membase(cd, (basereg),(disp),(dreg));
1593                 emit_imm8((imm));
1594         } else {
1595                 emit_rex(0,(dreg),0,(basereg));
1596                 *(cd->mcodeptr++) = 0x69;
1597                 emit_membase(cd, (basereg),(disp),(dreg));
1598                 emit_imm32((imm));
1599         }
1600 }
1601
1602
1603 void emit_idiv_reg(codegendata *cd, s8 reg) {
1604         emit_rex(1,0,0,(reg));
1605         *(cd->mcodeptr++) = 0xf7;
1606         emit_reg(7,(reg));
1607 }
1608
1609
1610 void emit_idivl_reg(codegendata *cd, s8 reg) {
1611         emit_rex(0,0,0,(reg));
1612         *(cd->mcodeptr++) = 0xf7;
1613         emit_reg(7,(reg));
1614 }
1615
1616
1617
1618 /*
1619  * shift ops
1620  */
1621 void emit_shift_reg(codegendata *cd, s8 opc, s8 reg) {
1622         emit_rex(1,0,0,(reg));
1623         *(cd->mcodeptr++) = 0xd3;
1624         emit_reg((opc),(reg));
1625 }
1626
1627
1628 void emit_shiftl_reg(codegendata *cd, s8 opc, s8 reg) {
1629         emit_rex(0,0,0,(reg));
1630         *(cd->mcodeptr++) = 0xd3;
1631         emit_reg((opc),(reg));
1632 }
1633
1634
1635 void emit_shift_membase(codegendata *cd, s8 opc, s8 basereg, s8 disp) {
1636         emit_rex(1,0,0,(basereg));
1637         *(cd->mcodeptr++) = 0xd3;
1638         emit_membase(cd, (basereg),(disp),(opc));
1639 }
1640
1641
1642 void emit_shiftl_membase(codegendata *cd, s8 opc, s8 basereg, s8 disp) {
1643         emit_rex(0,0,0,(basereg));
1644         *(cd->mcodeptr++) = 0xd3;
1645         emit_membase(cd, (basereg),(disp),(opc));
1646 }
1647
1648
1649 void emit_shift_imm_reg(codegendata *cd, s8 opc, s8 imm, s8 dreg) {
1650         if ((imm) == 1) {
1651                 emit_rex(1,0,0,(dreg));
1652                 *(cd->mcodeptr++) = 0xd1;
1653                 emit_reg((opc),(dreg));
1654         } else {
1655                 emit_rex(1,0,0,(dreg));
1656                 *(cd->mcodeptr++) = 0xc1;
1657                 emit_reg((opc),(dreg));
1658                 emit_imm8((imm));
1659         }
1660 }
1661
1662
1663 void emit_shiftl_imm_reg(codegendata *cd, s8 opc, s8 imm, s8 dreg) {
1664         if ((imm) == 1) {
1665                 emit_rex(0,0,0,(dreg));
1666                 *(cd->mcodeptr++) = 0xd1;
1667                 emit_reg((opc),(dreg));
1668         } else {
1669                 emit_rex(0,0,0,(dreg));
1670                 *(cd->mcodeptr++) = 0xc1;
1671                 emit_reg((opc),(dreg));
1672                 emit_imm8((imm));
1673         }
1674 }
1675
1676
1677 void emit_shift_imm_membase(codegendata *cd, s8 opc, s8 imm, s8 basereg, s8 disp) {
1678         if ((imm) == 1) {
1679                 emit_rex(1,0,0,(basereg));
1680                 *(cd->mcodeptr++) = 0xd1;
1681                 emit_membase(cd, (basereg),(disp),(opc));
1682         } else {
1683                 emit_rex(1,0,0,(basereg));
1684                 *(cd->mcodeptr++) = 0xc1;
1685                 emit_membase(cd, (basereg),(disp),(opc));
1686                 emit_imm8((imm));
1687         }
1688 }
1689
1690
1691 void emit_shiftl_imm_membase(codegendata *cd, s8 opc, s8 imm, s8 basereg, s8 disp) {
1692         if ((imm) == 1) {
1693                 emit_rex(0,0,0,(basereg));
1694                 *(cd->mcodeptr++) = 0xd1;
1695                 emit_membase(cd, (basereg),(disp),(opc));
1696         } else {
1697                 emit_rex(0,0,0,(basereg));
1698                 *(cd->mcodeptr++) = 0xc1;
1699                 emit_membase(cd, (basereg),(disp),(opc));
1700                 emit_imm8((imm));
1701         }
1702 }
1703
1704
1705
1706 /*
1707  * jump operations
1708  */
1709 void emit_jmp_imm(codegendata *cd, s8 imm) {
1710         *(cd->mcodeptr++) = 0xe9;
1711         emit_imm32((imm));
1712 }
1713
1714 /* like emit_jmp_imm but allows 8 bit optimization */
1715 void emit_jmp_imm2(codegendata *cd, s8 imm) {
1716         if (IS_IMM8(imm)) {
1717                 *(cd->mcodeptr++) = 0xeb;
1718                 emit_imm8((imm));
1719         }
1720         else {
1721                 *(cd->mcodeptr++) = 0xe9;
1722                 emit_imm32((imm));
1723         }
1724 }
1725
1726
1727 void emit_jmp_reg(codegendata *cd, s8 reg) {
1728         emit_rex(0,0,0,(reg));
1729         *(cd->mcodeptr++) = 0xff;
1730         emit_reg(4,(reg));
1731 }
1732
1733
1734 void emit_jcc(codegendata *cd, s8 opc, s8 imm) {
1735         *(cd->mcodeptr++) = 0x0f;
1736         *(cd->mcodeptr++) = (0x80 + (opc));
1737         emit_imm32((imm));
1738 }
1739
1740
1741
1742 /*
1743  * conditional set and move operations
1744  */
1745
1746 /* we need the rex byte to get all low bytes */
1747 void emit_setcc_reg(codegendata *cd, s4 opc, s4 reg)
1748 {
1749         *(cd->mcodeptr++) = (0x40 | (((reg) >> 3) & 0x01));
1750         *(cd->mcodeptr++) = 0x0f;
1751         *(cd->mcodeptr++) = (0x90 + (opc));
1752         emit_reg(0,(reg));
1753 }
1754
1755
1756 /* we need the rex byte to get all low bytes */
1757 void emit_setcc_membase(codegendata *cd, s4 opc, s4 basereg, s4 disp)
1758 {
1759         *(cd->mcodeptr++) = (0x40 | (((basereg) >> 3) & 0x01));
1760         *(cd->mcodeptr++) = 0x0f;
1761         *(cd->mcodeptr++) = (0x90 + (opc));
1762         emit_membase(cd, (basereg),(disp),0);
1763 }
1764
1765
1766 void emit_cmovcc_reg_reg(codegendata *cd, s4 opc, s4 reg, s4 dreg)
1767 {
1768         emit_rex(1,(dreg),0,(reg));
1769         *(cd->mcodeptr++) = 0x0f;
1770         *(cd->mcodeptr++) = (0x40 + (opc));
1771         emit_reg((dreg),(reg));
1772 }
1773
1774
1775 void emit_cmovccl_reg_reg(codegendata *cd, s4 opc, s4 reg, s4 dreg)
1776 {
1777         emit_rex(0,(dreg),0,(reg));
1778         *(cd->mcodeptr++) = 0x0f;
1779         *(cd->mcodeptr++) = (0x40 + (opc));
1780         emit_reg((dreg),(reg));
1781 }
1782
1783
1784 void emit_neg_reg(codegendata *cd, s8 reg)
1785 {
1786         emit_rex(1,0,0,(reg));
1787         *(cd->mcodeptr++) = 0xf7;
1788         emit_reg(3,(reg));
1789 }
1790
1791
1792 void emit_negl_reg(codegendata *cd, s8 reg)
1793 {
1794         emit_rex(0,0,0,(reg));
1795         *(cd->mcodeptr++) = 0xf7;
1796         emit_reg(3,(reg));
1797 }
1798
1799
1800 void emit_push_reg(codegendata *cd, s8 reg) {
1801         emit_rex(0,0,0,(reg));
1802         *(cd->mcodeptr++) = 0x50 + (0x07 & (reg));
1803 }
1804
1805
1806 void emit_push_imm(codegendata *cd, s8 imm) {
1807         *(cd->mcodeptr++) = 0x68;
1808         emit_imm32((imm));
1809 }
1810
1811
1812 void emit_pop_reg(codegendata *cd, s8 reg) {
1813         emit_rex(0,0,0,(reg));
1814         *(cd->mcodeptr++) = 0x58 + (0x07 & (reg));
1815 }
1816
1817
1818 void emit_xchg_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
1819         emit_rex(1,(reg),0,(dreg));
1820         *(cd->mcodeptr++) = 0x87;
1821         emit_reg((reg),(dreg));
1822 }
1823
1824
1825
1826 /*
1827  * call instructions
1828  */
1829 void emit_call_reg(codegendata *cd, s8 reg)
1830 {
1831         emit_rex(0,0,0,(reg));
1832         *(cd->mcodeptr++) = 0xff;
1833         emit_reg(2,(reg));
1834 }
1835
1836
1837 void emit_call_imm(codegendata *cd, s8 imm)
1838 {
1839         *(cd->mcodeptr++) = 0xe8;
1840         emit_imm32((imm));
1841 }
1842
1843
1844 void emit_call_mem(codegendata *cd, ptrint mem)
1845 {
1846         *(cd->mcodeptr++) = 0xff;
1847         emit_mem(2,(mem));
1848 }
1849
1850
1851
1852 /*
1853  * floating point instructions (SSE2)
1854  */
1855 void emit_addsd_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
1856         *(cd->mcodeptr++) = 0xf2;
1857         emit_rex(0,(dreg),0,(reg));
1858         *(cd->mcodeptr++) = 0x0f;
1859         *(cd->mcodeptr++) = 0x58;
1860         emit_reg((dreg),(reg));
1861 }
1862
1863
1864 void emit_addss_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
1865         *(cd->mcodeptr++) = 0xf3;
1866         emit_rex(0,(dreg),0,(reg));
1867         *(cd->mcodeptr++) = 0x0f;
1868         *(cd->mcodeptr++) = 0x58;
1869         emit_reg((dreg),(reg));
1870 }
1871
1872
1873 void emit_cvtsi2ssq_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
1874         *(cd->mcodeptr++) = 0xf3;
1875         emit_rex(1,(dreg),0,(reg));
1876         *(cd->mcodeptr++) = 0x0f;
1877         *(cd->mcodeptr++) = 0x2a;
1878         emit_reg((dreg),(reg));
1879 }
1880
1881
1882 void emit_cvtsi2ss_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
1883         *(cd->mcodeptr++) = 0xf3;
1884         emit_rex(0,(dreg),0,(reg));
1885         *(cd->mcodeptr++) = 0x0f;
1886         *(cd->mcodeptr++) = 0x2a;
1887         emit_reg((dreg),(reg));
1888 }
1889
1890
1891 void emit_cvtsi2sdq_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
1892         *(cd->mcodeptr++) = 0xf2;
1893         emit_rex(1,(dreg),0,(reg));
1894         *(cd->mcodeptr++) = 0x0f;
1895         *(cd->mcodeptr++) = 0x2a;
1896         emit_reg((dreg),(reg));
1897 }
1898
1899
1900 void emit_cvtsi2sd_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
1901         *(cd->mcodeptr++) = 0xf2;
1902         emit_rex(0,(dreg),0,(reg));
1903         *(cd->mcodeptr++) = 0x0f;
1904         *(cd->mcodeptr++) = 0x2a;
1905         emit_reg((dreg),(reg));
1906 }
1907
1908
1909 void emit_cvtss2sd_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
1910         *(cd->mcodeptr++) = 0xf3;
1911         emit_rex(0,(dreg),0,(reg));
1912         *(cd->mcodeptr++) = 0x0f;
1913         *(cd->mcodeptr++) = 0x5a;
1914         emit_reg((dreg),(reg));
1915 }
1916
1917
1918 void emit_cvtsd2ss_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
1919         *(cd->mcodeptr++) = 0xf2;
1920         emit_rex(0,(dreg),0,(reg));
1921         *(cd->mcodeptr++) = 0x0f;
1922         *(cd->mcodeptr++) = 0x5a;
1923         emit_reg((dreg),(reg));
1924 }
1925
1926
1927 void emit_cvttss2siq_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
1928         *(cd->mcodeptr++) = 0xf3;
1929         emit_rex(1,(dreg),0,(reg));
1930         *(cd->mcodeptr++) = 0x0f;
1931         *(cd->mcodeptr++) = 0x2c;
1932         emit_reg((dreg),(reg));
1933 }
1934
1935
1936 void emit_cvttss2si_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
1937         *(cd->mcodeptr++) = 0xf3;
1938         emit_rex(0,(dreg),0,(reg));
1939         *(cd->mcodeptr++) = 0x0f;
1940         *(cd->mcodeptr++) = 0x2c;
1941         emit_reg((dreg),(reg));
1942 }
1943
1944
1945 void emit_cvttsd2siq_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
1946         *(cd->mcodeptr++) = 0xf2;
1947         emit_rex(1,(dreg),0,(reg));
1948         *(cd->mcodeptr++) = 0x0f;
1949         *(cd->mcodeptr++) = 0x2c;
1950         emit_reg((dreg),(reg));
1951 }
1952
1953
1954 void emit_cvttsd2si_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
1955         *(cd->mcodeptr++) = 0xf2;
1956         emit_rex(0,(dreg),0,(reg));
1957         *(cd->mcodeptr++) = 0x0f;
1958         *(cd->mcodeptr++) = 0x2c;
1959         emit_reg((dreg),(reg));
1960 }
1961
1962
1963 void emit_divss_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
1964         *(cd->mcodeptr++) = 0xf3;
1965         emit_rex(0,(dreg),0,(reg));
1966         *(cd->mcodeptr++) = 0x0f;
1967         *(cd->mcodeptr++) = 0x5e;
1968         emit_reg((dreg),(reg));
1969 }
1970
1971
1972 void emit_divsd_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
1973         *(cd->mcodeptr++) = 0xf2;
1974         emit_rex(0,(dreg),0,(reg));
1975         *(cd->mcodeptr++) = 0x0f;
1976         *(cd->mcodeptr++) = 0x5e;
1977         emit_reg((dreg),(reg));
1978 }
1979
1980
1981 void emit_movd_reg_freg(codegendata *cd, s8 reg, s8 freg) {
1982         *(cd->mcodeptr++) = 0x66;
1983         emit_rex(1,(freg),0,(reg));
1984         *(cd->mcodeptr++) = 0x0f;
1985         *(cd->mcodeptr++) = 0x6e;
1986         emit_reg((freg),(reg));
1987 }
1988
1989
1990 void emit_movd_freg_reg(codegendata *cd, s8 freg, s8 reg) {
1991         *(cd->mcodeptr++) = 0x66;
1992         emit_rex(1,(freg),0,(reg));
1993         *(cd->mcodeptr++) = 0x0f;
1994         *(cd->mcodeptr++) = 0x7e;
1995         emit_reg((freg),(reg));
1996 }
1997
1998
1999 void emit_movd_reg_membase(codegendata *cd, s8 reg, s8 basereg, s8 disp) {
2000         *(cd->mcodeptr++) = 0x66;
2001         emit_rex(0,(reg),0,(basereg));
2002         *(cd->mcodeptr++) = 0x0f;
2003         *(cd->mcodeptr++) = 0x7e;
2004         emit_membase(cd, (basereg),(disp),(reg));
2005 }
2006
2007
2008 void emit_movd_reg_memindex(codegendata *cd, s8 reg, s8 disp, s8 basereg, s8 indexreg, s8 scale) {
2009         *(cd->mcodeptr++) = 0x66;
2010         emit_rex(0,(reg),(indexreg),(basereg));
2011         *(cd->mcodeptr++) = 0x0f;
2012         *(cd->mcodeptr++) = 0x7e;
2013         emit_memindex(cd, (reg),(disp),(basereg),(indexreg),(scale));
2014 }
2015
2016
2017 void emit_movd_membase_reg(codegendata *cd, s8 basereg, s8 disp, s8 dreg) {
2018         *(cd->mcodeptr++) = 0x66;
2019         emit_rex(1,(dreg),0,(basereg));
2020         *(cd->mcodeptr++) = 0x0f;
2021         *(cd->mcodeptr++) = 0x6e;
2022         emit_membase(cd, (basereg),(disp),(dreg));
2023 }
2024
2025
2026 void emit_movdl_membase_reg(codegendata *cd, s8 basereg, s8 disp, s8 dreg) {
2027         *(cd->mcodeptr++) = 0x66;
2028         emit_rex(0,(dreg),0,(basereg));
2029         *(cd->mcodeptr++) = 0x0f;
2030         *(cd->mcodeptr++) = 0x6e;
2031         emit_membase(cd, (basereg),(disp),(dreg));
2032 }
2033
2034
2035 void emit_movd_memindex_reg(codegendata *cd, s8 disp, s8 basereg, s8 indexreg, s8 scale, s8 dreg) {
2036         *(cd->mcodeptr++) = 0x66;
2037         emit_rex(0,(dreg),(indexreg),(basereg));
2038         *(cd->mcodeptr++) = 0x0f;
2039         *(cd->mcodeptr++) = 0x6e;
2040         emit_memindex(cd, (dreg),(disp),(basereg),(indexreg),(scale));
2041 }
2042
2043
2044 void emit_movq_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
2045         *(cd->mcodeptr++) = 0xf3;
2046         emit_rex(0,(dreg),0,(reg));
2047         *(cd->mcodeptr++) = 0x0f;
2048         *(cd->mcodeptr++) = 0x7e;
2049         emit_reg((dreg),(reg));
2050 }
2051
2052
2053 void emit_movq_reg_membase(codegendata *cd, s8 reg, s8 basereg, s8 disp) {
2054         *(cd->mcodeptr++) = 0x66;
2055         emit_rex(0,(reg),0,(basereg));
2056         *(cd->mcodeptr++) = 0x0f;
2057         *(cd->mcodeptr++) = 0xd6;
2058         emit_membase(cd, (basereg),(disp),(reg));
2059 }
2060
2061
2062 void emit_movq_membase_reg(codegendata *cd, s8 basereg, s8 disp, s8 dreg) {
2063         *(cd->mcodeptr++) = 0xf3;
2064         emit_rex(0,(dreg),0,(basereg));
2065         *(cd->mcodeptr++) = 0x0f;
2066         *(cd->mcodeptr++) = 0x7e;
2067         emit_membase(cd, (basereg),(disp),(dreg));
2068 }
2069
2070
2071 void emit_movss_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
2072         *(cd->mcodeptr++) = 0xf3;
2073         emit_rex(0,(reg),0,(dreg));
2074         *(cd->mcodeptr++) = 0x0f;
2075         *(cd->mcodeptr++) = 0x10;
2076         emit_reg((reg),(dreg));
2077 }
2078
2079
2080 void emit_movsd_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
2081         *(cd->mcodeptr++) = 0xf2;
2082         emit_rex(0,(reg),0,(dreg));
2083         *(cd->mcodeptr++) = 0x0f;
2084         *(cd->mcodeptr++) = 0x10;
2085         emit_reg((reg),(dreg));
2086 }
2087
2088
2089 void emit_movss_reg_membase(codegendata *cd, s8 reg, s8 basereg, s8 disp) {
2090         *(cd->mcodeptr++) = 0xf3;
2091         emit_rex(0,(reg),0,(basereg));
2092         *(cd->mcodeptr++) = 0x0f;
2093         *(cd->mcodeptr++) = 0x11;
2094         emit_membase(cd, (basereg),(disp),(reg));
2095 }
2096
2097
2098 /* Always emit a REX byte, because the instruction size can be smaller when   */
2099 /* all register indexes are smaller than 7.                                   */
2100 void emit_movss_reg_membase32(codegendata *cd, s8 reg, s8 basereg, s8 disp) {
2101         *(cd->mcodeptr++) = 0xf3;
2102         emit_byte_rex((reg),0,(basereg));
2103         *(cd->mcodeptr++) = 0x0f;
2104         *(cd->mcodeptr++) = 0x11;
2105         emit_membase32(cd, (basereg),(disp),(reg));
2106 }
2107
2108
2109 void emit_movsd_reg_membase(codegendata *cd, s8 reg, s8 basereg, s8 disp) {
2110         *(cd->mcodeptr++) = 0xf2;
2111         emit_rex(0,(reg),0,(basereg));
2112         *(cd->mcodeptr++) = 0x0f;
2113         *(cd->mcodeptr++) = 0x11;
2114         emit_membase(cd, (basereg),(disp),(reg));
2115 }
2116
2117
2118 /* Always emit a REX byte, because the instruction size can be smaller when   */
2119 /* all register indexes are smaller than 7.                                   */
2120 void emit_movsd_reg_membase32(codegendata *cd, s8 reg, s8 basereg, s8 disp) {
2121         *(cd->mcodeptr++) = 0xf2;
2122         emit_byte_rex((reg),0,(basereg));
2123         *(cd->mcodeptr++) = 0x0f;
2124         *(cd->mcodeptr++) = 0x11;
2125         emit_membase32(cd, (basereg),(disp),(reg));
2126 }
2127
2128
2129 void emit_movss_membase_reg(codegendata *cd, s8 basereg, s8 disp, s8 dreg) {
2130         *(cd->mcodeptr++) = 0xf3;
2131         emit_rex(0,(dreg),0,(basereg));
2132         *(cd->mcodeptr++) = 0x0f;
2133         *(cd->mcodeptr++) = 0x10;
2134         emit_membase(cd, (basereg),(disp),(dreg));
2135 }
2136
2137
2138 /* Always emit a REX byte, because the instruction size can be smaller when   */
2139 /* all register indexes are smaller than 7.                                   */
2140 void emit_movss_membase32_reg(codegendata *cd, s8 basereg, s8 disp, s8 dreg) {
2141         *(cd->mcodeptr++) = 0xf3;
2142         emit_byte_rex((dreg),0,(basereg));
2143         *(cd->mcodeptr++) = 0x0f;
2144         *(cd->mcodeptr++) = 0x10;
2145         emit_membase32(cd, (basereg),(disp),(dreg));
2146 }
2147
2148
2149 void emit_movlps_membase_reg(codegendata *cd, s8 basereg, s8 disp, s8 dreg)
2150 {
2151         emit_rex(0,(dreg),0,(basereg));
2152         *(cd->mcodeptr++) = 0x0f;
2153         *(cd->mcodeptr++) = 0x12;
2154         emit_membase(cd, (basereg),(disp),(dreg));
2155 }
2156
2157
2158 void emit_movlps_reg_membase(codegendata *cd, s8 reg, s8 basereg, s8 disp)
2159 {
2160         emit_rex(0,(reg),0,(basereg));
2161         *(cd->mcodeptr++) = 0x0f;
2162         *(cd->mcodeptr++) = 0x13;
2163         emit_membase(cd, (basereg),(disp),(reg));
2164 }
2165
2166
2167 void emit_movsd_membase_reg(codegendata *cd, s8 basereg, s8 disp, s8 dreg) {
2168         *(cd->mcodeptr++) = 0xf2;
2169         emit_rex(0,(dreg),0,(basereg));
2170         *(cd->mcodeptr++) = 0x0f;
2171         *(cd->mcodeptr++) = 0x10;
2172         emit_membase(cd, (basereg),(disp),(dreg));
2173 }
2174
2175
2176 /* Always emit a REX byte, because the instruction size can be smaller when   */
2177 /* all register indexes are smaller than 7.                                   */
2178 void emit_movsd_membase32_reg(codegendata *cd, s8 basereg, s8 disp, s8 dreg) {
2179         *(cd->mcodeptr++) = 0xf2;
2180         emit_byte_rex((dreg),0,(basereg));
2181         *(cd->mcodeptr++) = 0x0f;
2182         *(cd->mcodeptr++) = 0x10;
2183         emit_membase32(cd, (basereg),(disp),(dreg));
2184 }
2185
2186
2187 void emit_movlpd_membase_reg(codegendata *cd, s8 basereg, s8 disp, s8 dreg)
2188 {
2189         *(cd->mcodeptr++) = 0x66;
2190         emit_rex(0,(dreg),0,(basereg));
2191         *(cd->mcodeptr++) = 0x0f;
2192         *(cd->mcodeptr++) = 0x12;
2193         emit_membase(cd, (basereg),(disp),(dreg));
2194 }
2195
2196
2197 void emit_movlpd_reg_membase(codegendata *cd, s8 reg, s8 basereg, s8 disp)
2198 {
2199         *(cd->mcodeptr++) = 0x66;
2200         emit_rex(0,(reg),0,(basereg));
2201         *(cd->mcodeptr++) = 0x0f;
2202         *(cd->mcodeptr++) = 0x13;
2203         emit_membase(cd, (basereg),(disp),(reg));
2204 }
2205
2206
2207 void emit_movss_reg_memindex(codegendata *cd, s8 reg, s8 disp, s8 basereg, s8 indexreg, s8 scale) {
2208         *(cd->mcodeptr++) = 0xf3;
2209         emit_rex(0,(reg),(indexreg),(basereg));
2210         *(cd->mcodeptr++) = 0x0f;
2211         *(cd->mcodeptr++) = 0x11;
2212         emit_memindex(cd, (reg),(disp),(basereg),(indexreg),(scale));
2213 }
2214
2215
2216 void emit_movsd_reg_memindex(codegendata *cd, s8 reg, s8 disp, s8 basereg, s8 indexreg, s8 scale) {
2217         *(cd->mcodeptr++) = 0xf2;
2218         emit_rex(0,(reg),(indexreg),(basereg));
2219         *(cd->mcodeptr++) = 0x0f;
2220         *(cd->mcodeptr++) = 0x11;
2221         emit_memindex(cd, (reg),(disp),(basereg),(indexreg),(scale));
2222 }
2223
2224
2225 void emit_movss_memindex_reg(codegendata *cd, s8 disp, s8 basereg, s8 indexreg, s8 scale, s8 dreg) {
2226         *(cd->mcodeptr++) = 0xf3;
2227         emit_rex(0,(dreg),(indexreg),(basereg));
2228         *(cd->mcodeptr++) = 0x0f;
2229         *(cd->mcodeptr++) = 0x10;
2230         emit_memindex(cd, (dreg),(disp),(basereg),(indexreg),(scale));
2231 }
2232
2233
2234 void emit_movsd_memindex_reg(codegendata *cd, s8 disp, s8 basereg, s8 indexreg, s8 scale, s8 dreg) {
2235         *(cd->mcodeptr++) = 0xf2;
2236         emit_rex(0,(dreg),(indexreg),(basereg));
2237         *(cd->mcodeptr++) = 0x0f;
2238         *(cd->mcodeptr++) = 0x10;
2239         emit_memindex(cd, (dreg),(disp),(basereg),(indexreg),(scale));
2240 }
2241
2242
2243 void emit_mulss_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
2244         *(cd->mcodeptr++) = 0xf3;
2245         emit_rex(0,(dreg),0,(reg));
2246         *(cd->mcodeptr++) = 0x0f;
2247         *(cd->mcodeptr++) = 0x59;
2248         emit_reg((dreg),(reg));
2249 }
2250
2251
2252 void emit_mulsd_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
2253         *(cd->mcodeptr++) = 0xf2;
2254         emit_rex(0,(dreg),0,(reg));
2255         *(cd->mcodeptr++) = 0x0f;
2256         *(cd->mcodeptr++) = 0x59;
2257         emit_reg((dreg),(reg));
2258 }
2259
2260
2261 void emit_subss_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
2262         *(cd->mcodeptr++) = 0xf3;
2263         emit_rex(0,(dreg),0,(reg));
2264         *(cd->mcodeptr++) = 0x0f;
2265         *(cd->mcodeptr++) = 0x5c;
2266         emit_reg((dreg),(reg));
2267 }
2268
2269
2270 void emit_subsd_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
2271         *(cd->mcodeptr++) = 0xf2;
2272         emit_rex(0,(dreg),0,(reg));
2273         *(cd->mcodeptr++) = 0x0f;
2274         *(cd->mcodeptr++) = 0x5c;
2275         emit_reg((dreg),(reg));
2276 }
2277
2278
2279 void emit_ucomiss_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
2280         emit_rex(0,(dreg),0,(reg));
2281         *(cd->mcodeptr++) = 0x0f;
2282         *(cd->mcodeptr++) = 0x2e;
2283         emit_reg((dreg),(reg));
2284 }
2285
2286
2287 void emit_ucomisd_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
2288         *(cd->mcodeptr++) = 0x66;
2289         emit_rex(0,(dreg),0,(reg));
2290         *(cd->mcodeptr++) = 0x0f;
2291         *(cd->mcodeptr++) = 0x2e;
2292         emit_reg((dreg),(reg));
2293 }
2294
2295
2296 void emit_xorps_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
2297         emit_rex(0,(dreg),0,(reg));
2298         *(cd->mcodeptr++) = 0x0f;
2299         *(cd->mcodeptr++) = 0x57;
2300         emit_reg((dreg),(reg));
2301 }
2302
2303
2304 void emit_xorps_membase_reg(codegendata *cd, s8 basereg, s8 disp, s8 dreg) {
2305         emit_rex(0,(dreg),0,(basereg));
2306         *(cd->mcodeptr++) = 0x0f;
2307         *(cd->mcodeptr++) = 0x57;
2308         emit_membase(cd, (basereg),(disp),(dreg));
2309 }
2310
2311
2312 void emit_xorpd_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
2313         *(cd->mcodeptr++) = 0x66;
2314         emit_rex(0,(dreg),0,(reg));
2315         *(cd->mcodeptr++) = 0x0f;
2316         *(cd->mcodeptr++) = 0x57;
2317         emit_reg((dreg),(reg));
2318 }
2319
2320
2321 void emit_xorpd_membase_reg(codegendata *cd, s8 basereg, s8 disp, s8 dreg) {
2322         *(cd->mcodeptr++) = 0x66;
2323         emit_rex(0,(dreg),0,(basereg));
2324         *(cd->mcodeptr++) = 0x0f;
2325         *(cd->mcodeptr++) = 0x57;
2326         emit_membase(cd, (basereg),(disp),(dreg));
2327 }
2328
2329
2330 /* system instructions ********************************************************/
2331
2332 void emit_rdtsc(codegendata *cd)
2333 {
2334         *(cd->mcodeptr++) = 0x0f;
2335         *(cd->mcodeptr++) = 0x31;
2336 }
2337
2338
2339 /*
2340  * These are local overrides for various environment variables in Emacs.
2341  * Please do not remove this and leave it at the end of the file, where
2342  * Emacs will automagically detect them.
2343  * ---------------------------------------------------------------------
2344  * Local variables:
2345  * mode: c
2346  * indent-tabs-mode: t
2347  * c-basic-offset: 4
2348  * tab-width: 4
2349  * End:
2350  */