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