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