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