* src/vm/jit/codegen-common.cpp (codegen_emit): New generic version of the
[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 /**
302  * Emits code updating the condition register by comparing one integer
303  * register to an immediate integer value.
304  */
305 void emit_icmp_imm(codegendata* cd, int reg, int32_t value)
306 {
307         int32_t disp;
308
309         if ((value >= -32768) && (value <= 32767)) {
310                 M_CMPI(reg, value);
311         }
312         else {
313                 assert(reg != REG_ITMP2);
314                 disp = dseg_add_s4(cd, value);
315                 M_ILD(REG_ITMP2, REG_PV, disp);
316                 M_CMP(reg, REG_ITMP2);
317         }
318 }
319
320
321 /* emit_branch *****************************************************************
322
323    Emits the code for conditional and unconditional branchs.
324
325 *******************************************************************************/
326
327 void emit_branch(codegendata *cd, s4 disp, s4 condition, s4 reg, u4 opt)
328 {
329         s4 checkdisp;
330         s4 branchdisp;
331
332         /* calculate the different displacements */
333
334         checkdisp  =  disp + 4;
335         branchdisp = (disp - 4) >> 2;
336
337         /* check which branch to generate */
338
339         if (condition == BRANCH_UNCONDITIONAL) {
340                 /* check displacement for overflow */
341
342                 if ((checkdisp < (s4) 0xfe000000) || (checkdisp > (s4) 0x01fffffc)) {
343                         /* if the long-branches flag isn't set yet, do it */
344
345                         if (!CODEGENDATA_HAS_FLAG_LONGBRANCHES(cd)) {
346                                 cd->flags |= (CODEGENDATA_FLAG_ERROR |
347                                                           CODEGENDATA_FLAG_LONGBRANCHES);
348                         }
349
350                         vm_abort("emit_branch: emit unconditional long-branch code");
351                 }
352                 else {
353                         M_BR(branchdisp);
354                 }
355         }
356         else {
357                 /* and displacement for overflow */
358
359                 if ((checkdisp < (s4) 0xffff8000) || (checkdisp > (s4) 0x00007fff)) {
360                         /* if the long-branches flag isn't set yet, do it */
361
362                         if (!CODEGENDATA_HAS_FLAG_LONGBRANCHES(cd)) {
363                                 cd->flags |= (CODEGENDATA_FLAG_ERROR |
364                                                           CODEGENDATA_FLAG_LONGBRANCHES);
365                         }
366
367                         // Subtract 1 instruction from the displacement as the
368                         // actual branch is the second instruction.
369                         checkdisp  = checkdisp - 4;
370                         branchdisp = branchdisp - 1;
371
372                         if ((checkdisp < (int32_t) 0xfe000000) || (checkdisp > (int32_t) 0x01fffffc)) {
373                                 vm_abort("emit_branch: emit conditional long-branch code");
374                         }
375                         else {
376                                 switch (condition) {
377                                 case BRANCH_EQ:
378                                         M_BNE(1);
379                                         M_BR(branchdisp);
380                                         break;
381                                 case BRANCH_NE:
382                                         M_BEQ(1);
383                                         M_BR(branchdisp);
384                                         break;
385                                 case BRANCH_LT:
386                                         M_BGE(1);
387                                         M_BR(branchdisp);
388                                         break;
389                                 case BRANCH_GE:
390                                         M_BLT(1);
391                                         M_BR(branchdisp);
392                                         break;
393                                 case BRANCH_GT:
394                                         M_BLE(1);
395                                         M_BR(branchdisp);
396                                         break;
397                                 case BRANCH_LE:
398                                         M_BGT(1);
399                                         M_BR(branchdisp);
400                                         break;
401                                 case BRANCH_NAN:
402                                         vm_abort("emit_branch: long BRANCH_NAN");
403                                         break;
404                                 default:
405                                         vm_abort("emit_branch: unknown condition %d", condition);
406                                 }
407                         }
408                 }
409                 else {
410                         switch (condition) {
411                         case BRANCH_EQ:
412                                 M_BEQ(branchdisp);
413                                 break;
414                         case BRANCH_NE:
415                                 M_BNE(branchdisp);
416                                 break;
417                         case BRANCH_LT:
418                                 M_BLT(branchdisp);
419                                 break;
420                         case BRANCH_GE:
421                                 M_BGE(branchdisp);
422                                 break;
423                         case BRANCH_GT:
424                                 M_BGT(branchdisp);
425                                 break;
426                         case BRANCH_LE:
427                                 M_BLE(branchdisp);
428                                 break;
429                         case BRANCH_NAN:
430                                 M_BNAN(branchdisp);
431                                 break;
432                         default:
433                                 vm_abort("emit_branch: unknown condition %d", condition);
434                         }
435                 }
436         }
437 }
438
439
440 /* emit_arithmetic_check *******************************************************
441
442    Emit an ArithmeticException check.
443
444 *******************************************************************************/
445
446 void emit_arithmetic_check(codegendata *cd, instruction *iptr, s4 reg)
447 {
448         if (INSTRUCTION_MUST_CHECK(iptr)) {
449                 M_TST(reg);
450                 M_BNE(1);
451                 M_ALD_INTERN(REG_ZERO, REG_ZERO, TRAP_ArithmeticException);
452         }
453 }
454
455
456 /* emit_arrayindexoutofbounds_check ********************************************
457
458    Emit a ArrayIndexOutOfBoundsException check.
459
460 *******************************************************************************/
461
462 void emit_arrayindexoutofbounds_check(codegendata *cd, instruction *iptr, s4 s1, s4 s2)
463 {
464         if (INSTRUCTION_MUST_CHECK(iptr)) {
465                 M_ILD(REG_ITMP3, s1, OFFSET(java_array_t, size));
466                 M_TRAPGEU(s2, REG_ITMP3);
467         }
468 }
469
470
471 /* emit_arraystore_check *******************************************************
472
473    Emit an ArrayStoreException check.
474
475 *******************************************************************************/
476
477 void emit_arraystore_check(codegendata *cd, instruction *iptr)
478 {
479         if (INSTRUCTION_MUST_CHECK(iptr)) {
480                 M_TST(REG_RESULT);
481                 M_BNE(1);
482                 M_ALD_INTERN(REG_ZERO, REG_ZERO, TRAP_ArrayStoreException);
483         }
484 }
485
486
487 /* emit_classcast_check ********************************************************
488
489    Emit a ClassCastException check.
490
491 *******************************************************************************/
492
493 void emit_classcast_check(codegendata *cd, instruction *iptr, s4 condition, s4 reg, s4 s1)
494 {
495         if (INSTRUCTION_MUST_CHECK(iptr)) {
496                 switch (condition) {
497                 case BRANCH_LE:
498                         M_BGT(1);
499                         break;
500                 case BRANCH_EQ:
501                         M_BNE(1);
502                         break;
503                 case BRANCH_NE:
504                         M_BEQ(1);
505                         break;
506                 case BRANCH_GT:
507                         M_BLE(1);
508                         break;
509                 default:
510                         vm_abort("emit_classcast_check: unknown condition %d", condition);
511                 }
512                 M_ALD_INTERN(s1, REG_ZERO, TRAP_ClassCastException);
513         }
514 }
515
516
517 /* emit_nullpointer_check ******************************************************
518
519    Emit a NullPointerException check.
520
521 *******************************************************************************/
522
523 void emit_nullpointer_check(codegendata *cd, instruction *iptr, s4 reg)
524 {
525         if (INSTRUCTION_MUST_CHECK(iptr)) {
526                 M_TST(reg);
527                 M_BNE(1);
528                 M_ALD_INTERN(REG_ZERO, REG_ZERO, TRAP_NullPointerException);
529         }
530 }
531
532
533 /* emit_exception_check ********************************************************
534
535    Emit an Exception check.
536
537 *******************************************************************************/
538
539 void emit_exception_check(codegendata *cd, instruction *iptr)
540 {
541         if (INSTRUCTION_MUST_CHECK(iptr)) {
542                 M_TST(REG_RESULT);
543                 M_BNE(1);
544                 M_ALD_INTERN(REG_ZERO, REG_ZERO, TRAP_CHECK_EXCEPTION);
545         }
546 }
547
548
549 /* emit_trap_compiler **********************************************************
550
551    Emit a trap instruction which calls the JIT compiler.
552
553 *******************************************************************************/
554
555 void emit_trap_compiler(codegendata *cd)
556 {
557         M_ALD_INTERN(REG_METHODPTR, REG_ZERO, TRAP_COMPILER);
558 }
559
560
561 /* emit_trap *******************************************************************
562
563    Emit a trap instruction and return the original machine code.
564
565 *******************************************************************************/
566
567 uint32_t emit_trap(codegendata *cd)
568 {
569         // Get machine code which is patched back in later. The rap is 1
570         // instruction word long.
571         uint32_t mcode = *((uint32_t*) cd->mcodeptr);
572
573         M_ILLEGAL;
574
575         return mcode;
576 }
577
578
579 /**
580  * Emit code to recompute the procedure vector.
581  */
582 void emit_recompute_pv(codegendata *cd)
583 {
584         int32_t disp = (int32_t) (cd->mcodeptr - cd->mcodebase);
585
586         M_MFLR(REG_ITMP1);
587         M_LDA(REG_PV, REG_ITMP1, -disp);
588 }
589
590
591 /**
592  * Generates synchronization code to enter a monitor.
593  */
594 #if defined(ENABLE_THREADS)
595 void emit_monitor_enter(jitdata* jd, int32_t syncslot_offset)
596 {
597         int32_t p;
598         int32_t disp;
599
600         // Get required compiler data.
601         methodinfo*  m  = jd->m;
602         codegendata* cd = jd->cd;
603
604 # if !defined(NDEBUG)
605         if (JITDATA_HAS_FLAG_VERBOSECALL(jd)) {
606                 M_AADD_IMM(REG_SP, -((LA_SIZE_IN_POINTERS + ARG_CNT) * 8), REG_SP);
607
608                 for (p = 0; p < INT_ARG_CNT; p++)
609                         M_IST(abi_registers_integer_argument[p], REG_SP, LA_SIZE + p * 8);
610
611                 for (p = 0; p < FLT_ARG_CNT; p++)
612                         M_DST(abi_registers_float_argument[p], REG_SP, LA_SIZE + (INT_ARG_CNT + p) * 8);
613
614                 syncslot_offset += (LA_SIZE_IN_POINTERS + ARG_CNT) * 8;
615         }
616 # endif
617
618         disp = dseg_add_functionptr(cd, LOCK_monitor_enter);
619         M_ALD(REG_ITMP3, REG_PV, disp);
620         M_MTCTR(REG_ITMP3);
621
622         /* get or test the lock object */
623
624         if (m->flags & ACC_STATIC) {
625                 disp = dseg_add_address(cd, &m->clazz->object.header);
626                 M_ALD(REG_A0, REG_PV, disp);
627         }
628         else {
629                 M_TST(REG_A0);
630                 M_BNE(1);
631                 M_ALD_INTERN(REG_ZERO, REG_ZERO, TRAP_NullPointerException);
632         }
633
634         M_AST(REG_A0, REG_SP, syncslot_offset);
635         M_JSR;
636
637 # if !defined(NDEBUG)
638         if (JITDATA_HAS_FLAG_VERBOSECALL(jd)) {
639                 for (p = 0; p < INT_ARG_CNT; p++)
640                         M_ILD(abi_registers_integer_argument[p], REG_SP, LA_SIZE + p * 8);
641
642                 for (p = 0; p < FLT_ARG_CNT; p++)
643                         M_DLD(abi_registers_float_argument[p], REG_SP, LA_SIZE + (INT_ARG_CNT + p) * 8);
644
645                 M_AADD_IMM(REG_SP, (LA_SIZE_IN_POINTERS + ARG_CNT) * 8, REG_SP);
646         }
647 # endif
648 }
649 #endif
650
651
652 /**
653  * Generates synchronization code to leave a monitor.
654  */
655 #if defined(ENABLE_THREADS)
656 void emit_monitor_exit(jitdata* jd, int32_t syncslot_offset)
657 {
658         int32_t disp;
659
660         // Get required compiler data.
661         methodinfo*  m  = jd->m;
662         codegendata* cd = jd->cd;
663
664         disp = dseg_add_functionptr(cd, LOCK_monitor_exit);
665         M_ALD(REG_ITMP3, REG_PV, disp);
666         M_MTCTR(REG_ITMP3);
667
668         /* we need to save the proper return value */
669
670         methoddesc* md = m->parseddesc;
671
672         switch (md->returntype.type) {
673         case TYPE_LNG:
674                 M_IST(REG_RESULT2, REG_SP, syncslot_offset + 8);
675                 /* fall through */
676         case TYPE_INT:
677         case TYPE_ADR:
678                 M_IST(REG_RESULT , REG_SP, syncslot_offset + 4);
679                 break;
680         case TYPE_FLT:
681         case TYPE_DBL:
682                 M_DST(REG_FRESULT, REG_SP, syncslot_offset + 4);
683                 break;
684         }
685
686         M_ALD(REG_A0, REG_SP, syncslot_offset);
687         M_JSR;
688
689         /* and now restore the proper return value */
690
691         switch (md->returntype.type) {
692         case TYPE_LNG:
693                 M_ILD(REG_RESULT2, REG_SP, syncslot_offset + 8);
694                 /* fall through */
695         case TYPE_INT:
696         case TYPE_ADR:
697                 M_ILD(REG_RESULT , REG_SP, syncslot_offset + 4);
698                 break;
699         case TYPE_FLT:
700         case TYPE_DBL:
701                 M_DLD(REG_FRESULT, REG_SP, syncslot_offset + 4);
702                 break;
703         }
704 }
705 #endif
706
707
708 /**
709  * Emit profiling code for method frequency counting.
710  */
711 #if defined(ENABLE_PROFILING)
712 void emit_profile_method(codegendata* cd, codeinfo* code)
713 {
714         M_ALD(REG_ITMP1, REG_PV, CodeinfoPointer);
715         M_ALD(REG_ITMP2, REG_ITMP1, OFFSET(codeinfo, frequency));
716         M_IADD_IMM(REG_ITMP2, 1, REG_ITMP2);
717         M_AST(REG_ITMP2, REG_ITMP1, OFFSET(codeinfo, frequency));
718 }
719 #endif
720
721
722 /**
723  * Emit profiling code for basicblock frequency counting.
724  */
725 #if defined(ENABLE_PROFILING)
726 void emit_profile_basicblock(codegendata* cd, codeinfo* code, basicblock* bptr)
727 {
728         int32_t disp = dseg_add_address(cd, code->bbfrequency);
729
730         M_ALD(REG_ITMP2, REG_PV, disp);
731         M_ALD(REG_ITMP3, REG_ITMP2, bptr->nr * 4);
732         M_IADD_IMM(REG_ITMP3, 1, REG_ITMP3);
733         M_AST(REG_ITMP3, REG_ITMP2, bptr->nr * 4);
734 }
735 #endif
736
737
738 /* emit_verbosecall_enter ******************************************************
739
740    Generates the code for the call trace.
741
742 *******************************************************************************/
743
744 void emit_verbosecall_enter(jitdata *jd)
745 {
746 #if !defined(NDEBUG)
747         methodinfo   *m;
748         codegendata  *cd;
749         registerdata *rd;
750         methoddesc   *md;
751         int32_t       disp;
752         int32_t       i;
753         int32_t       s, d;
754
755         if (!JITDATA_HAS_FLAG_VERBOSECALL(jd))
756                 return;
757
758         /* get required compiler data */
759
760         m  = jd->m;
761         cd = jd->cd;
762         rd = jd->rd;
763
764         md = m->parseddesc;
765
766         /* mark trace code */
767
768         M_NOP;
769
770         /* On Darwin we need to allocate an additional 3*4 bytes of stack
771            for the arguments to trace_java_call_enter, we make it 2*8. */
772
773         M_MFLR(REG_ZERO);
774         M_AST(REG_ZERO, REG_SP, LA_LR_OFFSET);
775         M_STWU(REG_SP, REG_SP, -(LA_SIZE + (2 + ARG_CNT + TMP_CNT) * 8));
776
777         /* save argument registers */
778
779         for (i = 0; i < md->paramcount; i++) {
780                 if (!md->params[i].inmemory) {
781                         s = md->params[i].regoff;
782                         d = LA_SIZE + (i + 2) * 8;
783
784                         switch (md->paramtypes[i].type) {
785                         case TYPE_INT:
786                         case TYPE_ADR:
787                                 M_IST(s, REG_SP, d);
788                                 break;
789                         case TYPE_LNG:
790                                 M_LST(s, REG_SP, d);
791                                 break;
792                         case TYPE_FLT:
793                                 M_FST(s, REG_SP, d);
794                                 break;
795                         case TYPE_DBL:
796                                 M_DST(s, REG_SP, d);
797                                 break;
798                         }
799                 }
800         }
801
802         /* pass methodinfo and pointers to the tracer function */
803
804         disp = dseg_add_address(cd, m);
805         M_ALD(REG_A0, REG_PV, disp);
806         M_AADD_IMM(REG_SP, LA_SIZE + 2 * 8, REG_A1);
807         M_AADD_IMM(REG_SP, LA_SIZE + (2 + ARG_CNT + TMP_CNT + cd->stackframesize) * 8, REG_A2);
808         
809         disp = dseg_add_functionptr(cd, trace_java_call_enter);
810         M_ALD(REG_ITMP2, REG_PV, disp);
811         M_MTCTR(REG_ITMP2);
812         M_JSR;
813
814         /* restore argument registers */
815
816         for (i = 0; i < md->paramcount; i++) {
817                 if (!md->params[i].inmemory) {
818                         s = LA_SIZE + (i + 2) * 8;
819                         d = md->params[i].regoff;
820
821                         switch (md->paramtypes[i].type) {
822                         case TYPE_INT:
823                         case TYPE_ADR:
824                                 M_ILD(d, REG_SP, s);
825                                 break;
826                         case TYPE_LNG:
827                                 M_LLD(d, REG_SP, s);
828                                 break;
829                         case TYPE_FLT:
830                                 M_FLD(d, REG_SP, s);
831                                 break;
832                         case TYPE_DBL:
833                                 M_DLD(d, REG_SP, s);
834                                 break;
835                         }
836                 }
837         }
838
839         M_ALD(REG_ZERO, REG_SP, LA_SIZE + (2 + ARG_CNT + TMP_CNT) * 8 + LA_LR_OFFSET);
840         M_MTLR(REG_ZERO);
841         M_LDA(REG_SP, REG_SP, LA_SIZE + (2 + ARG_CNT + TMP_CNT) * 8);
842
843         /* mark trace code */
844
845         M_NOP;
846 #endif /* !defined(NDEBUG) */
847 }
848
849
850 /* emit_verbosecall_exit *******************************************************
851
852    Generates the code for the call trace.
853
854 *******************************************************************************/
855
856 void emit_verbosecall_exit(jitdata *jd)
857 {
858 #if !defined(NDEBUG)
859         methodinfo   *m;
860         codegendata  *cd;
861         registerdata *rd;
862         methoddesc   *md;
863         s4            disp;
864
865         if (!JITDATA_HAS_FLAG_VERBOSECALL(jd))
866                 return;
867
868         /* get required compiler data */
869
870         m  = jd->m;
871         cd = jd->cd;
872         rd = jd->rd;
873
874         md = m->parseddesc;
875         
876         /* mark trace code */
877
878         M_NOP;
879
880         /* On Darwin we need to allocate an additional 2*4 bytes of stack
881            for the arguments to trace_java_call_exit, we make it 1*8. */
882
883         M_MFLR(REG_ZERO);
884         M_AST(REG_ZERO, REG_SP, LA_LR_OFFSET);
885         M_STWU(REG_SP, REG_SP, -(LA_SIZE + (1 + 1) * 8));
886
887         /* save return value */
888
889         switch (md->returntype.type) {
890         case TYPE_INT:
891         case TYPE_ADR:
892                 M_IST(REG_RESULT, REG_SP, LA_SIZE + 1 * 8);
893                 break;
894         case TYPE_LNG:
895                 M_LST(REG_RESULT_PACKED, REG_SP, LA_SIZE + 1 * 8);
896                 break;
897         case TYPE_FLT:
898                 M_FST(REG_FRESULT, REG_SP, LA_SIZE + 1 * 8);
899                 break;
900         case TYPE_DBL:
901                 M_DST(REG_FRESULT, REG_SP, LA_SIZE + 1 * 8);
902                 break;
903         case TYPE_VOID:
904                 break;
905         }
906
907         disp = dseg_add_address(cd, m);
908         M_ALD(REG_A0, REG_PV, disp);
909         M_AADD_IMM(REG_SP, LA_SIZE + 1 * 8, REG_A1);
910
911         disp = dseg_add_functionptr(cd, trace_java_call_exit);
912         M_ALD(REG_ITMP2, REG_PV, disp);
913         M_MTCTR(REG_ITMP2);
914         M_JSR;
915
916         /* restore return value */
917
918         switch (md->returntype.type) {
919         case TYPE_INT:
920         case TYPE_ADR:
921                 M_ILD(REG_RESULT, REG_SP, LA_SIZE + 1 * 8);
922                 break;
923         case TYPE_LNG:
924                 M_LLD(REG_RESULT_PACKED, REG_SP, LA_SIZE + 1 * 8);
925                 break;
926         case TYPE_FLT:
927                 M_FLD(REG_FRESULT, REG_SP, LA_SIZE + 1 * 8);
928                 break;
929         case TYPE_DBL:
930                 M_DLD(REG_FRESULT, REG_SP, LA_SIZE + 1 * 8);
931                 break;
932         case TYPE_VOID:
933                 break;
934         }
935
936         M_ALD(REG_ZERO, REG_SP, LA_SIZE + (1 + 1) * 8 + LA_LR_OFFSET);
937         M_MTLR(REG_ZERO);
938         M_LDA(REG_SP, REG_SP, LA_SIZE + (1 + 1) * 8);
939
940         /* mark trace code */
941
942         M_NOP;
943 #endif /* !defined(NDEBUG) */
944 }
945
946
947 /*
948  * These are local overrides for various environment variables in Emacs.
949  * Please do not remove this and leave it at the end of the file, where
950  * Emacs will automagically detect them.
951  * ---------------------------------------------------------------------
952  * Local variables:
953  * mode: c
954  * indent-tabs-mode: t
955  * c-basic-offset: 4
956  * tab-width: 4
957  * End:
958  * vim:noexpandtab:sw=4:ts=4:
959  */