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