* Merged with 269162803388.
[cacao.git] / src / vm / jit / powerpc / emit.c
1 /* src/vm/jit/powerpc/emit.c - PowerPC code emitter functions
2
3    Copyright (C) 1996-2005, 2006, 2007 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 */
26
27
28 #include "config.h"
29
30 #include <assert.h>
31 #include <stdint.h>
32
33 #include "vm/types.h"
34
35 #include "md-abi.h"
36
37 #include "vm/jit/powerpc/codegen.h"
38
39 #include "mm/memory.h"
40
41 #include "threads/lock-common.h"
42
43 #include "vm/builtin.h"
44 #include "vm/exceptions.h"
45
46 #include "vm/jit/abi.h"
47 #include "vm/jit/asmpart.h"
48 #include "vm/jit/codegen-common.h"
49 #include "vm/jit/dseg.h"
50 #include "vm/jit/emit-common.h"
51 #include "vm/jit/jit.h"
52 #include "vm/jit/replace.h"
53 #include "vm/jit/trace.h"
54
55 #include "vmcore/options.h"
56
57
58 /* emit_load *******************************************************************
59
60    Emits a possible load of an operand.
61
62 *******************************************************************************/
63
64 s4 emit_load(jitdata *jd, instruction *iptr, varinfo *src, s4 tempreg)
65 {
66         codegendata *cd;
67         s4           disp;
68         s4           reg;
69
70         /* get required compiler data */
71
72         cd = jd->cd;
73
74         if (IS_INMEMORY(src->flags)) {
75                 COUNT_SPILLS;
76
77                 disp = src->vv.regoff;
78
79                 switch (src->type) {
80                 case TYPE_INT:
81                 case TYPE_ADR:
82                         M_ILD(tempreg, REG_SP, disp);
83                         break;
84                 case TYPE_LNG:
85                         M_LLD(tempreg, REG_SP, disp);
86                         break;
87                 case TYPE_FLT:
88                 case TYPE_DBL:
89                         M_DLD(tempreg, REG_SP, disp);
90                         break;
91                 default:
92                         vm_abort("emit_load: unknown type %d", src->type);
93                 }
94
95                 reg = tempreg;
96         }
97         else
98                 reg = src->vv.regoff;
99
100         return reg;
101 }
102
103
104 /* emit_load_low ***************************************************************
105
106    Emits a possible load of the low 32-bits of an operand.
107
108 *******************************************************************************/
109
110 s4 emit_load_low(jitdata *jd, instruction *iptr, varinfo *src, s4 tempreg)
111 {
112         codegendata  *cd;
113         s4            disp;
114         s4            reg;
115
116         assert(src->type == TYPE_LNG);
117
118         /* get required compiler data */
119
120         cd = jd->cd;
121
122         if (IS_INMEMORY(src->flags)) {
123                 COUNT_SPILLS;
124
125                 disp = src->vv.regoff;
126
127                 M_ILD(tempreg, REG_SP, disp + 4);
128
129                 reg = tempreg;
130         }
131         else
132                 reg = GET_LOW_REG(src->vv.regoff);
133
134         return reg;
135 }
136
137
138 /* emit_load_high **************************************************************
139
140    Emits a possible load of the high 32-bits of an operand.
141
142 *******************************************************************************/
143
144 s4 emit_load_high(jitdata *jd, instruction *iptr, varinfo *src, s4 tempreg)
145 {
146         codegendata  *cd;
147         s4            disp;
148         s4            reg;
149
150         assert(src->type == TYPE_LNG);
151
152         /* get required compiler data */
153
154         cd = jd->cd;
155
156         if (IS_INMEMORY(src->flags)) {
157                 COUNT_SPILLS;
158
159                 disp = src->vv.regoff;
160
161                 M_ILD(tempreg, REG_SP, disp);
162
163                 reg = tempreg;
164         }
165         else
166                 reg = GET_HIGH_REG(src->vv.regoff);
167
168         return reg;
169 }
170
171
172 /* emit_store ******************************************************************
173
174    Emit a possible store for the given variable.
175
176 *******************************************************************************/
177
178 void emit_store(jitdata *jd, instruction *iptr, varinfo *dst, s4 d)
179 {
180         codegendata *cd;
181         s4           disp;
182
183         /* get required compiler data */
184
185         cd = jd->cd;
186
187         if (IS_INMEMORY(dst->flags)) {
188                 COUNT_SPILLS;
189
190                 disp = dst->vv.regoff;
191
192                 switch (dst->type) {
193                 case TYPE_INT:
194                 case TYPE_ADR:
195                         M_IST(d, REG_SP, disp);
196                         break;
197                 case TYPE_LNG:
198                         M_LST(d, REG_SP, disp);
199                         break;
200                 case TYPE_FLT:
201                 case TYPE_DBL:
202                         M_DST(d, REG_SP, disp);
203                         break;
204                 default:
205                         vm_abort("emit_store: unknown type %d", dst->type);
206                 }
207         }
208 }
209
210
211 /* emit_copy *******************************************************************
212
213    Generates a register/memory to register/memory copy.
214
215 *******************************************************************************/
216
217 void emit_copy(jitdata *jd, instruction *iptr)
218 {
219         codegendata *cd;
220         varinfo     *src;
221         varinfo     *dst;
222         s4           s1, d;
223
224         /* get required compiler data */
225
226         cd = jd->cd;
227
228         /* get source and destination variables */
229
230         src = VAROP(iptr->s1);
231         dst = VAROP(iptr->dst);
232
233         if ((src->vv.regoff != dst->vv.regoff) ||
234                 (IS_INMEMORY(src->flags ^ dst->flags))) {
235
236                 if ((src->type == TYPE_RET) || (dst->type == TYPE_RET)) {
237                         /* emit nothing, as the value won't be used anyway */
238                         return;
239                 }
240
241                 /* If one of the variables resides in memory, we can eliminate
242                    the register move from/to the temporary register with the
243                    order of getting the destination register and the load. */
244
245                 if (IS_INMEMORY(src->flags)) {
246                         if (IS_LNG_TYPE(src->type))
247                                 d = codegen_reg_of_var(iptr->opc, dst, REG_ITMP12_PACKED);
248                         else
249                                 d = codegen_reg_of_var(iptr->opc, dst, REG_IFTMP);
250
251                         s1 = emit_load(jd, iptr, src, d);
252                 }
253                 else {
254                         if (IS_LNG_TYPE(src->type))
255                                 s1 = emit_load(jd, iptr, src, REG_ITMP12_PACKED);
256                         else
257                                 s1 = emit_load(jd, iptr, src, REG_IFTMP);
258
259                         d = codegen_reg_of_var(iptr->opc, dst, s1);
260                 }
261
262                 if (s1 != d) {
263                         switch (src->type) {
264                         case TYPE_INT:
265                         case TYPE_ADR:
266                                 M_MOV(s1, d);
267                                 break;
268                         case TYPE_LNG:
269                                 M_MOV(GET_LOW_REG(s1), GET_LOW_REG(d));
270                                 M_MOV(GET_HIGH_REG(s1), GET_HIGH_REG(d));
271                                 break;
272                         case TYPE_FLT:
273                         case TYPE_DBL:
274                                 M_FMOV(s1, d);
275                                 break;
276                         default:
277                                 vm_abort("emit_copy: unknown type %d", src->type);
278                         }
279                 }
280
281                 emit_store(jd, iptr, dst, d);
282         }
283 }
284
285
286 /* emit_iconst *****************************************************************
287
288    XXX
289
290 *******************************************************************************/
291
292 void emit_iconst(codegendata *cd, s4 d, s4 value)
293 {
294         s4 disp;
295
296         if ((value >= -32768) && (value <= 32767))
297                 M_LDA_INTERN(d, REG_ZERO, value);
298         else {
299                 disp = dseg_add_s4(cd, value);
300                 M_ILD(d, REG_PV, disp);
301         }
302 }
303
304
305 /* emit_branch *****************************************************************
306
307    Emits the code for conditional and unconditional branchs.
308
309 *******************************************************************************/
310
311 void emit_branch(codegendata *cd, s4 disp, s4 condition, s4 reg, u4 opt)
312 {
313         s4 checkdisp;
314         s4 branchdisp;
315
316         /* calculate the different displacements */
317
318         checkdisp  =  disp + 4;
319         branchdisp = (disp - 4) >> 2;
320
321         /* check which branch to generate */
322
323         if (condition == BRANCH_UNCONDITIONAL) {
324                 /* check displacement for overflow */
325
326                 if ((checkdisp < (s4) 0xfe000000) || (checkdisp > (s4) 0x01fffffc)) {
327                         /* if the long-branches flag isn't set yet, do it */
328
329                         if (!CODEGENDATA_HAS_FLAG_LONGBRANCHES(cd)) {
330                                 cd->flags |= (CODEGENDATA_FLAG_ERROR |
331                                                           CODEGENDATA_FLAG_LONGBRANCHES);
332                         }
333
334                         vm_abort("emit_branch: emit unconditional long-branch code");
335                 }
336                 else {
337                         M_BR(branchdisp);
338                 }
339         }
340         else {
341                 /* and displacement for overflow */
342
343                 if ((checkdisp < (s4) 0xffff8000) || (checkdisp > (s4) 0x00007fff)) {
344                         /* if the long-branches flag isn't set yet, do it */
345
346                         if (!CODEGENDATA_HAS_FLAG_LONGBRANCHES(cd)) {
347                                 cd->flags |= (CODEGENDATA_FLAG_ERROR |
348                                                           CODEGENDATA_FLAG_LONGBRANCHES);
349                         }
350
351                         switch (condition) {
352                         case BRANCH_EQ:
353                                 M_BNE(1);
354                                 M_BR(branchdisp);
355                                 break;
356                         case BRANCH_NE:
357                                 M_BEQ(1);
358                                 M_BR(branchdisp);
359                                 break;
360                         case BRANCH_LT:
361                                 M_BGE(1);
362                                 M_BR(branchdisp);
363                                 break;
364                         case BRANCH_GE:
365                                 M_BLT(1);
366                                 M_BR(branchdisp);
367                                 break;
368                         case BRANCH_GT:
369                                 M_BLE(1);
370                                 M_BR(branchdisp);
371                                 break;
372                         case BRANCH_LE:
373                                 M_BGT(1);
374                                 M_BR(branchdisp);
375                                 break;
376                         case BRANCH_NAN:
377                                 vm_abort("emit_branch: long BRANCH_NAN");
378                                 break;
379                         default:
380                                 vm_abort("emit_branch: unknown condition %d", condition);
381                         }
382                 }
383                 else {
384                         switch (condition) {
385                         case BRANCH_EQ:
386                                 M_BEQ(branchdisp);
387                                 break;
388                         case BRANCH_NE:
389                                 M_BNE(branchdisp);
390                                 break;
391                         case BRANCH_LT:
392                                 M_BLT(branchdisp);
393                                 break;
394                         case BRANCH_GE:
395                                 M_BGE(branchdisp);
396                                 break;
397                         case BRANCH_GT:
398                                 M_BGT(branchdisp);
399                                 break;
400                         case BRANCH_LE:
401                                 M_BLE(branchdisp);
402                                 break;
403                         case BRANCH_NAN:
404                                 M_BNAN(branchdisp);
405                                 break;
406                         default:
407                                 vm_abort("emit_branch: unknown condition %d", condition);
408                         }
409                 }
410         }
411 }
412
413
414 /* emit_arithmetic_check *******************************************************
415
416    Emit an ArithmeticException check.
417
418 *******************************************************************************/
419
420 void emit_arithmetic_check(codegendata *cd, instruction *iptr, s4 reg)
421 {
422         if (INSTRUCTION_MUST_CHECK(iptr)) {
423                 M_TST(reg);
424                 M_BNE(1);
425                 M_ALD_INTERN(REG_ZERO, REG_ZERO, EXCEPTION_HARDWARE_ARITHMETIC);
426         }
427 }
428
429
430 /* emit_arrayindexoutofbounds_check ********************************************
431
432    Emit a ArrayIndexOutOfBoundsException check.
433
434 *******************************************************************************/
435
436 void emit_arrayindexoutofbounds_check(codegendata *cd, instruction *iptr, s4 s1, s4 s2)
437 {
438         if (INSTRUCTION_MUST_CHECK(iptr)) {
439                 M_ILD(REG_ITMP3, s1, OFFSET(java_array_t, size));
440                 M_TRAPGEU(s2, REG_ITMP3);
441         }
442 }
443
444
445 /* emit_arraystore_check *******************************************************
446
447    Emit an ArrayStoreException check.
448
449 *******************************************************************************/
450
451 void emit_arraystore_check(codegendata *cd, instruction *iptr)
452 {
453         if (INSTRUCTION_MUST_CHECK(iptr)) {
454                 M_TST(REG_RESULT);
455                 M_BNE(1);
456                 M_ALD_INTERN(REG_ZERO, REG_ZERO, EXCEPTION_HARDWARE_ARRAYSTORE);
457         }
458 }
459
460
461 /* emit_classcast_check ********************************************************
462
463    Emit a ClassCastException check.
464
465 *******************************************************************************/
466
467 void emit_classcast_check(codegendata *cd, instruction *iptr, s4 condition, s4 reg, s4 s1)
468 {
469         if (INSTRUCTION_MUST_CHECK(iptr)) {
470                 switch (condition) {
471                 case BRANCH_LE:
472                         M_BGT(1);
473                         break;
474                 case BRANCH_EQ:
475                         M_BNE(1);
476                         break;
477                 case BRANCH_GT:
478                         M_BLE(1);
479                         break;
480                 default:
481                         vm_abort("emit_classcast_check: unknown condition %d", condition);
482                 }
483                 M_ALD_INTERN(s1, REG_ZERO, EXCEPTION_HARDWARE_CLASSCAST);
484         }
485 }
486
487
488 /* emit_nullpointer_check ******************************************************
489
490    Emit a NullPointerException check.
491
492 *******************************************************************************/
493
494 void emit_nullpointer_check(codegendata *cd, instruction *iptr, s4 reg)
495 {
496         if (INSTRUCTION_MUST_CHECK(iptr)) {
497                 M_TST(reg);
498                 M_BNE(1);
499                 M_ALD_INTERN(REG_ZERO, REG_ZERO, EXCEPTION_HARDWARE_NULLPOINTER);
500         }
501 }
502
503
504 /* emit_exception_check ********************************************************
505
506    Emit an Exception check.
507
508 *******************************************************************************/
509
510 void emit_exception_check(codegendata *cd, instruction *iptr)
511 {
512         if (INSTRUCTION_MUST_CHECK(iptr)) {
513                 M_TST(REG_RESULT);
514                 M_BNE(1);
515                 M_ALD_INTERN(REG_ZERO, REG_ZERO, EXCEPTION_HARDWARE_EXCEPTION);
516         }
517 }
518
519
520 /* emit_trap *******************************************************************
521
522    Emit a trap instruction and return the original machine code.
523
524 *******************************************************************************/
525
526 uint32_t emit_trap(codegendata *cd)
527 {
528         uint32_t mcode;
529
530         /* Get machine code which is patched back in later. The
531            trap is 1 instruction word long. */
532
533         mcode = *((u4 *) cd->mcodeptr);
534
535         M_ALD_INTERN(REG_ZERO, REG_ZERO, EXCEPTION_HARDWARE_PATCHER);
536
537         return mcode;
538 }
539
540
541 /* emit_verbosecall_enter ******************************************************
542
543    Generates the code for the call trace.
544
545 *******************************************************************************/
546
547 void emit_verbosecall_enter(jitdata *jd)
548 {
549 #if !defined(NDEBUG)
550         methodinfo   *m;
551         codegendata  *cd;
552         registerdata *rd;
553         methoddesc   *md;
554         int32_t       disp;
555         int32_t       i;
556         int32_t       s, d;
557
558         if (!JITDATA_HAS_FLAG_VERBOSECALL(jd))
559                 return;
560
561         /* get required compiler data */
562
563         m  = jd->m;
564         cd = jd->cd;
565         rd = jd->rd;
566
567         md = m->parseddesc;
568
569         /* mark trace code */
570
571         M_NOP;
572
573         /* On Darwin we need to allocate an additional 3*4 bytes of stack
574            for the arguments to trace_java_call_enter, we make it 2*8. */
575
576         M_MFLR(REG_ZERO);
577         M_AST(REG_ZERO, REG_SP, LA_LR_OFFSET);
578         M_STWU(REG_SP, REG_SP, -(LA_SIZE + (2 + ARG_CNT + TMP_CNT) * 8));
579
580         /* save argument registers */
581
582         for (i = 0; i < md->paramcount; i++) {
583                 if (!md->params[i].inmemory) {
584                         s = md->params[i].regoff;
585                         d = LA_SIZE + (i + 2) * 8;
586
587                         switch (md->paramtypes[i].type) {
588                         case TYPE_INT:
589                         case TYPE_ADR:
590                                 M_IST(s, REG_SP, d);
591                                 break;
592                         case TYPE_LNG:
593                                 M_LST(s, REG_SP, d);
594                                 break;
595                         case TYPE_FLT:
596                                 M_FST(s, REG_SP, d);
597                                 break;
598                         case TYPE_DBL:
599                                 M_DST(s, REG_SP, d);
600                                 break;
601                         }
602                 }
603         }
604
605         /* pass methodinfo and pointers to the tracer function */
606
607         disp = dseg_add_address(cd, m);
608         M_ALD(REG_A0, REG_PV, disp);
609         M_AADD_IMM(REG_SP, LA_SIZE + 2 * 8, REG_A1);
610         M_AADD_IMM(REG_SP, LA_SIZE + (2 + ARG_CNT + TMP_CNT + cd->stackframesize) * 8, REG_A2);
611         
612         disp = dseg_add_functionptr(cd, trace_java_call_enter);
613         M_ALD(REG_ITMP2, REG_PV, disp);
614         M_MTCTR(REG_ITMP2);
615         M_JSR;
616
617         /* restore argument registers */
618
619         for (i = 0; i < md->paramcount; i++) {
620                 if (!md->params[i].inmemory) {
621                         s = LA_SIZE + (i + 2) * 8;
622                         d = md->params[i].regoff;
623
624                         switch (md->paramtypes[i].type) {
625                         case TYPE_INT:
626                         case TYPE_ADR:
627                                 M_ILD(d, REG_SP, s);
628                                 break;
629                         case TYPE_LNG:
630                                 M_LLD(d, REG_SP, s);
631                                 break;
632                         case TYPE_FLT:
633                                 M_FLD(d, REG_SP, s);
634                                 break;
635                         case TYPE_DBL:
636                                 M_DLD(d, REG_SP, s);
637                                 break;
638                         }
639                 }
640         }
641
642         M_ALD(REG_ZERO, REG_SP, LA_SIZE + (2 + ARG_CNT + TMP_CNT) * 8 + LA_LR_OFFSET);
643         M_MTLR(REG_ZERO);
644         M_LDA(REG_SP, REG_SP, LA_SIZE + (2 + ARG_CNT + TMP_CNT) * 8);
645
646         /* mark trace code */
647
648         M_NOP;
649 #endif /* !defined(NDEBUG) */
650 }
651
652
653 /* emit_verbosecall_exit *******************************************************
654
655    Generates the code for the call trace.
656
657    void builtin_verbosecall_exit(s8 l, double d, float f, methodinfo *m);
658
659 *******************************************************************************/
660
661 void emit_verbosecall_exit(jitdata *jd)
662 {
663 #if !defined(NDEBUG)
664         methodinfo   *m;
665         codegendata  *cd;
666         registerdata *rd;
667         methoddesc   *md;
668         s4            disp;
669
670         if (!JITDATA_HAS_FLAG_VERBOSECALL(jd))
671                 return;
672
673         /* get required compiler data */
674
675         m  = jd->m;
676         cd = jd->cd;
677         rd = jd->rd;
678
679         md = m->parseddesc;
680         
681         /* mark trace code */
682
683         M_NOP;
684
685         /* On Darwin we need to allocate an additional 2*4 bytes of stack
686            for the arguments to trace_java_call_exit, we make it 1*8. */
687
688         M_MFLR(REG_ZERO);
689         M_AST(REG_ZERO, REG_SP, LA_LR_OFFSET);
690         M_STWU(REG_SP, REG_SP, -(LA_SIZE + (1 + 1) * 8));
691
692         /* save return value */
693
694         switch (md->returntype.type) {
695         case TYPE_INT:
696         case TYPE_ADR:
697                 M_IST(REG_RESULT, REG_SP, LA_SIZE + 1 * 8);
698                 break;
699         case TYPE_LNG:
700                 M_LST(REG_RESULT_PACKED, REG_SP, LA_SIZE + 1 * 8);
701                 break;
702         case TYPE_FLT:
703                 M_FST(REG_FRESULT, REG_SP, LA_SIZE + 1 * 8);
704                 break;
705         case TYPE_DBL:
706                 M_DST(REG_FRESULT, REG_SP, LA_SIZE + 1 * 8);
707                 break;
708         case TYPE_VOID:
709                 break;
710         }
711
712         disp = dseg_add_address(cd, m);
713         M_ALD(REG_A0, REG_PV, disp);
714         M_AADD_IMM(REG_SP, LA_SIZE + 1 * 8, REG_A1);
715
716         disp = dseg_add_functionptr(cd, trace_java_call_exit);
717         M_ALD(REG_ITMP2, REG_PV, disp);
718         M_MTCTR(REG_ITMP2);
719         M_JSR;
720
721         /* restore return value */
722
723         switch (md->returntype.type) {
724         case TYPE_INT:
725         case TYPE_ADR:
726                 M_ILD(REG_RESULT, REG_SP, LA_SIZE + 1 * 8);
727                 break;
728         case TYPE_LNG:
729                 M_LLD(REG_RESULT_PACKED, REG_SP, LA_SIZE + 1 * 8);
730                 break;
731         case TYPE_FLT:
732                 M_FLD(REG_FRESULT, REG_SP, LA_SIZE + 1 * 8);
733                 break;
734         case TYPE_DBL:
735                 M_DLD(REG_FRESULT, REG_SP, LA_SIZE + 1 * 8);
736                 break;
737         case TYPE_VOID:
738                 break;
739         }
740
741         M_ALD(REG_ZERO, REG_SP, LA_SIZE + (1 + 1) * 8 + LA_LR_OFFSET);
742         M_MTLR(REG_ZERO);
743         M_LDA(REG_SP, REG_SP, LA_SIZE + (1 + 1) * 8);
744
745         /* mark trace code */
746
747         M_NOP;
748 #endif /* !defined(NDEBUG) */
749 }
750
751
752 /*
753  * These are local overrides for various environment variables in Emacs.
754  * Please do not remove this and leave it at the end of the file, where
755  * Emacs will automagically detect them.
756  * ---------------------------------------------------------------------
757  * Local variables:
758  * mode: c
759  * indent-tabs-mode: t
760  * c-basic-offset: 4
761  * tab-width: 4
762  * End:
763  * vim:noexpandtab:sw=4:ts=4:
764  */