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