Merged branch subtype-trunk into default.
[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.h"
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_GT:
484                         M_BLE(1);
485                         break;
486                 default:
487                         vm_abort("emit_classcast_check: unknown condition %d", condition);
488                 }
489                 M_ALD_INTERN(s1, REG_ZERO, TRAP_ClassCastException);
490         }
491 }
492
493
494 /* emit_nullpointer_check ******************************************************
495
496    Emit a NullPointerException check.
497
498 *******************************************************************************/
499
500 void emit_nullpointer_check(codegendata *cd, instruction *iptr, s4 reg)
501 {
502         if (INSTRUCTION_MUST_CHECK(iptr)) {
503                 M_TST(reg);
504                 M_BNE(1);
505                 M_ALD_INTERN(REG_ZERO, REG_ZERO, TRAP_NullPointerException);
506         }
507 }
508
509
510 /* emit_exception_check ********************************************************
511
512    Emit an Exception check.
513
514 *******************************************************************************/
515
516 void emit_exception_check(codegendata *cd, instruction *iptr)
517 {
518         if (INSTRUCTION_MUST_CHECK(iptr)) {
519                 M_TST(REG_RESULT);
520                 M_BNE(1);
521                 M_ALD_INTERN(REG_ZERO, REG_ZERO, TRAP_CHECK_EXCEPTION);
522         }
523 }
524
525
526 /* emit_trap_compiler **********************************************************
527
528    Emit a trap instruction which calls the JIT compiler.
529
530 *******************************************************************************/
531
532 void emit_trap_compiler(codegendata *cd)
533 {
534         M_ALD_INTERN(REG_METHODPTR, REG_ZERO, TRAP_COMPILER);
535 }
536
537
538 /* emit_trap *******************************************************************
539
540    Emit a trap instruction and return the original machine code.
541
542 *******************************************************************************/
543
544 uint32_t emit_trap(codegendata *cd)
545 {
546         // Get machine code which is patched back in later. The rap is 1
547         // instruction word long.
548         uint32_t mcode = *((uint32_t*) cd->mcodeptr);
549
550         M_ILLEGAL;
551
552         return mcode;
553 }
554
555
556 /* emit_verbosecall_enter ******************************************************
557
558    Generates the code for the call trace.
559
560 *******************************************************************************/
561
562 void emit_verbosecall_enter(jitdata *jd)
563 {
564 #if !defined(NDEBUG)
565         methodinfo   *m;
566         codegendata  *cd;
567         registerdata *rd;
568         methoddesc   *md;
569         int32_t       disp;
570         int32_t       i;
571         int32_t       s, d;
572
573         if (!JITDATA_HAS_FLAG_VERBOSECALL(jd))
574                 return;
575
576         /* get required compiler data */
577
578         m  = jd->m;
579         cd = jd->cd;
580         rd = jd->rd;
581
582         md = m->parseddesc;
583
584         /* mark trace code */
585
586         M_NOP;
587
588         /* On Darwin we need to allocate an additional 3*4 bytes of stack
589            for the arguments to trace_java_call_enter, we make it 2*8. */
590
591         M_MFLR(REG_ZERO);
592         M_AST(REG_ZERO, REG_SP, LA_LR_OFFSET);
593         M_STWU(REG_SP, REG_SP, -(LA_SIZE + (2 + ARG_CNT + TMP_CNT) * 8));
594
595         /* save argument registers */
596
597         for (i = 0; i < md->paramcount; i++) {
598                 if (!md->params[i].inmemory) {
599                         s = md->params[i].regoff;
600                         d = LA_SIZE + (i + 2) * 8;
601
602                         switch (md->paramtypes[i].type) {
603                         case TYPE_INT:
604                         case TYPE_ADR:
605                                 M_IST(s, REG_SP, d);
606                                 break;
607                         case TYPE_LNG:
608                                 M_LST(s, REG_SP, d);
609                                 break;
610                         case TYPE_FLT:
611                                 M_FST(s, REG_SP, d);
612                                 break;
613                         case TYPE_DBL:
614                                 M_DST(s, REG_SP, d);
615                                 break;
616                         }
617                 }
618         }
619
620         /* pass methodinfo and pointers to the tracer function */
621
622         disp = dseg_add_address(cd, m);
623         M_ALD(REG_A0, REG_PV, disp);
624         M_AADD_IMM(REG_SP, LA_SIZE + 2 * 8, REG_A1);
625         M_AADD_IMM(REG_SP, LA_SIZE + (2 + ARG_CNT + TMP_CNT + cd->stackframesize) * 8, REG_A2);
626         
627         disp = dseg_add_functionptr(cd, trace_java_call_enter);
628         M_ALD(REG_ITMP2, REG_PV, disp);
629         M_MTCTR(REG_ITMP2);
630         M_JSR;
631
632         /* restore argument registers */
633
634         for (i = 0; i < md->paramcount; i++) {
635                 if (!md->params[i].inmemory) {
636                         s = LA_SIZE + (i + 2) * 8;
637                         d = md->params[i].regoff;
638
639                         switch (md->paramtypes[i].type) {
640                         case TYPE_INT:
641                         case TYPE_ADR:
642                                 M_ILD(d, REG_SP, s);
643                                 break;
644                         case TYPE_LNG:
645                                 M_LLD(d, REG_SP, s);
646                                 break;
647                         case TYPE_FLT:
648                                 M_FLD(d, REG_SP, s);
649                                 break;
650                         case TYPE_DBL:
651                                 M_DLD(d, REG_SP, s);
652                                 break;
653                         }
654                 }
655         }
656
657         M_ALD(REG_ZERO, REG_SP, LA_SIZE + (2 + ARG_CNT + TMP_CNT) * 8 + LA_LR_OFFSET);
658         M_MTLR(REG_ZERO);
659         M_LDA(REG_SP, REG_SP, LA_SIZE + (2 + ARG_CNT + TMP_CNT) * 8);
660
661         /* mark trace code */
662
663         M_NOP;
664 #endif /* !defined(NDEBUG) */
665 }
666
667
668 /* emit_verbosecall_exit *******************************************************
669
670    Generates the code for the call trace.
671
672 *******************************************************************************/
673
674 void emit_verbosecall_exit(jitdata *jd)
675 {
676 #if !defined(NDEBUG)
677         methodinfo   *m;
678         codegendata  *cd;
679         registerdata *rd;
680         methoddesc   *md;
681         s4            disp;
682
683         if (!JITDATA_HAS_FLAG_VERBOSECALL(jd))
684                 return;
685
686         /* get required compiler data */
687
688         m  = jd->m;
689         cd = jd->cd;
690         rd = jd->rd;
691
692         md = m->parseddesc;
693         
694         /* mark trace code */
695
696         M_NOP;
697
698         /* On Darwin we need to allocate an additional 2*4 bytes of stack
699            for the arguments to trace_java_call_exit, we make it 1*8. */
700
701         M_MFLR(REG_ZERO);
702         M_AST(REG_ZERO, REG_SP, LA_LR_OFFSET);
703         M_STWU(REG_SP, REG_SP, -(LA_SIZE + (1 + 1) * 8));
704
705         /* save return value */
706
707         switch (md->returntype.type) {
708         case TYPE_INT:
709         case TYPE_ADR:
710                 M_IST(REG_RESULT, REG_SP, LA_SIZE + 1 * 8);
711                 break;
712         case TYPE_LNG:
713                 M_LST(REG_RESULT_PACKED, REG_SP, LA_SIZE + 1 * 8);
714                 break;
715         case TYPE_FLT:
716                 M_FST(REG_FRESULT, REG_SP, LA_SIZE + 1 * 8);
717                 break;
718         case TYPE_DBL:
719                 M_DST(REG_FRESULT, REG_SP, LA_SIZE + 1 * 8);
720                 break;
721         case TYPE_VOID:
722                 break;
723         }
724
725         disp = dseg_add_address(cd, m);
726         M_ALD(REG_A0, REG_PV, disp);
727         M_AADD_IMM(REG_SP, LA_SIZE + 1 * 8, REG_A1);
728
729         disp = dseg_add_functionptr(cd, trace_java_call_exit);
730         M_ALD(REG_ITMP2, REG_PV, disp);
731         M_MTCTR(REG_ITMP2);
732         M_JSR;
733
734         /* restore return value */
735
736         switch (md->returntype.type) {
737         case TYPE_INT:
738         case TYPE_ADR:
739                 M_ILD(REG_RESULT, REG_SP, LA_SIZE + 1 * 8);
740                 break;
741         case TYPE_LNG:
742                 M_LLD(REG_RESULT_PACKED, REG_SP, LA_SIZE + 1 * 8);
743                 break;
744         case TYPE_FLT:
745                 M_FLD(REG_FRESULT, REG_SP, LA_SIZE + 1 * 8);
746                 break;
747         case TYPE_DBL:
748                 M_DLD(REG_FRESULT, REG_SP, LA_SIZE + 1 * 8);
749                 break;
750         case TYPE_VOID:
751                 break;
752         }
753
754         M_ALD(REG_ZERO, REG_SP, LA_SIZE + (1 + 1) * 8 + LA_LR_OFFSET);
755         M_MTLR(REG_ZERO);
756         M_LDA(REG_SP, REG_SP, LA_SIZE + (1 + 1) * 8);
757
758         /* mark trace code */
759
760         M_NOP;
761 #endif /* !defined(NDEBUG) */
762 }
763
764
765 /*
766  * These are local overrides for various environment variables in Emacs.
767  * Please do not remove this and leave it at the end of the file, where
768  * Emacs will automagically detect them.
769  * ---------------------------------------------------------------------
770  * Local variables:
771  * mode: c
772  * indent-tabs-mode: t
773  * c-basic-offset: 4
774  * tab-width: 4
775  * End:
776  * vim:noexpandtab:sw=4:ts=4:
777  */