45882a6e93366ee042a278e79485d1a52c5741d3
[cacao.git] / src / vm / jit / x86_64 / emitfuncs.c
1 /* jit/x86_64/emitfuncs.c - x86_64 code emitter functions
2
3    Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003
4    Institut f. Computersprachen, TU Wien
5    R. Grafl, A. Krall, C. Kruegel, C. Oates, R. Obermaisser, M. Probst,
6    S. Ring, E. Steiner, C. Thalinger, D. Thuernbeck, P. Tomsich,
7    J. Wenninger
8
9    This file is part of CACAO.
10
11    This program is free software; you can redistribute it and/or
12    modify it under the terms of the GNU General Public License as
13    published by the Free Software Foundation; either version 2, or (at
14    your option) any later version.
15
16    This program is distributed in the hope that it will be useful, but
17    WITHOUT ANY WARRANTY; without even the implied warranty of
18    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
19    General Public License for more details.
20
21    You should have received a copy of the GNU General Public License
22    along with this program; if not, write to the Free Software
23    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
24    02111-1307, USA.
25
26    Contact: cacao@complang.tuwien.ac.at
27
28    Authors: Christian Thalinger
29
30    $Id: emitfuncs.c 1353 2004-07-26 22:31:24Z twisti $
31
32 */
33
34
35 #include "jit/jit.h"
36 #include "jit/x86_64/emitfuncs.h"
37 #include "jit/x86_64/codegen.h"
38 #include "jit/x86_64/types.h"
39
40
41 /* code generation functions */
42
43 void x86_64_emit_ialu(methodinfo *m, s4 alu_op, stackptr src, instruction *iptr)
44 {
45         codegendata *cd;
46         s4 s1 = src->prev->regoff;
47         s4 s2 = src->regoff;
48         s4 d = iptr->dst->regoff;
49
50         cd = m->codegendata;
51
52         if (iptr->dst->flags & INMEMORY) {
53                 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
54                         if (s2 == d) {
55                                 x86_64_movl_membase_reg(cd, REG_SP, s1 * 8, REG_ITMP1);
56                                 x86_64_alul_reg_membase(cd, alu_op, REG_ITMP1, REG_SP, d * 8);
57
58                         } else if (s1 == d) {
59                                 x86_64_movl_membase_reg(cd, REG_SP, s2 * 8, REG_ITMP1);
60                                 x86_64_alul_reg_membase(cd, alu_op, REG_ITMP1, REG_SP, d * 8);
61
62                         } else {
63                                 x86_64_movl_membase_reg(cd, REG_SP, s1 * 8, REG_ITMP1);
64                                 x86_64_alul_membase_reg(cd, alu_op, REG_SP, s2 * 8, REG_ITMP1);
65                                 x86_64_movl_reg_membase(cd, REG_ITMP1, REG_SP, d * 8);
66                         }
67
68                 } else if ((src->flags & INMEMORY) && !(src->prev->flags & INMEMORY)) {
69                         if (s2 == d) {
70                                 x86_64_alul_reg_membase(cd, alu_op, s1, REG_SP, d * 8);
71
72                         } else {
73                                 x86_64_movl_membase_reg(cd, REG_SP, s2 * 8, REG_ITMP1);
74                                 x86_64_alul_reg_reg(cd, alu_op, s1, REG_ITMP1);
75                                 x86_64_movl_reg_membase(cd, REG_ITMP1, REG_SP, d * 8);
76                         }
77
78                 } else if (!(src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
79                         if (s1 == d) {
80                                 x86_64_alul_reg_membase(cd, alu_op, s2, REG_SP, d * 8);
81                                                 
82                         } else {
83                                 x86_64_movl_membase_reg(cd, REG_SP, s1 * 8, REG_ITMP1);
84                                 x86_64_alul_reg_reg(cd, alu_op, s2, REG_ITMP1);
85                                 x86_64_movl_reg_membase(cd, REG_ITMP1, REG_SP, d * 8);
86                         }
87
88                 } else {
89                         x86_64_movl_reg_membase(cd, s1, REG_SP, d * 8);
90                         x86_64_alul_reg_membase(cd, alu_op, s2, REG_SP, d * 8);
91                 }
92
93         } else {
94                 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
95                         x86_64_movl_membase_reg(cd, REG_SP, s1 * 8, d);
96                         x86_64_alul_membase_reg(cd, alu_op, REG_SP, s2 * 8, d);
97
98                 } else if ((src->flags & INMEMORY) && !(src->prev->flags & INMEMORY)) {
99                         M_INTMOVE(s1, d);
100                         x86_64_alul_membase_reg(cd, alu_op, REG_SP, s2 * 8, d);
101
102                 } else if (!(src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
103                         M_INTMOVE(s2, d);
104                         x86_64_alul_membase_reg(cd, alu_op, REG_SP, s1 * 8, d);
105
106                 } else {
107                         if (s2 == d) {
108                                 x86_64_alul_reg_reg(cd, alu_op, s1, d);
109
110                         } else {
111                                 M_INTMOVE(s1, d);
112                                 x86_64_alul_reg_reg(cd, alu_op, s2, d);
113                         }
114                 }
115         }
116 }
117
118
119
120 void x86_64_emit_lalu(methodinfo *m, s4 alu_op, stackptr src, instruction *iptr)
121 {
122         codegendata *cd;
123         s4 s1 = src->prev->regoff;
124         s4 s2 = src->regoff;
125         s4 d = iptr->dst->regoff;
126
127         cd = m->codegendata;
128
129         if (iptr->dst->flags & INMEMORY) {
130                 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
131                         if (s2 == d) {
132                                 x86_64_mov_membase_reg(cd, REG_SP, s1 * 8, REG_ITMP1);
133                                 x86_64_alu_reg_membase(cd, alu_op, REG_ITMP1, REG_SP, d * 8);
134
135                         } else if (s1 == d) {
136                                 x86_64_mov_membase_reg(cd, REG_SP, s2 * 8, REG_ITMP1);
137                                 x86_64_alu_reg_membase(cd, alu_op, REG_ITMP1, REG_SP, d * 8);
138
139                         } else {
140                                 x86_64_mov_membase_reg(cd, REG_SP, s1 * 8, REG_ITMP1);
141                                 x86_64_alu_membase_reg(cd, alu_op, REG_SP, s2 * 8, REG_ITMP1);
142                                 x86_64_mov_reg_membase(cd, REG_ITMP1, REG_SP, d * 8);
143                         }
144
145                 } else if ((src->flags & INMEMORY) && !(src->prev->flags & INMEMORY)) {
146                         if (s2 == d) {
147                                 x86_64_alu_reg_membase(cd, alu_op, s1, REG_SP, d * 8);
148
149                         } else {
150                                 x86_64_mov_membase_reg(cd, REG_SP, s2 * 8, REG_ITMP1);
151                                 x86_64_alu_reg_reg(cd, alu_op, s1, REG_ITMP1);
152                                 x86_64_mov_reg_membase(cd, REG_ITMP1, REG_SP, d * 8);
153                         }
154
155                 } else if (!(src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
156                         if (s1 == d) {
157                                 x86_64_alu_reg_membase(cd, alu_op, s2, REG_SP, d * 8);
158                                                 
159                         } else {
160                                 x86_64_mov_membase_reg(cd, REG_SP, s1 * 8, REG_ITMP1);
161                                 x86_64_alu_reg_reg(cd, alu_op, s2, REG_ITMP1);
162                                 x86_64_mov_reg_membase(cd, REG_ITMP1, REG_SP, d * 8);
163                         }
164
165                 } else {
166                         x86_64_mov_reg_membase(cd, s1, REG_SP, d * 8);
167                         x86_64_alu_reg_membase(cd, alu_op, s2, REG_SP, d * 8);
168                 }
169
170         } else {
171                 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
172                         x86_64_mov_membase_reg(cd, REG_SP, s1 * 8, d);
173                         x86_64_alu_membase_reg(cd, alu_op, REG_SP, s2 * 8, d);
174
175                 } else if ((src->flags & INMEMORY) && !(src->prev->flags & INMEMORY)) {
176                         M_INTMOVE(s1, d);
177                         x86_64_alu_membase_reg(cd, alu_op, REG_SP, s2 * 8, d);
178
179                 } else if (!(src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
180                         M_INTMOVE(s2, d);
181                         x86_64_alu_membase_reg(cd, alu_op, REG_SP, s1 * 8, d);
182
183                 } else {
184                         if (s2 == d) {
185                                 x86_64_alu_reg_reg(cd, alu_op, s1, d);
186
187                         } else {
188                                 M_INTMOVE(s1, d);
189                                 x86_64_alu_reg_reg(cd, alu_op, s2, d);
190                         }
191                 }
192         }
193 }
194
195
196
197 void x86_64_emit_ialuconst(methodinfo *m, s4 alu_op, stackptr src, instruction *iptr)
198 {
199         codegendata *cd;
200         s4 s1 = src->regoff;
201         s4 d = iptr->dst->regoff;
202
203         cd = m->codegendata;
204
205         if (iptr->dst->flags & INMEMORY) {
206                 if (src->flags & INMEMORY) {
207                         if (s1 == d) {
208                                 x86_64_alul_imm_membase(cd, alu_op, iptr->val.i, REG_SP, d * 8);
209
210                         } else {
211                                 x86_64_movl_membase_reg(cd, REG_SP, s1 * 8, REG_ITMP1);
212                                 x86_64_alul_imm_reg(cd, alu_op, iptr->val.i, REG_ITMP1);
213                                 x86_64_movl_reg_membase(cd, REG_ITMP1, REG_SP, d * 8);
214                         }
215
216                 } else {
217                         x86_64_movl_reg_membase(cd, s1, REG_SP, d * 8);
218                         x86_64_alul_imm_membase(cd, alu_op, iptr->val.i, REG_SP, d * 8);
219                 }
220
221         } else {
222                 if (src->flags & INMEMORY) {
223                         x86_64_movl_membase_reg(cd, REG_SP, s1 * 8, d);
224                         x86_64_alul_imm_reg(cd, alu_op, iptr->val.i, d);
225
226                 } else {
227                         M_INTMOVE(s1, d);
228                         x86_64_alul_imm_reg(cd, alu_op, iptr->val.i, d);
229                 }
230         }
231 }
232
233
234
235 void x86_64_emit_laluconst(methodinfo *m, s4 alu_op, stackptr src, instruction *iptr)
236 {
237         codegendata *cd;
238         s4 s1 = src->regoff;
239         s4 d = iptr->dst->regoff;
240
241         cd = m->codegendata;
242
243         if (iptr->dst->flags & INMEMORY) {
244                 if (src->flags & INMEMORY) {
245                         if (s1 == d) {
246                                 if (x86_64_is_imm32(iptr->val.l)) {
247                                         x86_64_alu_imm_membase(cd, alu_op, iptr->val.l, REG_SP, d * 8);
248
249                                 } else {
250                                         x86_64_mov_imm_reg(cd, iptr->val.l, REG_ITMP1);
251                                         x86_64_alu_reg_membase(cd, alu_op, REG_ITMP1, REG_SP, d * 8);
252                                 }
253
254                         } else {
255                                 x86_64_mov_membase_reg(cd, REG_SP, s1 * 8, REG_ITMP1);
256
257                                 if (x86_64_is_imm32(iptr->val.l)) {
258                                         x86_64_alu_imm_reg(cd, alu_op, iptr->val.l, REG_ITMP1);
259
260                                 } else {
261                                         x86_64_mov_imm_reg(cd, iptr->val.l, REG_ITMP2);
262                                         x86_64_alu_reg_reg(cd, alu_op, REG_ITMP2, REG_ITMP1);
263                                 }
264                                 x86_64_mov_reg_membase(cd, REG_ITMP1, REG_SP, d * 8);
265                         }
266
267                 } else {
268                         x86_64_mov_reg_membase(cd, s1, REG_SP, d * 8);
269
270                         if (x86_64_is_imm32(iptr->val.l)) {
271                                 x86_64_alu_imm_membase(cd, alu_op, iptr->val.l, REG_SP, d * 8);
272
273                         } else {
274                                 x86_64_mov_imm_reg(cd, iptr->val.l, REG_ITMP1);
275                                 x86_64_alu_reg_membase(cd, alu_op, REG_ITMP1, REG_SP, d * 8);
276                         }
277                 }
278
279         } else {
280                 if (src->flags & INMEMORY) {
281                         x86_64_mov_membase_reg(cd, REG_SP, s1 * 8, d);
282
283                 } else {
284                         M_INTMOVE(s1, d);
285                 }
286
287                 if (x86_64_is_imm32(iptr->val.l)) {
288                         x86_64_alu_imm_reg(cd, alu_op, iptr->val.l, d);
289
290                 } else {
291                         x86_64_mov_imm_reg(cd, iptr->val.l, REG_ITMP1);
292                         x86_64_alu_reg_reg(cd, alu_op, REG_ITMP1, d);
293                 }
294         }
295 }
296
297
298
299 void x86_64_emit_ishift(methodinfo *m, s4 shift_op, stackptr src, instruction *iptr)
300 {
301         codegendata *cd;
302         s4 s1 = src->prev->regoff;
303         s4 s2 = src->regoff;
304         s4 d = iptr->dst->regoff;
305
306         cd = m->codegendata;
307
308         M_INTMOVE(RCX, REG_ITMP1);    /* save RCX */
309         if (iptr->dst->flags & INMEMORY) {
310                 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
311                         if (s1 == d) {
312                                 x86_64_movl_membase_reg(cd, REG_SP, s2 * 8, RCX);
313                                 x86_64_shiftl_membase(cd, shift_op, REG_SP, d * 8);
314
315                         } else {
316                                 x86_64_movl_membase_reg(cd, REG_SP, s2 * 8, RCX);
317                                 x86_64_movl_membase_reg(cd, REG_SP, s1 * 8, REG_ITMP2);
318                                 x86_64_shiftl_reg(cd, shift_op, REG_ITMP2);
319                                 x86_64_movl_reg_membase(cd, REG_ITMP2, REG_SP, d * 8);
320                         }
321
322                 } else if ((src->flags & INMEMORY) && !(src->prev->flags & INMEMORY)) {
323                         x86_64_movl_membase_reg(cd, REG_SP, s2 * 8, RCX);
324                         x86_64_movl_reg_membase(cd, s1, REG_SP, d * 8);
325                         x86_64_shiftl_membase(cd, shift_op, REG_SP, d * 8);
326
327                 } else if (!(src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
328                         if (s1 == d) {
329                                 M_INTMOVE(s2, RCX);
330                                 x86_64_shiftl_membase(cd, shift_op, REG_SP, d * 8);
331
332                         } else {
333                                 M_INTMOVE(s2, RCX);
334                                 x86_64_movl_membase_reg(cd, REG_SP, s1 * 8, REG_ITMP2);
335                                 x86_64_shiftl_reg(cd, shift_op, REG_ITMP2);
336                                 x86_64_movl_reg_membase(cd, REG_ITMP2, REG_SP, d * 8);
337                         }
338
339                 } else {
340                         M_INTMOVE(s2, RCX);
341                         x86_64_movl_reg_membase(cd, s1, REG_SP, d * 8);
342                         x86_64_shiftl_membase(cd, shift_op, REG_SP, d * 8);
343                 }
344                 M_INTMOVE(REG_ITMP1, RCX);    /* restore RCX */
345
346         } else {
347                 if (d == RCX) {
348                         d = REG_ITMP3;
349                 }
350                                         
351                 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
352                         x86_64_movl_membase_reg(cd, REG_SP, s2 * 8, RCX);
353                         x86_64_movl_membase_reg(cd, REG_SP, s1 * 8, d);
354                         x86_64_shiftl_reg(cd, shift_op, d);
355
356                 } else if ((src->flags & INMEMORY) && !(src->prev->flags & INMEMORY)) {
357                         M_INTMOVE(s1, d);    /* maybe src is RCX */
358                         x86_64_movl_membase_reg(cd, REG_SP, s2 * 8, RCX);
359                         x86_64_shiftl_reg(cd, shift_op, d);
360
361                 } else if (!(src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
362                         M_INTMOVE(s2, RCX);
363                         x86_64_movl_membase_reg(cd, REG_SP, s1 * 8, d);
364                         x86_64_shiftl_reg(cd, shift_op, d);
365
366                 } else {
367                         if (s1 == RCX) {
368                                 M_INTMOVE(s1, d);
369                                 M_INTMOVE(s2, RCX);
370
371                         } else {
372                                 M_INTMOVE(s2, RCX);
373                                 M_INTMOVE(s1, d);
374                         }
375                         x86_64_shiftl_reg(cd, shift_op, d);
376                 }
377
378                 if (d == RCX) {
379                         M_INTMOVE(REG_ITMP3, RCX);
380
381                 } else {
382                         M_INTMOVE(REG_ITMP1, RCX);    /* restore RCX */
383                 }
384         }
385 }
386
387
388
389 void x86_64_emit_lshift(methodinfo *m, s4 shift_op, stackptr src, instruction *iptr)
390 {
391         codegendata *cd;
392         s4 s1 = src->prev->regoff;
393         s4 s2 = src->regoff;
394         s4 d = iptr->dst->regoff;
395
396         cd = m->codegendata;
397
398         M_INTMOVE(RCX, REG_ITMP1);    /* save RCX */
399         if (iptr->dst->flags & INMEMORY) {
400                 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
401                         if (s1 == d) {
402                                 x86_64_mov_membase_reg(cd, REG_SP, s2 * 8, RCX);
403                                 x86_64_shift_membase(cd, shift_op, REG_SP, d * 8);
404
405                         } else {
406                                 x86_64_mov_membase_reg(cd, REG_SP, s2 * 8, RCX);
407                                 x86_64_mov_membase_reg(cd, REG_SP, s1 * 8, REG_ITMP2);
408                                 x86_64_shift_reg(cd, shift_op, REG_ITMP2);
409                                 x86_64_mov_reg_membase(cd, REG_ITMP2, REG_SP, d * 8);
410                         }
411
412                 } else if ((src->flags & INMEMORY) && !(src->prev->flags & INMEMORY)) {
413                         x86_64_mov_membase_reg(cd, REG_SP, s2 * 8, RCX);
414                         x86_64_mov_reg_membase(cd, s1, REG_SP, d * 8);
415                         x86_64_shift_membase(cd, shift_op, REG_SP, d * 8);
416
417                 } else if (!(src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
418                         if (s1 == d) {
419                                 M_INTMOVE(s2, RCX);
420                                 x86_64_shift_membase(cd, shift_op, REG_SP, d * 8);
421
422                         } else {
423                                 M_INTMOVE(s2, RCX);
424                                 x86_64_mov_membase_reg(cd, REG_SP, s1 * 8, REG_ITMP2);
425                                 x86_64_shift_reg(cd, shift_op, REG_ITMP2);
426                                 x86_64_mov_reg_membase(cd, REG_ITMP2, REG_SP, d * 8);
427                         }
428
429                 } else {
430                         M_INTMOVE(s2, RCX);
431                         x86_64_mov_reg_membase(cd, s1, REG_SP, d * 8);
432                         x86_64_shift_membase(cd, shift_op, REG_SP, d * 8);
433                 }
434                 M_INTMOVE(REG_ITMP1, RCX);    /* restore RCX */
435
436         } else {
437                 if (d == RCX) {
438                         d = REG_ITMP3;
439                 }
440
441                 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
442                         x86_64_mov_membase_reg(cd, REG_SP, s2 * 8, RCX);
443                         x86_64_mov_membase_reg(cd, REG_SP, s1 * 8, d);
444                         x86_64_shift_reg(cd, shift_op, d);
445
446                 } else if ((src->flags & INMEMORY) && !(src->prev->flags & INMEMORY)) {
447                         M_INTMOVE(s1, d);    /* maybe src is RCX */
448                         x86_64_mov_membase_reg(cd, REG_SP, s2 * 8, RCX);
449                         x86_64_shift_reg(cd, shift_op, d);
450
451                 } else if (!(src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
452                         M_INTMOVE(s2, RCX);
453                         x86_64_mov_membase_reg(cd, REG_SP, s1 * 8, d);
454                         x86_64_shift_reg(cd, shift_op, d);
455
456                 } else {
457                         if (s1 == RCX) {
458                                 M_INTMOVE(s1, d);
459                                 M_INTMOVE(s2, RCX);
460                         } else {
461                                 M_INTMOVE(s2, RCX);
462                                 M_INTMOVE(s1, d);
463                         }
464                         x86_64_shift_reg(cd, shift_op, d);
465                 }
466
467                 if (d == RCX) {
468                         M_INTMOVE(REG_ITMP3, RCX);
469
470                 } else {
471                         M_INTMOVE(REG_ITMP1, RCX);    /* restore RCX */
472                 }
473         }
474 }
475
476
477
478 void x86_64_emit_ishiftconst(methodinfo *m, s4 shift_op, stackptr src, instruction *iptr)
479 {
480         codegendata *cd;
481         s4 s1 = src->regoff;
482         s4 d = iptr->dst->regoff;
483
484         cd = m->codegendata;
485
486         if ((src->flags & INMEMORY) && (iptr->dst->flags & INMEMORY)) {
487                 if (s1 == d) {
488                         x86_64_shiftl_imm_membase(cd, shift_op, iptr->val.i, REG_SP, d * 8);
489
490                 } else {
491                         x86_64_movl_membase_reg(cd, REG_SP, s1 * 8, REG_ITMP1);
492                         x86_64_shiftl_imm_reg(cd, shift_op, iptr->val.i, REG_ITMP1);
493                         x86_64_movl_reg_membase(cd, REG_ITMP1, REG_SP, d * 8);
494                 }
495
496         } else if ((src->flags & INMEMORY) && !(iptr->dst->flags & INMEMORY)) {
497                 x86_64_movl_membase_reg(cd, REG_SP, s1 * 8, d);
498                 x86_64_shiftl_imm_reg(cd, shift_op, iptr->val.i, d);
499                                 
500         } else if (!(src->flags & INMEMORY) && (iptr->dst->flags & INMEMORY)) {
501                 x86_64_movl_reg_membase(cd, s1, REG_SP, d * 8);
502                 x86_64_shiftl_imm_membase(cd, shift_op, iptr->val.i, REG_SP, d * 8);
503
504         } else {
505                 M_INTMOVE(s1, d);
506                 x86_64_shiftl_imm_reg(cd, shift_op, iptr->val.i, d);
507         }
508 }
509
510
511
512 void x86_64_emit_lshiftconst(methodinfo *m, s4 shift_op, stackptr src, instruction *iptr)
513 {
514         codegendata *cd;
515         s4 s1 = src->regoff;
516         s4 d = iptr->dst->regoff;
517
518         cd = m->codegendata;
519
520         if ((src->flags & INMEMORY) && (iptr->dst->flags & INMEMORY)) {
521                 if (s1 == d) {
522                         x86_64_shift_imm_membase(cd, shift_op, iptr->val.i, REG_SP, d * 8);
523
524                 } else {
525                         x86_64_mov_membase_reg(cd, REG_SP, s1 * 8, REG_ITMP1);
526                         x86_64_shift_imm_reg(cd, shift_op, iptr->val.i, REG_ITMP1);
527                         x86_64_mov_reg_membase(cd, REG_ITMP1, REG_SP, d * 8);
528                 }
529
530         } else if ((src->flags & INMEMORY) && !(iptr->dst->flags & INMEMORY)) {
531                 x86_64_mov_membase_reg(cd, REG_SP, s1 * 8, d);
532                 x86_64_shift_imm_reg(cd, shift_op, iptr->val.i, d);
533                                 
534         } else if (!(src->flags & INMEMORY) && (iptr->dst->flags & INMEMORY)) {
535                 x86_64_mov_reg_membase(cd, s1, REG_SP, d * 8);
536                 x86_64_shift_imm_membase(cd, shift_op, iptr->val.i, REG_SP, d * 8);
537
538         } else {
539                 M_INTMOVE(s1, d);
540                 x86_64_shift_imm_reg(cd, shift_op, iptr->val.i, d);
541         }
542 }
543
544
545
546 void x86_64_emit_ifcc(methodinfo *m, s4 if_op, stackptr src, instruction *iptr)
547 {
548         codegendata *cd;
549
550         cd = m->codegendata;
551
552         if (src->flags & INMEMORY) {
553                 x86_64_alul_imm_membase(cd, X86_64_CMP, iptr->val.i, REG_SP, src->regoff * 8);
554
555         } else {
556                 x86_64_alul_imm_reg(cd, X86_64_CMP, iptr->val.i, src->regoff);
557         }
558         x86_64_jcc(cd, if_op, 0);
559         codegen_addreference(m, BlockPtrOfPC(iptr->op1), cd->mcodeptr);
560 }
561
562
563
564 void x86_64_emit_if_lcc(methodinfo *m, s4 if_op, stackptr src, instruction *iptr)
565 {
566         codegendata *cd;
567         s4 s1 = src->regoff;
568
569         cd = m->codegendata;
570
571         if (src->flags & INMEMORY) {
572                 if (x86_64_is_imm32(iptr->val.l)) {
573                         x86_64_alu_imm_membase(cd, X86_64_CMP, iptr->val.l, REG_SP, s1 * 8);
574
575                 } else {
576                         x86_64_mov_imm_reg(cd, iptr->val.l, REG_ITMP1);
577                         x86_64_alu_reg_membase(cd, X86_64_CMP, REG_ITMP1, REG_SP, s1 * 8);
578                 }
579
580         } else {
581                 if (x86_64_is_imm32(iptr->val.l)) {
582                         x86_64_alu_imm_reg(cd, X86_64_CMP, iptr->val.l, s1);
583
584                 } else {
585                         x86_64_mov_imm_reg(cd, iptr->val.l, REG_ITMP1);
586                         x86_64_alu_reg_reg(cd, X86_64_CMP, REG_ITMP1, s1);
587                 }
588         }
589         x86_64_jcc(cd, if_op, 0);
590         codegen_addreference(m, BlockPtrOfPC(iptr->op1), cd->mcodeptr);
591 }
592
593
594
595 void x86_64_emit_if_icmpcc(methodinfo *m, s4 if_op, stackptr src, instruction *iptr)
596 {
597         codegendata *cd;
598         s4 s1 = src->prev->regoff;
599         s4 s2 = src->regoff;
600
601         cd = m->codegendata;
602
603         if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
604                 x86_64_movl_membase_reg(cd, REG_SP, s2 * 8, REG_ITMP1);
605                 x86_64_alul_reg_membase(cd, X86_64_CMP, REG_ITMP1, REG_SP, s1 * 8);
606
607         } else if ((src->flags & INMEMORY) && !(src->prev->flags & INMEMORY)) {
608                 x86_64_alul_membase_reg(cd, X86_64_CMP, REG_SP, s2 * 8, s1);
609
610         } else if (!(src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
611                 x86_64_alul_reg_membase(cd, X86_64_CMP, s2, REG_SP, s1 * 8);
612
613         } else {
614                 x86_64_alul_reg_reg(cd, X86_64_CMP, s2, s1);
615         }
616         x86_64_jcc(cd, if_op, 0);
617         codegen_addreference(m, BlockPtrOfPC(iptr->op1), cd->mcodeptr);
618 }
619
620
621
622 void x86_64_emit_if_lcmpcc(methodinfo *m, s4 if_op, stackptr src, instruction *iptr)
623 {
624         codegendata *cd;
625         s4 s1 = src->prev->regoff;
626         s4 s2 = src->regoff;
627
628         cd = m->codegendata;
629
630         if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
631                 x86_64_mov_membase_reg(cd, REG_SP, s2 * 8, REG_ITMP1);
632                 x86_64_alu_reg_membase(cd, X86_64_CMP, REG_ITMP1, REG_SP, s1 * 8);
633
634         } else if ((src->flags & INMEMORY) && !(src->prev->flags & INMEMORY)) {
635                 x86_64_alu_membase_reg(cd, X86_64_CMP, REG_SP, s2 * 8, s1);
636
637         } else if (!(src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
638                 x86_64_alu_reg_membase(cd, X86_64_CMP, s2, REG_SP, s1 * 8);
639
640         } else {
641                 x86_64_alu_reg_reg(cd, X86_64_CMP, s2, s1);
642         }
643         x86_64_jcc(cd, if_op, 0);
644         codegen_addreference(m, BlockPtrOfPC(iptr->op1), cd->mcodeptr);
645 }
646
647
648 /*
649  * mov ops
650  */
651 void x86_64_mov_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
652         x86_64_emit_rex(1,(reg),0,(dreg));
653         *(cd->mcodeptr++) = 0x89;
654         x86_64_emit_reg((reg),(dreg));
655 }
656
657
658 void x86_64_mov_imm_reg(codegendata *cd, s8 imm, s8 reg) {
659         x86_64_emit_rex(1,0,0,(reg));
660         *(cd->mcodeptr++) = 0xb8 + ((reg) & 0x07);
661         x86_64_emit_imm64((imm));
662 }
663
664
665 void x86_64_movl_imm_reg(codegendata *cd, s8 imm, s8 reg) {
666         x86_64_emit_rex(0,0,0,(reg));
667         *(cd->mcodeptr++) = 0xb8 + ((reg) & 0x07);
668         x86_64_emit_imm32((imm));
669 }
670
671
672 void x86_64_mov_membase_reg(codegendata *cd, s8 basereg, s8 disp, s8 reg) {
673         x86_64_emit_rex(1,(reg),0,(basereg));
674         *(cd->mcodeptr++) = 0x8b;
675         x86_64_emit_membase((basereg),(disp),(reg));
676 }
677
678
679 void x86_64_movl_membase_reg(codegendata *cd, s8 basereg, s8 disp, s8 reg) {
680         x86_64_emit_rex(0,(reg),0,(basereg));
681         *(cd->mcodeptr++) = 0x8b;
682         x86_64_emit_membase((basereg),(disp),(reg));
683 }
684
685
686 /*
687  * this one is for INVOKEVIRTUAL/INVOKEINTERFACE to have a
688  * constant membase immediate length of 32bit
689  */
690 void x86_64_mov_membase32_reg(codegendata *cd, s8 basereg, s8 disp, s8 reg) {
691         x86_64_emit_rex(1,(reg),0,(basereg));
692         *(cd->mcodeptr++) = 0x8b;
693         x86_64_address_byte(2, (reg), (basereg));
694         x86_64_emit_imm32((disp));
695 }
696
697
698 void x86_64_mov_reg_membase(codegendata *cd, s8 reg, s8 basereg, s8 disp) {
699         x86_64_emit_rex(1,(reg),0,(basereg));
700         *(cd->mcodeptr++) = 0x89;
701         x86_64_emit_membase((basereg),(disp),(reg));
702 }
703
704
705 void x86_64_movl_reg_membase(codegendata *cd, s8 reg, s8 basereg, s8 disp) {
706         x86_64_emit_rex(0,(reg),0,(basereg));
707         *(cd->mcodeptr++) = 0x89;
708         x86_64_emit_membase((basereg),(disp),(reg));
709 }
710
711
712 void x86_64_mov_memindex_reg(codegendata *cd, s8 disp, s8 basereg, s8 indexreg, s8 scale, s8 reg) {
713         x86_64_emit_rex(1,(reg),(indexreg),(basereg));
714         *(cd->mcodeptr++) = 0x8b;
715         x86_64_emit_memindex((reg),(disp),(basereg),(indexreg),(scale));
716 }
717
718
719 void x86_64_movl_memindex_reg(codegendata *cd, s8 disp, s8 basereg, s8 indexreg, s8 scale, s8 reg) {
720         x86_64_emit_rex(0,(reg),(indexreg),(basereg));
721         *(cd->mcodeptr++) = 0x8b;
722         x86_64_emit_memindex((reg),(disp),(basereg),(indexreg),(scale));
723 }
724
725
726 void x86_64_mov_reg_memindex(codegendata *cd, s8 reg, s8 disp, s8 basereg, s8 indexreg, s8 scale) {
727         x86_64_emit_rex(1,(reg),(indexreg),(basereg));
728         *(cd->mcodeptr++) = 0x89;
729         x86_64_emit_memindex((reg),(disp),(basereg),(indexreg),(scale));
730 }
731
732
733 void x86_64_movl_reg_memindex(codegendata *cd, s8 reg, s8 disp, s8 basereg, s8 indexreg, s8 scale) {
734         x86_64_emit_rex(0,(reg),(indexreg),(basereg));
735         *(cd->mcodeptr++) = 0x89;
736         x86_64_emit_memindex((reg),(disp),(basereg),(indexreg),(scale));
737 }
738
739
740 void x86_64_movw_reg_memindex(codegendata *cd, s8 reg, s8 disp, s8 basereg, s8 indexreg, s8 scale) {
741         *(cd->mcodeptr++) = 0x66;
742         x86_64_emit_rex(0,(reg),(indexreg),(basereg));
743         *(cd->mcodeptr++) = 0x89;
744         x86_64_emit_memindex((reg),(disp),(basereg),(indexreg),(scale));
745 }
746
747
748 void x86_64_movb_reg_memindex(codegendata *cd, s8 reg, s8 disp, s8 basereg, s8 indexreg, s8 scale) {
749         x86_64_emit_rex(0,(reg),(indexreg),(basereg));
750         *(cd->mcodeptr++) = 0x88;
751         x86_64_emit_memindex((reg),(disp),(basereg),(indexreg),(scale));
752 }
753
754
755 void x86_64_mov_imm_membase(codegendata *cd, s8 imm, s8 basereg, s8 disp) {
756         x86_64_emit_rex(1,0,0,(basereg));
757         *(cd->mcodeptr++) = 0xc7;
758         x86_64_emit_membase((basereg),(disp),0);
759         x86_64_emit_imm32((imm));
760 }
761
762
763 void x86_64_movl_imm_membase(codegendata *cd, s8 imm, s8 basereg, s8 disp) {
764         x86_64_emit_rex(0,0,0,(basereg));
765         *(cd->mcodeptr++) = 0xc7;
766         x86_64_emit_membase((basereg),(disp),0);
767         x86_64_emit_imm32((imm));
768 }
769
770
771 void x86_64_movsbq_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
772         x86_64_emit_rex(1,(dreg),0,(reg));
773         *(cd->mcodeptr++) = 0x0f;
774         *(cd->mcodeptr++) = 0xbe;
775         /* XXX: why do reg and dreg have to be exchanged */
776         x86_64_emit_reg((dreg),(reg));
777 }
778
779
780 void x86_64_movsbq_membase_reg(codegendata *cd, s8 basereg, s8 disp, s8 dreg) {
781         x86_64_emit_rex(1,(dreg),0,(basereg));
782         *(cd->mcodeptr++) = 0x0f;
783         *(cd->mcodeptr++) = 0xbe;
784         x86_64_emit_membase((basereg),(disp),(dreg));
785 }
786
787
788 void x86_64_movswq_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
789         x86_64_emit_rex(1,(dreg),0,(reg));
790         *(cd->mcodeptr++) = 0x0f;
791         *(cd->mcodeptr++) = 0xbf;
792         /* XXX: why do reg and dreg have to be exchanged */
793         x86_64_emit_reg((dreg),(reg));
794 }
795
796
797 void x86_64_movswq_membase_reg(codegendata *cd, s8 basereg, s8 disp, s8 dreg) {
798         x86_64_emit_rex(1,(dreg),0,(basereg));
799         *(cd->mcodeptr++) = 0x0f;
800         *(cd->mcodeptr++) = 0xbf;
801         x86_64_emit_membase((basereg),(disp),(dreg));
802 }
803
804
805 void x86_64_movslq_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
806         x86_64_emit_rex(1,(dreg),0,(reg));
807         *(cd->mcodeptr++) = 0x63;
808         /* XXX: why do reg and dreg have to be exchanged */
809         x86_64_emit_reg((dreg),(reg));
810 }
811
812
813 void x86_64_movslq_membase_reg(codegendata *cd, s8 basereg, s8 disp, s8 dreg) {
814         x86_64_emit_rex(1,(dreg),0,(basereg));
815         *(cd->mcodeptr++) = 0x63;
816         x86_64_emit_membase((basereg),(disp),(dreg));
817 }
818
819
820 void x86_64_movzwq_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
821         x86_64_emit_rex(1,(dreg),0,(reg));
822         *(cd->mcodeptr++) = 0x0f;
823         *(cd->mcodeptr++) = 0xb7;
824         /* XXX: why do reg and dreg have to be exchanged */
825         x86_64_emit_reg((dreg),(reg));
826 }
827
828
829 void x86_64_movzwq_membase_reg(codegendata *cd, s8 basereg, s8 disp, s8 dreg) {
830         x86_64_emit_rex(1,(dreg),0,(basereg));
831         *(cd->mcodeptr++) = 0x0f;
832         *(cd->mcodeptr++) = 0xb7;
833         x86_64_emit_membase((basereg),(disp),(dreg));
834 }
835
836
837 void x86_64_movswq_memindex_reg(codegendata *cd, s8 disp, s8 basereg, s8 indexreg, s8 scale, s8 reg) {
838         x86_64_emit_rex(1,(reg),(indexreg),(basereg));
839         *(cd->mcodeptr++) = 0x0f;
840         *(cd->mcodeptr++) = 0xbf;
841         x86_64_emit_memindex((reg),(disp),(basereg),(indexreg),(scale));
842 }
843
844
845 void x86_64_movsbq_memindex_reg(codegendata *cd, s8 disp, s8 basereg, s8 indexreg, s8 scale, s8 reg) {
846         x86_64_emit_rex(1,(reg),(indexreg),(basereg));
847         *(cd->mcodeptr++) = 0x0f;
848         *(cd->mcodeptr++) = 0xbe;
849         x86_64_emit_memindex((reg),(disp),(basereg),(indexreg),(scale));
850 }
851
852
853 void x86_64_movzwq_memindex_reg(codegendata *cd, s8 disp, s8 basereg, s8 indexreg, s8 scale, s8 reg) {
854         x86_64_emit_rex(1,(reg),(indexreg),(basereg));
855         *(cd->mcodeptr++) = 0x0f;
856         *(cd->mcodeptr++) = 0xb7;
857         x86_64_emit_memindex((reg),(disp),(basereg),(indexreg),(scale));
858 }
859
860
861
862 /*
863  * alu operations
864  */
865 void x86_64_alu_reg_reg(codegendata *cd, s8 opc, s8 reg, s8 dreg) {
866         x86_64_emit_rex(1,(reg),0,(dreg));
867         *(cd->mcodeptr++) = (((opc)) << 3) + 1;
868         x86_64_emit_reg((reg),(dreg));
869 }
870
871
872 void x86_64_alul_reg_reg(codegendata *cd, s8 opc, s8 reg, s8 dreg) {
873         x86_64_emit_rex(0,(reg),0,(dreg));
874         *(cd->mcodeptr++) = (((opc)) << 3) + 1;
875         x86_64_emit_reg((reg),(dreg));
876 }
877
878
879 void x86_64_alu_reg_membase(codegendata *cd, s8 opc, s8 reg, s8 basereg, s8 disp) {
880         x86_64_emit_rex(1,(reg),0,(basereg));
881         *(cd->mcodeptr++) = (((opc)) << 3) + 1;
882         x86_64_emit_membase((basereg),(disp),(reg));
883 }
884
885
886 void x86_64_alul_reg_membase(codegendata *cd, s8 opc, s8 reg, s8 basereg, s8 disp) {
887         x86_64_emit_rex(0,(reg),0,(basereg));
888         *(cd->mcodeptr++) = (((opc)) << 3) + 1;
889         x86_64_emit_membase((basereg),(disp),(reg));
890 }
891
892
893 void x86_64_alu_membase_reg(codegendata *cd, s8 opc, s8 basereg, s8 disp, s8 reg) {
894         x86_64_emit_rex(1,(reg),0,(basereg));
895         *(cd->mcodeptr++) = (((opc)) << 3) + 3;
896         x86_64_emit_membase((basereg),(disp),(reg));
897 }
898
899
900 void x86_64_alul_membase_reg(codegendata *cd, s8 opc, s8 basereg, s8 disp, s8 reg) {
901         x86_64_emit_rex(0,(reg),0,(basereg));
902         *(cd->mcodeptr++) = (((opc)) << 3) + 3;
903         x86_64_emit_membase((basereg),(disp),(reg));
904 }
905
906
907 void x86_64_alu_imm_reg(codegendata *cd, s8 opc, s8 imm, s8 dreg) {
908         if (x86_64_is_imm8(imm)) {
909                 x86_64_emit_rex(1,0,0,(dreg));
910                 *(cd->mcodeptr++) = 0x83;
911                 x86_64_emit_reg((opc),(dreg));
912                 x86_64_emit_imm8((imm));
913         } else {
914                 x86_64_emit_rex(1,0,0,(dreg));
915                 *(cd->mcodeptr++) = 0x81;
916                 x86_64_emit_reg((opc),(dreg));
917                 x86_64_emit_imm32((imm));
918         }
919 }
920
921
922 void x86_64_alul_imm_reg(codegendata *cd, s8 opc, s8 imm, s8 dreg) {
923         if (x86_64_is_imm8(imm)) {
924                 x86_64_emit_rex(0,0,0,(dreg));
925                 *(cd->mcodeptr++) = 0x83;
926                 x86_64_emit_reg((opc),(dreg));
927                 x86_64_emit_imm8((imm));
928         } else {
929                 x86_64_emit_rex(0,0,0,(dreg));
930                 *(cd->mcodeptr++) = 0x81;
931                 x86_64_emit_reg((opc),(dreg));
932                 x86_64_emit_imm32((imm));
933         }
934 }
935
936
937 void x86_64_alu_imm_membase(codegendata *cd, s8 opc, s8 imm, s8 basereg, s8 disp) {
938         if (x86_64_is_imm8(imm)) {
939                 x86_64_emit_rex(1,(basereg),0,0);
940                 *(cd->mcodeptr++) = 0x83;
941                 x86_64_emit_membase((basereg),(disp),(opc));
942                 x86_64_emit_imm8((imm));
943         } else {
944                 x86_64_emit_rex(1,(basereg),0,0);
945                 *(cd->mcodeptr++) = 0x81;
946                 x86_64_emit_membase((basereg),(disp),(opc));
947                 x86_64_emit_imm32((imm));
948         }
949 }
950
951
952 void x86_64_alul_imm_membase(codegendata *cd, s8 opc, s8 imm, s8 basereg, s8 disp) {
953         if (x86_64_is_imm8(imm)) {
954                 x86_64_emit_rex(0,(basereg),0,0);
955                 *(cd->mcodeptr++) = 0x83;
956                 x86_64_emit_membase((basereg),(disp),(opc));
957                 x86_64_emit_imm8((imm));
958         } else {
959                 x86_64_emit_rex(0,(basereg),0,0);
960                 *(cd->mcodeptr++) = 0x81;
961                 x86_64_emit_membase((basereg),(disp),(opc));
962                 x86_64_emit_imm32((imm));
963         }
964 }
965
966
967 void x86_64_test_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
968         x86_64_emit_rex(1,(reg),0,(dreg));
969         *(cd->mcodeptr++) = 0x85;
970         x86_64_emit_reg((reg),(dreg));
971 }
972
973
974 void x86_64_testl_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
975         x86_64_emit_rex(0,(reg),0,(dreg));
976         *(cd->mcodeptr++) = 0x85;
977         x86_64_emit_reg((reg),(dreg));
978 }
979
980
981 void x86_64_test_imm_reg(codegendata *cd, s8 imm, s8 reg) {
982         *(cd->mcodeptr++) = 0xf7;
983         x86_64_emit_reg(0,(reg));
984         x86_64_emit_imm32((imm));
985 }
986
987
988 void x86_64_testw_imm_reg(codegendata *cd, s8 imm, s8 reg) {
989         *(cd->mcodeptr++) = 0x66;
990         *(cd->mcodeptr++) = 0xf7;
991         x86_64_emit_reg(0,(reg));
992         x86_64_emit_imm16((imm));
993 }
994
995
996 void x86_64_testb_imm_reg(codegendata *cd, s8 imm, s8 reg) {
997         *(cd->mcodeptr++) = 0xf6;
998         x86_64_emit_reg(0,(reg));
999         x86_64_emit_imm8((imm));
1000 }
1001
1002
1003 void x86_64_lea_membase_reg(codegendata *cd, s8 basereg, s8 disp, s8 reg) {
1004         x86_64_emit_rex(1,(reg),0,(basereg));
1005         *(cd->mcodeptr++) = 0x8d;
1006         x86_64_emit_membase((basereg),(disp),(reg));
1007 }
1008
1009
1010 void x86_64_leal_membase_reg(codegendata *cd, s8 basereg, s8 disp, s8 reg) {
1011         x86_64_emit_rex(0,(reg),0,(basereg));
1012         *(cd->mcodeptr++) = 0x8d;
1013         x86_64_emit_membase((basereg),(disp),(reg));
1014 }
1015
1016
1017
1018 /*
1019  * inc, dec operations
1020  */
1021 void x86_64_inc_reg(codegendata *cd, s8 reg) {
1022         x86_64_emit_rex(1,0,0,(reg));
1023         *(cd->mcodeptr++) = 0xff;
1024         x86_64_emit_reg(0,(reg));
1025 }
1026
1027
1028 void x86_64_incl_reg(codegendata *cd, s8 reg) {
1029         x86_64_emit_rex(0,0,0,(reg));
1030         *(cd->mcodeptr++) = 0xff;
1031         x86_64_emit_reg(0,(reg));
1032 }
1033
1034
1035 void x86_64_inc_membase(codegendata *cd, s8 basereg, s8 disp) {
1036         x86_64_emit_rex(1,(basereg),0,0);
1037         *(cd->mcodeptr++) = 0xff;
1038         x86_64_emit_membase((basereg),(disp),0);
1039 }
1040
1041
1042 void x86_64_incl_membase(codegendata *cd, s8 basereg, s8 disp) {
1043         x86_64_emit_rex(0,(basereg),0,0);
1044         *(cd->mcodeptr++) = 0xff;
1045         x86_64_emit_membase((basereg),(disp),0);
1046 }
1047
1048
1049 void x86_64_dec_reg(codegendata *cd, s8 reg) {
1050         x86_64_emit_rex(1,0,0,(reg));
1051         *(cd->mcodeptr++) = 0xff;
1052         x86_64_emit_reg(1,(reg));
1053 }
1054
1055         
1056 void x86_64_decl_reg(codegendata *cd, s8 reg) {
1057         x86_64_emit_rex(0,0,0,(reg));
1058         *(cd->mcodeptr++) = 0xff;
1059         x86_64_emit_reg(1,(reg));
1060 }
1061
1062         
1063 void x86_64_dec_membase(codegendata *cd, s8 basereg, s8 disp) {
1064         x86_64_emit_rex(1,(basereg),0,0);
1065         *(cd->mcodeptr++) = 0xff;
1066         x86_64_emit_membase((basereg),(disp),1);
1067 }
1068
1069
1070 void x86_64_decl_membase(codegendata *cd, s8 basereg, s8 disp) {
1071         x86_64_emit_rex(0,(basereg),0,0);
1072         *(cd->mcodeptr++) = 0xff;
1073         x86_64_emit_membase((basereg),(disp),1);
1074 }
1075
1076
1077
1078
1079 void x86_64_cltd(codegendata *cd) {
1080     *(cd->mcodeptr++) = 0x99;
1081 }
1082
1083
1084 void x86_64_cqto(codegendata *cd) {
1085         x86_64_emit_rex(1,0,0,0);
1086         *(cd->mcodeptr++) = 0x99;
1087 }
1088
1089
1090
1091 void x86_64_imul_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
1092         x86_64_emit_rex(1,(dreg),0,(reg));
1093         *(cd->mcodeptr++) = 0x0f;
1094         *(cd->mcodeptr++) = 0xaf;
1095         x86_64_emit_reg((dreg),(reg));
1096 }
1097
1098
1099 void x86_64_imull_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
1100         x86_64_emit_rex(0,(dreg),0,(reg));
1101         *(cd->mcodeptr++) = 0x0f;
1102         *(cd->mcodeptr++) = 0xaf;
1103         x86_64_emit_reg((dreg),(reg));
1104 }
1105
1106
1107 void x86_64_imul_membase_reg(codegendata *cd, s8 basereg, s8 disp, s8 dreg) {
1108         x86_64_emit_rex(1,(dreg),0,(basereg));
1109         *(cd->mcodeptr++) = 0x0f;
1110         *(cd->mcodeptr++) = 0xaf;
1111         x86_64_emit_membase((basereg),(disp),(dreg));
1112 }
1113
1114
1115 void x86_64_imull_membase_reg(codegendata *cd, s8 basereg, s8 disp, s8 dreg) {
1116         x86_64_emit_rex(0,(dreg),0,(basereg));
1117         *(cd->mcodeptr++) = 0x0f;
1118         *(cd->mcodeptr++) = 0xaf;
1119         x86_64_emit_membase((basereg),(disp),(dreg));
1120 }
1121
1122
1123 void x86_64_imul_imm_reg(codegendata *cd, s8 imm, s8 dreg) {
1124         if (x86_64_is_imm8((imm))) {
1125                 x86_64_emit_rex(1,0,0,(dreg));
1126                 *(cd->mcodeptr++) = 0x6b;
1127                 x86_64_emit_reg(0,(dreg));
1128                 x86_64_emit_imm8((imm));
1129         } else {
1130                 x86_64_emit_rex(1,0,0,(dreg));
1131                 *(cd->mcodeptr++) = 0x69;
1132                 x86_64_emit_reg(0,(dreg));
1133                 x86_64_emit_imm32((imm));
1134         }
1135 }
1136
1137
1138 void x86_64_imul_imm_reg_reg(codegendata *cd, s8 imm, s8 reg, s8 dreg) {
1139         if (x86_64_is_imm8((imm))) {
1140                 x86_64_emit_rex(1,(dreg),0,(reg));
1141                 *(cd->mcodeptr++) = 0x6b;
1142                 x86_64_emit_reg((dreg),(reg));
1143                 x86_64_emit_imm8((imm));
1144         } else {
1145                 x86_64_emit_rex(1,(dreg),0,(reg));
1146                 *(cd->mcodeptr++) = 0x69;
1147                 x86_64_emit_reg((dreg),(reg));
1148                 x86_64_emit_imm32((imm));
1149         }
1150 }
1151
1152
1153 void x86_64_imull_imm_reg_reg(codegendata *cd, s8 imm, s8 reg, s8 dreg) {
1154         if (x86_64_is_imm8((imm))) {
1155                 x86_64_emit_rex(0,(dreg),0,(reg));
1156                 *(cd->mcodeptr++) = 0x6b;
1157                 x86_64_emit_reg((dreg),(reg));
1158                 x86_64_emit_imm8((imm));
1159         } else {
1160                 x86_64_emit_rex(0,(dreg),0,(reg));
1161                 *(cd->mcodeptr++) = 0x69;
1162                 x86_64_emit_reg((dreg),(reg));
1163                 x86_64_emit_imm32((imm));
1164         }
1165 }
1166
1167
1168 void x86_64_imul_imm_membase_reg(codegendata *cd, s8 imm, s8 basereg, s8 disp, s8 dreg) {
1169         if (x86_64_is_imm8((imm))) {
1170                 x86_64_emit_rex(1,(dreg),0,(basereg));
1171                 *(cd->mcodeptr++) = 0x6b;
1172                 x86_64_emit_membase((basereg),(disp),(dreg));
1173                 x86_64_emit_imm8((imm));
1174         } else {
1175                 x86_64_emit_rex(1,(dreg),0,(basereg));
1176                 *(cd->mcodeptr++) = 0x69;
1177                 x86_64_emit_membase((basereg),(disp),(dreg));
1178                 x86_64_emit_imm32((imm));
1179         }
1180 }
1181
1182
1183 void x86_64_imull_imm_membase_reg(codegendata *cd, s8 imm, s8 basereg, s8 disp, s8 dreg) {
1184         if (x86_64_is_imm8((imm))) {
1185                 x86_64_emit_rex(0,(dreg),0,(basereg));
1186                 *(cd->mcodeptr++) = 0x6b;
1187                 x86_64_emit_membase((basereg),(disp),(dreg));
1188                 x86_64_emit_imm8((imm));
1189         } else {
1190                 x86_64_emit_rex(0,(dreg),0,(basereg));
1191                 *(cd->mcodeptr++) = 0x69;
1192                 x86_64_emit_membase((basereg),(disp),(dreg));
1193                 x86_64_emit_imm32((imm));
1194         }
1195 }
1196
1197
1198 void x86_64_idiv_reg(codegendata *cd, s8 reg) {
1199         x86_64_emit_rex(1,0,0,(reg));
1200         *(cd->mcodeptr++) = 0xf7;
1201         x86_64_emit_reg(7,(reg));
1202 }
1203
1204
1205 void x86_64_idivl_reg(codegendata *cd, s8 reg) {
1206         x86_64_emit_rex(0,0,0,(reg));
1207         *(cd->mcodeptr++) = 0xf7;
1208         x86_64_emit_reg(7,(reg));
1209 }
1210
1211
1212
1213 void x86_64_ret(codegendata *cd) {
1214     *(cd->mcodeptr++) = 0xc3;
1215 }
1216
1217
1218
1219 /*
1220  * shift ops
1221  */
1222 void x86_64_shift_reg(codegendata *cd, s8 opc, s8 reg) {
1223         x86_64_emit_rex(1,0,0,(reg));
1224         *(cd->mcodeptr++) = 0xd3;
1225         x86_64_emit_reg((opc),(reg));
1226 }
1227
1228
1229 void x86_64_shiftl_reg(codegendata *cd, s8 opc, s8 reg) {
1230         x86_64_emit_rex(0,0,0,(reg));
1231         *(cd->mcodeptr++) = 0xd3;
1232         x86_64_emit_reg((opc),(reg));
1233 }
1234
1235
1236 void x86_64_shift_membase(codegendata *cd, s8 opc, s8 basereg, s8 disp) {
1237         x86_64_emit_rex(1,0,0,(basereg));
1238         *(cd->mcodeptr++) = 0xd3;
1239         x86_64_emit_membase((basereg),(disp),(opc));
1240 }
1241
1242
1243 void x86_64_shiftl_membase(codegendata *cd, s8 opc, s8 basereg, s8 disp) {
1244         x86_64_emit_rex(0,0,0,(basereg));
1245         *(cd->mcodeptr++) = 0xd3;
1246         x86_64_emit_membase((basereg),(disp),(opc));
1247 }
1248
1249
1250 void x86_64_shift_imm_reg(codegendata *cd, s8 opc, s8 imm, s8 dreg) {
1251         if ((imm) == 1) {
1252                 x86_64_emit_rex(1,0,0,(dreg));
1253                 *(cd->mcodeptr++) = 0xd1;
1254                 x86_64_emit_reg((opc),(dreg));
1255         } else {
1256                 x86_64_emit_rex(1,0,0,(dreg));
1257                 *(cd->mcodeptr++) = 0xc1;
1258                 x86_64_emit_reg((opc),(dreg));
1259                 x86_64_emit_imm8((imm));
1260         }
1261 }
1262
1263
1264 void x86_64_shiftl_imm_reg(codegendata *cd, s8 opc, s8 imm, s8 dreg) {
1265         if ((imm) == 1) {
1266                 x86_64_emit_rex(0,0,0,(dreg));
1267                 *(cd->mcodeptr++) = 0xd1;
1268                 x86_64_emit_reg((opc),(dreg));
1269         } else {
1270                 x86_64_emit_rex(0,0,0,(dreg));
1271                 *(cd->mcodeptr++) = 0xc1;
1272                 x86_64_emit_reg((opc),(dreg));
1273                 x86_64_emit_imm8((imm));
1274         }
1275 }
1276
1277
1278 void x86_64_shift_imm_membase(codegendata *cd, s8 opc, s8 imm, s8 basereg, s8 disp) {
1279         if ((imm) == 1) {
1280                 x86_64_emit_rex(1,0,0,(basereg));
1281                 *(cd->mcodeptr++) = 0xd1;
1282                 x86_64_emit_membase((basereg),(disp),(opc));
1283         } else {
1284                 x86_64_emit_rex(1,0,0,(basereg));
1285                 *(cd->mcodeptr++) = 0xc1;
1286                 x86_64_emit_membase((basereg),(disp),(opc));
1287                 x86_64_emit_imm8((imm));
1288         }
1289 }
1290
1291
1292 void x86_64_shiftl_imm_membase(codegendata *cd, s8 opc, s8 imm, s8 basereg, s8 disp) {
1293         if ((imm) == 1) {
1294                 x86_64_emit_rex(0,0,0,(basereg));
1295                 *(cd->mcodeptr++) = 0xd1;
1296                 x86_64_emit_membase((basereg),(disp),(opc));
1297         } else {
1298                 x86_64_emit_rex(0,0,0,(basereg));
1299                 *(cd->mcodeptr++) = 0xc1;
1300                 x86_64_emit_membase((basereg),(disp),(opc));
1301                 x86_64_emit_imm8((imm));
1302         }
1303 }
1304
1305
1306
1307 /*
1308  * jump operations
1309  */
1310 void x86_64_jmp_imm(codegendata *cd, s8 imm) {
1311         *(cd->mcodeptr++) = 0xe9;
1312         x86_64_emit_imm32((imm));
1313 }
1314
1315
1316 void x86_64_jmp_reg(codegendata *cd, s8 reg) {
1317         x86_64_emit_rex(0,0,0,(reg));
1318         *(cd->mcodeptr++) = 0xff;
1319         x86_64_emit_reg(4,(reg));
1320 }
1321
1322
1323 void x86_64_jcc(codegendata *cd, s8 opc, s8 imm) {
1324         *(cd->mcodeptr++) = 0x0f;
1325         *(cd->mcodeptr++) = (0x80 + (opc));
1326         x86_64_emit_imm32((imm));
1327 }
1328
1329
1330
1331 /*
1332  * conditional set and move operations
1333  */
1334
1335 /* we need the rex byte to get all low bytes */
1336 void x86_64_setcc_reg(codegendata *cd, s8 opc, s8 reg) {
1337         *(cd->mcodeptr++) = (0x40 | (((reg) >> 3) & 0x01));
1338         *(cd->mcodeptr++) = 0x0f;
1339         *(cd->mcodeptr++) = (0x90 + (opc));
1340         x86_64_emit_reg(0,(reg));
1341 }
1342
1343
1344 /* we need the rex byte to get all low bytes */
1345 void x86_64_setcc_membase(codegendata *cd, s8 opc, s8 basereg, s8 disp) {
1346         *(cd->mcodeptr++) = (0x40 | (((basereg) >> 3) & 0x01));
1347         *(cd->mcodeptr++) = 0x0f;
1348         *(cd->mcodeptr++) = (0x90 + (opc));
1349         x86_64_emit_membase((basereg),(disp),0);
1350 }
1351
1352
1353 void x86_64_cmovcc_reg_reg(codegendata *cd, s8 opc, s8 reg, s8 dreg) {
1354         x86_64_emit_rex(1,(dreg),0,(reg));
1355         *(cd->mcodeptr++) = 0x0f;
1356         *(cd->mcodeptr++) = (0x40 + (opc));
1357         x86_64_emit_reg((dreg),(reg));
1358 }
1359
1360
1361 void x86_64_cmovccl_reg_reg(codegendata *cd, s8 opc, s8 reg, s8 dreg) {
1362         x86_64_emit_rex(0,(dreg),0,(reg));
1363         *(cd->mcodeptr++) = 0x0f;
1364         *(cd->mcodeptr++) = (0x40 + (opc));
1365         x86_64_emit_reg((dreg),(reg));
1366 }
1367
1368
1369
1370 void x86_64_neg_reg(codegendata *cd, s8 reg) {
1371         x86_64_emit_rex(1,0,0,(reg));
1372         *(cd->mcodeptr++) = 0xf7;
1373         x86_64_emit_reg(3,(reg));
1374 }
1375
1376
1377 void x86_64_negl_reg(codegendata *cd, s8 reg) {
1378         x86_64_emit_rex(0,0,0,(reg));
1379         *(cd->mcodeptr++) = 0xf7;
1380         x86_64_emit_reg(3,(reg));
1381 }
1382
1383
1384 void x86_64_neg_membase(codegendata *cd, s8 basereg, s8 disp) {
1385         x86_64_emit_rex(1,0,0,(basereg));
1386         *(cd->mcodeptr++) = 0xf7;
1387         x86_64_emit_membase((basereg),(disp),3);
1388 }
1389
1390
1391 void x86_64_negl_membase(codegendata *cd, s8 basereg, s8 disp) {
1392         x86_64_emit_rex(0,0,0,(basereg));
1393         *(cd->mcodeptr++) = 0xf7;
1394         x86_64_emit_membase((basereg),(disp),3);
1395 }
1396
1397
1398 void x86_64_push_reg(codegendata *cd, s8 reg) {
1399         x86_64_emit_rex(0,0,0,(reg));
1400         *(cd->mcodeptr++) = 0x50 + (0x07 & (reg));
1401 }
1402
1403
1404 void x86_64_push_imm(codegendata *cd, s8 imm) {
1405         *(cd->mcodeptr++) = 0x68;
1406         x86_64_emit_imm32((imm));
1407 }
1408
1409
1410 void x86_64_pop_reg(codegendata *cd, s8 reg) {
1411         x86_64_emit_rex(0,0,0,(reg));
1412         *(cd->mcodeptr++) = 0x58 + (0x07 & (reg));
1413 }
1414
1415
1416 void x86_64_xchg_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
1417         x86_64_emit_rex(1,(reg),0,(dreg));
1418         *(cd->mcodeptr++) = 0x87;
1419         x86_64_emit_reg((reg),(dreg));
1420 }
1421
1422
1423 void x86_64_nop(codegendata *cd) {
1424     *(cd->mcodeptr++) = 0x90;
1425 }
1426
1427
1428
1429 /*
1430  * call instructions
1431  */
1432 void x86_64_call_reg(codegendata *cd, s8 reg) {
1433         x86_64_emit_rex(1,0,0,(reg));
1434         *(cd->mcodeptr++) = 0xff;
1435         x86_64_emit_reg(2,(reg));
1436 }
1437
1438
1439 void x86_64_call_imm(codegendata *cd, s8 imm) {
1440         *(cd->mcodeptr++) = 0xe8;
1441         x86_64_emit_imm32((imm));
1442 }
1443
1444
1445 void x86_64_call_mem(codegendata *cd, s8 mem) {
1446         *(cd->mcodeptr++) = 0xff;
1447         x86_64_emit_mem(2,(mem));
1448 }
1449
1450
1451
1452 /*
1453  * floating point instructions (SSE2)
1454  */
1455 void x86_64_addsd_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
1456         *(cd->mcodeptr++) = 0xf2;
1457         x86_64_emit_rex(0,(dreg),0,(reg));
1458         *(cd->mcodeptr++) = 0x0f;
1459         *(cd->mcodeptr++) = 0x58;
1460         x86_64_emit_reg((dreg),(reg));
1461 }
1462
1463
1464 void x86_64_addss_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
1465         *(cd->mcodeptr++) = 0xf3;
1466         x86_64_emit_rex(0,(dreg),0,(reg));
1467         *(cd->mcodeptr++) = 0x0f;
1468         *(cd->mcodeptr++) = 0x58;
1469         x86_64_emit_reg((dreg),(reg));
1470 }
1471
1472
1473 void x86_64_cvtsi2ssq_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
1474         *(cd->mcodeptr++) = 0xf3;
1475         x86_64_emit_rex(1,(dreg),0,(reg));
1476         *(cd->mcodeptr++) = 0x0f;
1477         *(cd->mcodeptr++) = 0x2a;
1478         x86_64_emit_reg((dreg),(reg));
1479 }
1480
1481
1482 void x86_64_cvtsi2ss_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
1483         *(cd->mcodeptr++) = 0xf3;
1484         x86_64_emit_rex(0,(dreg),0,(reg));
1485         *(cd->mcodeptr++) = 0x0f;
1486         *(cd->mcodeptr++) = 0x2a;
1487         x86_64_emit_reg((dreg),(reg));
1488 }
1489
1490
1491 void x86_64_cvtsi2sdq_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
1492         *(cd->mcodeptr++) = 0xf2;
1493         x86_64_emit_rex(1,(dreg),0,(reg));
1494         *(cd->mcodeptr++) = 0x0f;
1495         *(cd->mcodeptr++) = 0x2a;
1496         x86_64_emit_reg((dreg),(reg));
1497 }
1498
1499
1500 void x86_64_cvtsi2sd_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
1501         *(cd->mcodeptr++) = 0xf2;
1502         x86_64_emit_rex(0,(dreg),0,(reg));
1503         *(cd->mcodeptr++) = 0x0f;
1504         *(cd->mcodeptr++) = 0x2a;
1505         x86_64_emit_reg((dreg),(reg));
1506 }
1507
1508
1509 void x86_64_cvtss2sd_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
1510         *(cd->mcodeptr++) = 0xf3;
1511         x86_64_emit_rex(0,(dreg),0,(reg));
1512         *(cd->mcodeptr++) = 0x0f;
1513         *(cd->mcodeptr++) = 0x5a;
1514         x86_64_emit_reg((dreg),(reg));
1515 }
1516
1517
1518 void x86_64_cvtsd2ss_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
1519         *(cd->mcodeptr++) = 0xf2;
1520         x86_64_emit_rex(0,(dreg),0,(reg));
1521         *(cd->mcodeptr++) = 0x0f;
1522         *(cd->mcodeptr++) = 0x5a;
1523         x86_64_emit_reg((dreg),(reg));
1524 }
1525
1526
1527 void x86_64_cvttss2siq_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
1528         *(cd->mcodeptr++) = 0xf3;
1529         x86_64_emit_rex(1,(dreg),0,(reg));
1530         *(cd->mcodeptr++) = 0x0f;
1531         *(cd->mcodeptr++) = 0x2c;
1532         x86_64_emit_reg((dreg),(reg));
1533 }
1534
1535
1536 void x86_64_cvttss2si_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
1537         *(cd->mcodeptr++) = 0xf3;
1538         x86_64_emit_rex(0,(dreg),0,(reg));
1539         *(cd->mcodeptr++) = 0x0f;
1540         *(cd->mcodeptr++) = 0x2c;
1541         x86_64_emit_reg((dreg),(reg));
1542 }
1543
1544
1545 void x86_64_cvttsd2siq_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
1546         *(cd->mcodeptr++) = 0xf2;
1547         x86_64_emit_rex(1,(dreg),0,(reg));
1548         *(cd->mcodeptr++) = 0x0f;
1549         *(cd->mcodeptr++) = 0x2c;
1550         x86_64_emit_reg((dreg),(reg));
1551 }
1552
1553
1554 void x86_64_cvttsd2si_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
1555         *(cd->mcodeptr++) = 0xf2;
1556         x86_64_emit_rex(0,(dreg),0,(reg));
1557         *(cd->mcodeptr++) = 0x0f;
1558         *(cd->mcodeptr++) = 0x2c;
1559         x86_64_emit_reg((dreg),(reg));
1560 }
1561
1562
1563 void x86_64_divss_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
1564         *(cd->mcodeptr++) = 0xf3;
1565         x86_64_emit_rex(0,(dreg),0,(reg));
1566         *(cd->mcodeptr++) = 0x0f;
1567         *(cd->mcodeptr++) = 0x5e;
1568         x86_64_emit_reg((dreg),(reg));
1569 }
1570
1571
1572 void x86_64_divsd_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
1573         *(cd->mcodeptr++) = 0xf2;
1574         x86_64_emit_rex(0,(dreg),0,(reg));
1575         *(cd->mcodeptr++) = 0x0f;
1576         *(cd->mcodeptr++) = 0x5e;
1577         x86_64_emit_reg((dreg),(reg));
1578 }
1579
1580
1581 void x86_64_movd_reg_freg(codegendata *cd, s8 reg, s8 freg) {
1582         *(cd->mcodeptr++) = 0x66;
1583         x86_64_emit_rex(1,(freg),0,(reg));
1584         *(cd->mcodeptr++) = 0x0f;
1585         *(cd->mcodeptr++) = 0x6e;
1586         x86_64_emit_reg((freg),(reg));
1587 }
1588
1589
1590 void x86_64_movd_freg_reg(codegendata *cd, s8 freg, s8 reg) {
1591         *(cd->mcodeptr++) = 0x66;
1592         x86_64_emit_rex(1,(freg),0,(reg));
1593         *(cd->mcodeptr++) = 0x0f;
1594         *(cd->mcodeptr++) = 0x7e;
1595         x86_64_emit_reg((freg),(reg));
1596 }
1597
1598
1599 void x86_64_movd_reg_membase(codegendata *cd, s8 reg, s8 basereg, s8 disp) {
1600         *(cd->mcodeptr++) = 0x66;
1601         x86_64_emit_rex(0,(reg),0,(basereg));
1602         *(cd->mcodeptr++) = 0x0f;
1603         *(cd->mcodeptr++) = 0x7e;
1604         x86_64_emit_membase((basereg),(disp),(reg));
1605 }
1606
1607
1608 void x86_64_movd_reg_memindex(codegendata *cd, s8 reg, s8 disp, s8 basereg, s8 indexreg, s8 scale) {
1609         *(cd->mcodeptr++) = 0x66;
1610         x86_64_emit_rex(0,(reg),(indexreg),(basereg));
1611         *(cd->mcodeptr++) = 0x0f;
1612         *(cd->mcodeptr++) = 0x7e;
1613         x86_64_emit_memindex((reg),(disp),(basereg),(indexreg),(scale));
1614 }
1615
1616
1617 void x86_64_movd_membase_reg(codegendata *cd, s8 basereg, s8 disp, s8 dreg) {
1618         *(cd->mcodeptr++) = 0x66;
1619         x86_64_emit_rex(1,(dreg),0,(basereg));
1620         *(cd->mcodeptr++) = 0x0f;
1621         *(cd->mcodeptr++) = 0x6e;
1622         x86_64_emit_membase((basereg),(disp),(dreg));
1623 }
1624
1625
1626 void x86_64_movdl_membase_reg(codegendata *cd, s8 basereg, s8 disp, s8 dreg) {
1627         *(cd->mcodeptr++) = 0x66;
1628         x86_64_emit_rex(0,(dreg),0,(basereg));
1629         *(cd->mcodeptr++) = 0x0f;
1630         *(cd->mcodeptr++) = 0x6e;
1631         x86_64_emit_membase((basereg),(disp),(dreg));
1632 }
1633
1634
1635 void x86_64_movd_memindex_reg(codegendata *cd, s8 disp, s8 basereg, s8 indexreg, s8 scale, s8 dreg) {
1636         *(cd->mcodeptr++) = 0x66;
1637         x86_64_emit_rex(0,(dreg),(indexreg),(basereg));
1638         *(cd->mcodeptr++) = 0x0f;
1639         *(cd->mcodeptr++) = 0x6e;
1640         x86_64_emit_memindex((dreg),(disp),(basereg),(indexreg),(scale));
1641 }
1642
1643
1644 void x86_64_movq_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
1645         *(cd->mcodeptr++) = 0xf3;
1646         x86_64_emit_rex(0,(dreg),0,(reg));
1647         *(cd->mcodeptr++) = 0x0f;
1648         *(cd->mcodeptr++) = 0x7e;
1649         x86_64_emit_reg((dreg),(reg));
1650 }
1651
1652
1653 void x86_64_movq_reg_membase(codegendata *cd, s8 reg, s8 basereg, s8 disp) {
1654         *(cd->mcodeptr++) = 0x66;
1655         x86_64_emit_rex(0,(reg),0,(basereg));
1656         *(cd->mcodeptr++) = 0x0f;
1657         *(cd->mcodeptr++) = 0xd6;
1658         x86_64_emit_membase((basereg),(disp),(reg));
1659 }
1660
1661
1662 void x86_64_movq_membase_reg(codegendata *cd, s8 basereg, s8 disp, s8 dreg) {
1663         *(cd->mcodeptr++) = 0xf3;
1664         x86_64_emit_rex(0,(dreg),0,(basereg));
1665         *(cd->mcodeptr++) = 0x0f;
1666         *(cd->mcodeptr++) = 0x7e;
1667         x86_64_emit_membase((basereg),(disp),(dreg));
1668 }
1669
1670
1671 void x86_64_movss_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
1672         *(cd->mcodeptr++) = 0xf3;
1673         x86_64_emit_rex(0,(reg),0,(dreg));
1674         *(cd->mcodeptr++) = 0x0f;
1675         *(cd->mcodeptr++) = 0x10;
1676         x86_64_emit_reg((reg),(dreg));
1677 }
1678
1679
1680 void x86_64_movsd_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
1681         *(cd->mcodeptr++) = 0xf2;
1682         x86_64_emit_rex(0,(reg),0,(dreg));
1683         *(cd->mcodeptr++) = 0x0f;
1684         *(cd->mcodeptr++) = 0x10;
1685         x86_64_emit_reg((reg),(dreg));
1686 }
1687
1688
1689 void x86_64_movss_reg_membase(codegendata *cd, s8 reg, s8 basereg, s8 disp) {
1690         *(cd->mcodeptr++) = 0xf3;
1691         x86_64_emit_rex(0,(reg),0,(basereg));
1692         *(cd->mcodeptr++) = 0x0f;
1693         *(cd->mcodeptr++) = 0x11;
1694         x86_64_emit_membase((basereg),(disp),(reg));
1695 }
1696
1697
1698 void x86_64_movsd_reg_membase(codegendata *cd, s8 reg, s8 basereg, s8 disp) {
1699         *(cd->mcodeptr++) = 0xf2;
1700         x86_64_emit_rex(0,(reg),0,(basereg));
1701         *(cd->mcodeptr++) = 0x0f;
1702         *(cd->mcodeptr++) = 0x11;
1703         x86_64_emit_membase((basereg),(disp),(reg));
1704 }
1705
1706
1707 void x86_64_movss_membase_reg(codegendata *cd, s8 basereg, s8 disp, s8 dreg) {
1708         *(cd->mcodeptr++) = 0xf3;
1709         x86_64_emit_rex(0,(dreg),0,(basereg));
1710         *(cd->mcodeptr++) = 0x0f;
1711         *(cd->mcodeptr++) = 0x10;
1712         x86_64_emit_membase((basereg),(disp),(dreg));
1713 }
1714
1715
1716 void x86_64_movlps_membase_reg(codegendata *cd, s8 basereg, s8 disp, s8 dreg) {
1717         x86_64_emit_rex(0,(dreg),0,(basereg));
1718         *(cd->mcodeptr++) = 0x0f;
1719         *(cd->mcodeptr++) = 0x12;
1720         x86_64_emit_membase((basereg),(disp),(dreg));
1721 }
1722
1723
1724 void x86_64_movsd_membase_reg(codegendata *cd, s8 basereg, s8 disp, s8 dreg) {
1725         *(cd->mcodeptr++) = 0xf2;
1726         x86_64_emit_rex(0,(dreg),0,(basereg));
1727         *(cd->mcodeptr++) = 0x0f;
1728         *(cd->mcodeptr++) = 0x10;
1729         x86_64_emit_membase((basereg),(disp),(dreg));
1730 }
1731
1732
1733 void x86_64_movlpd_membase_reg(codegendata *cd, s8 basereg, s8 disp, s8 dreg) {
1734         *(cd->mcodeptr++) = 0x66;
1735         x86_64_emit_rex(0,(dreg),0,(basereg));
1736         *(cd->mcodeptr++) = 0x0f;
1737         *(cd->mcodeptr++) = 0x12;
1738         x86_64_emit_membase((basereg),(disp),(dreg));
1739 }
1740
1741
1742 void x86_64_movss_reg_memindex(codegendata *cd, s8 reg, s8 disp, s8 basereg, s8 indexreg, s8 scale) {
1743         *(cd->mcodeptr++) = 0xf3;
1744         x86_64_emit_rex(0,(reg),(indexreg),(basereg));
1745         *(cd->mcodeptr++) = 0x0f;
1746         *(cd->mcodeptr++) = 0x11;
1747         x86_64_emit_memindex((reg),(disp),(basereg),(indexreg),(scale));
1748 }
1749
1750
1751 void x86_64_movsd_reg_memindex(codegendata *cd, s8 reg, s8 disp, s8 basereg, s8 indexreg, s8 scale) {
1752         *(cd->mcodeptr++) = 0xf2;
1753         x86_64_emit_rex(0,(reg),(indexreg),(basereg));
1754         *(cd->mcodeptr++) = 0x0f;
1755         *(cd->mcodeptr++) = 0x11;
1756         x86_64_emit_memindex((reg),(disp),(basereg),(indexreg),(scale));
1757 }
1758
1759
1760 void x86_64_movss_memindex_reg(codegendata *cd, s8 disp, s8 basereg, s8 indexreg, s8 scale, s8 dreg) {
1761         *(cd->mcodeptr++) = 0xf3;
1762         x86_64_emit_rex(0,(dreg),(indexreg),(basereg));
1763         *(cd->mcodeptr++) = 0x0f;
1764         *(cd->mcodeptr++) = 0x10;
1765         x86_64_emit_memindex((dreg),(disp),(basereg),(indexreg),(scale));
1766 }
1767
1768
1769 void x86_64_movsd_memindex_reg(codegendata *cd, s8 disp, s8 basereg, s8 indexreg, s8 scale, s8 dreg) {
1770         *(cd->mcodeptr++) = 0xf2;
1771         x86_64_emit_rex(0,(dreg),(indexreg),(basereg));
1772         *(cd->mcodeptr++) = 0x0f;
1773         *(cd->mcodeptr++) = 0x10;
1774         x86_64_emit_memindex((dreg),(disp),(basereg),(indexreg),(scale));
1775 }
1776
1777
1778 void x86_64_mulss_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
1779         *(cd->mcodeptr++) = 0xf3;
1780         x86_64_emit_rex(0,(dreg),0,(reg));
1781         *(cd->mcodeptr++) = 0x0f;
1782         *(cd->mcodeptr++) = 0x59;
1783         x86_64_emit_reg((dreg),(reg));
1784 }
1785
1786
1787 void x86_64_mulsd_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
1788         *(cd->mcodeptr++) = 0xf2;
1789         x86_64_emit_rex(0,(dreg),0,(reg));
1790         *(cd->mcodeptr++) = 0x0f;
1791         *(cd->mcodeptr++) = 0x59;
1792         x86_64_emit_reg((dreg),(reg));
1793 }
1794
1795
1796 void x86_64_subss_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
1797         *(cd->mcodeptr++) = 0xf3;
1798         x86_64_emit_rex(0,(dreg),0,(reg));
1799         *(cd->mcodeptr++) = 0x0f;
1800         *(cd->mcodeptr++) = 0x5c;
1801         x86_64_emit_reg((dreg),(reg));
1802 }
1803
1804
1805 void x86_64_subsd_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
1806         *(cd->mcodeptr++) = 0xf2;
1807         x86_64_emit_rex(0,(dreg),0,(reg));
1808         *(cd->mcodeptr++) = 0x0f;
1809         *(cd->mcodeptr++) = 0x5c;
1810         x86_64_emit_reg((dreg),(reg));
1811 }
1812
1813
1814 void x86_64_ucomiss_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
1815         x86_64_emit_rex(0,(dreg),0,(reg));
1816         *(cd->mcodeptr++) = 0x0f;
1817         *(cd->mcodeptr++) = 0x2e;
1818         x86_64_emit_reg((dreg),(reg));
1819 }
1820
1821
1822 void x86_64_ucomisd_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
1823         *(cd->mcodeptr++) = 0x66;
1824         x86_64_emit_rex(0,(dreg),0,(reg));
1825         *(cd->mcodeptr++) = 0x0f;
1826         *(cd->mcodeptr++) = 0x2e;
1827         x86_64_emit_reg((dreg),(reg));
1828 }
1829
1830
1831 void x86_64_xorps_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
1832         x86_64_emit_rex(0,(dreg),0,(reg));
1833         *(cd->mcodeptr++) = 0x0f;
1834         *(cd->mcodeptr++) = 0x57;
1835         x86_64_emit_reg((dreg),(reg));
1836 }
1837
1838
1839 void x86_64_xorps_membase_reg(codegendata *cd, s8 basereg, s8 disp, s8 dreg) {
1840         x86_64_emit_rex(0,(dreg),0,(basereg));
1841         *(cd->mcodeptr++) = 0x0f;
1842         *(cd->mcodeptr++) = 0x57;
1843         x86_64_emit_membase((basereg),(disp),(dreg));
1844 }
1845
1846
1847 void x86_64_xorpd_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
1848         *(cd->mcodeptr++) = 0x66;
1849         x86_64_emit_rex(0,(dreg),0,(reg));
1850         *(cd->mcodeptr++) = 0x0f;
1851         *(cd->mcodeptr++) = 0x57;
1852         x86_64_emit_reg((dreg),(reg));
1853 }
1854
1855
1856 void x86_64_xorpd_membase_reg(codegendata *cd, s8 basereg, s8 disp, s8 dreg) {
1857         *(cd->mcodeptr++) = 0x66;
1858         x86_64_emit_rex(0,(dreg),0,(basereg));
1859         *(cd->mcodeptr++) = 0x0f;
1860         *(cd->mcodeptr++) = 0x57;
1861         x86_64_emit_membase((basereg),(disp),(dreg));
1862 }
1863
1864
1865 /*
1866  * These are local overrides for various environment variables in Emacs.
1867  * Please do not remove this and leave it at the end of the file, where
1868  * Emacs will automagically detect them.
1869  * ---------------------------------------------------------------------
1870  * Local variables:
1871  * mode: c
1872  * indent-tabs-mode: t
1873  * c-basic-offset: 4
1874  * tab-width: 4
1875  * End:
1876  */