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