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