powerpc64 compiles
[cacao.git] / src / vm / jit / powerpc64 / emit.c
1 /* src/vm/jit/powerpc/emit.c - PowerPC code emitter functions
2
3    Copyright (C) 1996-2005, 2006 R. Grafl, A. Krall, C. Kruegel,
4    C. Oates, R. Obermaisser, M. Platter, M. Probst, S. Ring,
5    E. Steiner, C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich,
6    J. Wenninger, Institut f. Computersprachen - TU Wien
7
8    This file is part of CACAO.
9
10    This program is free software; you can redistribute it and/or
11    modify it under the terms of the GNU General Public License as
12    published by the Free Software Foundation; either version 2, or (at
13    your option) any later version.
14
15    This program is distributed in the hope that it will be useful, but
16    WITHOUT ANY WARRANTY; without even the implied warranty of
17    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
18    General Public License for more details.
19
20    You should have received a copy of the GNU General Public License
21    along with this program; if not, write to the Free Software
22    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
23    02110-1301, USA.
24
25    Contact: cacao@cacaojvm.org
26
27    Authors: Christian Thalinger
28
29    Changes:
30
31    $Id: emitfuncs.c 4398 2006-01-31 23:43:08Z twisti $
32
33 */
34
35
36 #include "config.h"
37
38 #include <assert.h>
39
40 #include "vm/types.h"
41
42 #include "md-abi.h"
43
44 #include "vm/jit/emit.h"
45 #include "vm/jit/jit.h"
46 #include "vm/jit/powerpc/codegen.h"
47
48
49 /* code generation functions **************************************************/
50
51 /* emit_load_s1 ****************************************************************
52
53    Emits a possible load of the first source operand.
54
55 *******************************************************************************/
56
57 s4 emit_load_s1(jitdata *jd, instruction *iptr, stackptr src, s4 tempreg)
58 {
59         codegendata  *cd;
60         s4            disp;
61         s4            reg;
62
63         /* get required compiler data */
64
65         cd = jd->cd;
66
67         if (src->flags & INMEMORY) {
68                 COUNT_SPILLS;
69
70                 disp = src->regoff * 4;
71
72                 if (IS_FLT_DBL_TYPE(src->type)) {
73                         if (IS_2_WORD_TYPE(src->type))
74                                 M_DLD(tempreg, REG_SP, disp);
75                         else
76                                 M_FLD(tempreg, REG_SP, disp);
77
78                 } else {
79                         if (IS_2_WORD_TYPE(src->type))
80                                 M_LLD(tempreg, REG_SP, disp);
81                         else
82                                 M_ILD(tempreg, REG_SP, disp);
83                 }
84
85                 reg = tempreg;
86         } else
87                 reg = src->regoff;
88
89         return reg;
90 }
91
92
93 /* emit_load_s2 ****************************************************************
94
95    Emits a possible load of the second source operand.
96
97 *******************************************************************************/
98
99 s4 emit_load_s2(jitdata *jd, instruction *iptr, stackptr src, s4 tempreg)
100 {
101         codegendata  *cd;
102         s4            disp;
103         s4            reg;
104
105         /* get required compiler data */
106
107         cd = jd->cd;
108
109         if (src->flags & INMEMORY) {
110                 COUNT_SPILLS;
111
112                 disp = src->regoff * 4;
113
114                 if (IS_FLT_DBL_TYPE(src->type)) {
115                         if (IS_2_WORD_TYPE(src->type))
116                                 M_DLD(tempreg, REG_SP, disp);
117                         else
118                                 M_FLD(tempreg, REG_SP, disp);
119
120                 } else {
121                         if (IS_2_WORD_TYPE(src->type))
122                                 M_LLD(tempreg, REG_SP, disp);
123                         else
124                                 M_ILD(tempreg, REG_SP, disp);
125                 }
126
127                 reg = tempreg;
128         } else
129                 reg = src->regoff;
130
131         return reg;
132 }
133
134
135 /* emit_load_s3 ****************************************************************
136
137    Emits a possible load of the third source operand.
138
139 *******************************************************************************/
140
141 s4 emit_load_s3(jitdata *jd, instruction *iptr, stackptr src, s4 tempreg)
142 {
143         codegendata  *cd;
144         s4            disp;
145         s4            reg;
146
147         /* get required compiler data */
148
149         cd = jd->cd;
150
151         if (src->flags & INMEMORY) {
152                 COUNT_SPILLS;
153
154                 disp = src->regoff * 4;
155
156                 if (IS_FLT_DBL_TYPE(src->type)) {
157                         if (IS_2_WORD_TYPE(src->type))
158                                 M_DLD(tempreg, REG_SP, disp);
159                         else
160                                 M_FLD(tempreg, REG_SP, disp);
161
162                 } else {
163                         if (IS_2_WORD_TYPE(src->type))
164                                 M_LLD(tempreg, REG_SP, disp);
165                         else
166                                 M_ILD(tempreg, REG_SP, disp);
167                 }
168
169                 reg = tempreg;
170         } else
171                 reg = src->regoff;
172
173         return reg;
174 }
175
176
177 /* emit_load_s1_low ************************************************************
178
179    Emits a possible load of the low 32-bits of the first long source
180    operand.
181
182 *******************************************************************************/
183
184 s4 emit_load_s1_low(jitdata *jd, instruction *iptr, stackptr src, s4 tempreg)
185 {
186         codegendata  *cd;
187         s4            disp;
188         s4            reg;
189
190         assert(src->type == TYPE_LNG);
191
192         /* get required compiler data */
193
194         cd = jd->cd;
195
196         if (src->flags & INMEMORY) {
197                 COUNT_SPILLS;
198
199                 disp = src->regoff * 4;
200
201                 M_ILD(tempreg, REG_SP, disp + 4);
202
203                 reg = tempreg;
204         } else
205                 reg = GET_LOW_REG(src->regoff);
206
207         return reg;
208 }
209
210
211 /* emit_load_s2_low ************************************************************
212
213    Emits a possible load of the low 32-bits of the second long source
214    operand.
215
216 *******************************************************************************/
217
218 s4 emit_load_s2_low(jitdata *jd, instruction *iptr, stackptr src, s4 tempreg)
219 {
220         codegendata  *cd;
221         s4            disp;
222         s4            reg;
223
224         assert(src->type == TYPE_LNG);
225
226         /* get required compiler data */
227
228         cd = jd->cd;
229
230         if (src->flags & INMEMORY) {
231                 COUNT_SPILLS;
232
233                 disp = src->regoff * 4;
234
235                 M_ILD(tempreg, REG_SP, disp + 4);
236
237                 reg = tempreg;
238         } else
239                 reg = GET_LOW_REG(src->regoff);
240
241         return reg;
242 }
243
244
245 /* emit_load_s3_low ************************************************************
246
247    Emits a possible load of the low 32-bits of the third long source
248    operand.
249
250 *******************************************************************************/
251
252 s4 emit_load_s3_low(jitdata *jd, instruction *iptr, stackptr src, s4 tempreg)
253 {
254         codegendata  *cd;
255         s4            disp;
256         s4            reg;
257
258         assert(src->type == TYPE_LNG);
259
260         /* get required compiler data */
261
262         cd = jd->cd;
263
264         if (src->flags & INMEMORY) {
265                 COUNT_SPILLS;
266
267                 disp = src->regoff * 4;
268
269                 M_ILD(tempreg, REG_SP, disp + 4);
270
271                 reg = tempreg;
272         } else
273                 reg = GET_LOW_REG(src->regoff);
274
275         return reg;
276 }
277
278
279 /* emit_load_s1_high ***********************************************************
280
281    Emits a possible load of the high 32-bits of the first long source
282    operand.
283
284 *******************************************************************************/
285
286 s4 emit_load_s1_high(jitdata *jd, instruction *iptr, stackptr src, s4 tempreg)
287 {
288         codegendata  *cd;
289         s4            disp;
290         s4            reg;
291
292         assert(src->type == TYPE_LNG);
293
294         /* get required compiler data */
295
296         cd = jd->cd;
297
298         if (src->flags & INMEMORY) {
299                 COUNT_SPILLS;
300
301                 disp = src->regoff * 4;
302
303                 M_ILD(tempreg, REG_SP, disp);
304
305                 reg = tempreg;
306         } else
307                 reg = GET_HIGH_REG(src->regoff);
308
309         return reg;
310 }
311
312
313 /* emit_load_s2_high ***********************************************************
314
315    Emits a possible load of the high 32-bits of the second long source
316    operand.
317
318 *******************************************************************************/
319
320 s4 emit_load_s2_high(jitdata *jd, instruction *iptr, stackptr src, s4 tempreg)
321 {
322         codegendata  *cd;
323         s4            disp;
324         s4            reg;
325
326         assert(src->type == TYPE_LNG);
327
328         /* get required compiler data */
329
330         cd = jd->cd;
331
332         if (src->flags & INMEMORY) {
333                 COUNT_SPILLS;
334
335                 disp = src->regoff * 4;
336
337                 M_ILD(tempreg, REG_SP, disp);
338
339                 reg = tempreg;
340         } else
341                 reg = GET_HIGH_REG(src->regoff);
342
343         return reg;
344 }
345
346
347 /* emit_load_s3_high ***********************************************************
348
349    Emits a possible load of the high 32-bits of the third long source
350    operand.
351
352 *******************************************************************************/
353
354 s4 emit_load_s3_high(jitdata *jd, instruction *iptr, stackptr src, s4 tempreg)
355 {
356         codegendata  *cd;
357         s4            disp;
358         s4            reg;
359
360         assert(src->type == TYPE_LNG);
361
362         /* get required compiler data */
363
364         cd = jd->cd;
365
366         if (src->flags & INMEMORY) {
367                 COUNT_SPILLS;
368
369                 disp = src->regoff * 4;
370
371                 M_ILD(tempreg, REG_SP, disp);
372
373                 reg = tempreg;
374         } else
375                 reg = GET_HIGH_REG(src->regoff);
376
377         return reg;
378 }
379
380
381 /* emit_store ******************************************************************
382
383    XXX
384
385 *******************************************************************************/
386
387 void emit_store(jitdata *jd, instruction *iptr, stackptr dst, s4 d)
388 {
389         codegendata  *cd;
390
391         /* get required compiler data */
392
393         cd = jd->cd;
394
395         if (dst->flags & INMEMORY) {
396                 COUNT_SPILLS;
397
398                 if (IS_FLT_DBL_TYPE(dst->type)) {
399                         if (IS_2_WORD_TYPE(dst->type))
400                                 M_DST(d, REG_SP, dst->regoff * 4);
401                         else
402                                 M_FST(d, REG_SP, dst->regoff * 4);
403
404                 } else {
405                         if (IS_2_WORD_TYPE(dst->type))
406                                 M_LST(d, REG_SP, dst->regoff * 4);
407                         else
408                                 M_IST(d, REG_SP, dst->regoff * 4);
409                 }
410         }
411 }
412
413
414 /* emit_copy *******************************************************************
415
416    XXX
417
418 *******************************************************************************/
419
420 void emit_copy(jitdata *jd, instruction *iptr, stackptr src, stackptr dst)
421 {
422         codegendata  *cd;
423         registerdata *rd;
424         s4            s1, d;
425
426         /* get required compiler data */
427
428         cd = jd->cd;
429         rd = jd->rd;
430
431         if (src->type == TYPE_LNG)
432                 d = codegen_reg_of_var(rd, iptr->opc, dst, PACK_REGS(REG_ITMP2, REG_ITMP1));
433         else
434                 d = codegen_reg_of_var(rd, iptr->opc, dst, REG_IFTMP);
435
436         if ((src->regoff != dst->regoff) ||
437                 ((src->flags ^ dst->flags) & INMEMORY)) {
438                 s1 = emit_load_s1(jd, iptr, src, d);
439
440                 if (s1 != d) {
441                         if (IS_FLT_DBL_TYPE(src->type))
442                                 M_FMOV(s1, d);
443                         else {
444                                 if (IS_2_WORD_TYPE(src->type)) {
445                                         M_MOV(GET_LOW_REG(s1), GET_LOW_REG(d));
446                                         M_MOV(GET_HIGH_REG(s1), GET_HIGH_REG(d));
447                 } else
448                     M_MOV(s1, d);
449                         }
450                 }
451
452                 emit_store(jd, iptr, dst, d);
453         }
454 }
455
456
457 /* emit_iconst *****************************************************************
458
459    XXX
460
461 *******************************************************************************/
462
463 void emit_iconst(codegendata *cd, s4 d, s4 value)
464 {
465         s4 disp;
466
467         if ((value >= -32768) && (value <= 32767))
468                 M_LDA_INTERN(d, REG_ZERO, value);
469         else {
470                 disp = dseg_adds4(cd, value);
471                 M_ILD(d, REG_PV, disp);
472         }
473 }
474
475
476 /*
477  * These are local overrides for various environment variables in Emacs.
478  * Please do not remove this and leave it at the end of the file, where
479  * Emacs will automagically detect them.
480  * ---------------------------------------------------------------------
481  * Local variables:
482  * mode: c
483  * indent-tabs-mode: t
484  * c-basic-offset: 4
485  * tab-width: 4
486  * End:
487  * vim:noexpandtab:sw=4:ts=4:
488  */