* src/vm/jit/jit.cpp: Use C++ interface of OprofileAgent.
[cacao.git] / src / vm / jit / codegen-common.cpp
1 /* src/vm/jit/codegen-common.cpp - architecture independent code generator stuff
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    All functions assume the following code area / data area layout:
24
25    +-----------+
26    |           |
27    | code area | code area grows to higher addresses
28    |           |
29    +-----------+ <-- start of procedure
30    |           |
31    | data area | data area grows to lower addresses
32    |           |
33    +-----------+
34
35    The functions first write into a temporary code/data area allocated by
36    "codegen_init". "codegen_finish" copies the code and data area into permanent
37    memory. All functions writing values into the data area return the offset
38    relative the begin of the code area (start of procedure).    
39
40 */
41
42
43 #include "config.h"
44
45 #include <assert.h>
46 #include <string.h>
47
48 #include "vm/types.h"
49
50 #include "codegen.h"
51 #include "md.h"
52 #include "md-abi.h"
53
54 #include "mm/memory.h"
55
56 #include "toolbox/avl.h"
57 #include "toolbox/list.hpp"
58 #include "toolbox/logging.h"
59
60 #include "native/llni.h"
61 #include "native/localref.hpp"
62 #include "native/native.hpp"
63
64 #include "threads/thread.hpp"
65
66 #include "vm/jit/builtin.hpp"
67 #include "vm/exceptions.hpp"
68 #include "vm/method.h"
69 #include "vm/options.h"
70 #include "vm/string.hpp"
71
72 # include "vm/statistics.h"
73
74
75 #include "vm/jit/abi.h"
76 #include "vm/jit/asmpart.h"
77 #include "vm/jit/code.hpp"
78 #include "vm/jit/codegen-common.hpp"
79
80 #if defined(ENABLE_DISASSEMBLER)
81 # include "vm/jit/disass.h"
82 #endif
83
84 #include "vm/jit/dseg.h"
85 #include "vm/jit/emit-common.hpp"
86 #include "vm/jit/jit.hpp"
87 #include "vm/jit/linenumbertable.hpp"
88 #include "vm/jit/methodheader.h"
89 #include "vm/jit/methodtree.h"
90 #include "vm/jit/patcher-common.hpp"
91 #include "vm/jit/replace.hpp"
92 #if defined(ENABLE_SSA)
93 # include "vm/jit/optimizing/lsra.h"
94 # include "vm/jit/optimizing/ssa.h"
95 #endif
96 #include "vm/jit/stacktrace.hpp"
97 #include "vm/jit/trace.hpp"
98
99 #if defined(ENABLE_INTRP)
100 #include "vm/jit/intrp/intrp.h"
101 #endif
102
103 #if defined(ENABLE_VMLOG)
104 #include <vmlog_cacao.h>
105 #endif
106
107 #include "show.hpp"
108
109
110 /* codegen_init ****************************************************************
111
112    TODO
113
114 *******************************************************************************/
115
116 void codegen_init(void)
117 {
118 }
119
120
121 /* codegen_setup ***************************************************************
122
123    Allocates and initialises code area, data area and references.
124
125 *******************************************************************************/
126
127 void codegen_setup(jitdata *jd)
128 {
129         methodinfo  *m;
130         codegendata *cd;
131
132         /* get required compiler data */
133
134         m  = jd->m;
135         cd = jd->cd;
136
137         /* initialize members */
138
139         cd->flags        = 0;
140
141         cd->mcodebase    = (u1*) DumpMemory::allocate(MCODEINITSIZE);
142         cd->mcodeend     = cd->mcodebase + MCODEINITSIZE;
143         cd->mcodesize    = MCODEINITSIZE;
144
145         /* initialize mcode variables */
146
147         cd->mcodeptr     = cd->mcodebase;
148         cd->lastmcodeptr = cd->mcodebase;
149
150 #if defined(ENABLE_INTRP)
151         /* native dynamic superinstructions variables */
152
153         if (opt_intrp) {
154                 cd->ncodebase = (u1*) DumpMemory::allocate(NCODEINITSIZE);
155                 cd->ncodesize = NCODEINITSIZE;
156
157                 /* initialize ncode variables */
158         
159                 cd->ncodeptr = cd->ncodebase;
160
161                 cd->lastinstwithoutdispatch = ~0; /* no inst without dispatch */
162                 cd->superstarts = NULL;
163         }
164 #endif
165
166         cd->dseg           = NULL;
167         cd->dseglen        = 0;
168
169         cd->jumpreferences = NULL;
170
171 #if defined(__I386__) || defined(__X86_64__) || defined(__XDSPCORE__) || defined(__M68K__) || defined(ENABLE_INTRP)
172         cd->datareferences = NULL;
173 #endif
174
175         cd->brancheslabel  = new DumpList<branch_label_ref_t*>();
176         cd->linenumbers    = new DumpList<Linenumber>();
177 }
178
179
180 /* codegen_reset ***************************************************************
181
182    Resets the codegen data structure so we can recompile the method.
183
184 *******************************************************************************/
185
186 static void codegen_reset(jitdata *jd)
187 {
188         codeinfo    *code;
189         codegendata *cd;
190         basicblock  *bptr;
191
192         /* get required compiler data */
193
194         code = jd->code;
195         cd   = jd->cd;
196
197         /* reset error flag */
198
199         cd->flags          &= ~CODEGENDATA_FLAG_ERROR;
200
201         /* reset some members, we reuse the code memory already allocated
202            as this should have almost the correct size */
203
204         cd->mcodeptr        = cd->mcodebase;
205         cd->lastmcodeptr    = cd->mcodebase;
206
207         cd->dseg            = NULL;
208         cd->dseglen         = 0;
209
210         cd->jumpreferences  = NULL;
211
212 #if defined(__I386__) || defined(__X86_64__) || defined(__XDSPCORE__) || defined(__M68K__) || defined(ENABLE_INTRP)
213         cd->datareferences  = NULL;
214 #endif
215
216         cd->brancheslabel   = new DumpList<branch_label_ref_t*>();
217         cd->linenumbers     = new DumpList<Linenumber>();
218         
219         /* We need to clear the mpc and the branch references from all
220            basic blocks as they will definitely change. */
221
222         for (bptr = jd->basicblocks; bptr != NULL; bptr = bptr->next) {
223                 bptr->mpc        = -1;
224                 bptr->branchrefs = NULL;
225         }
226
227         /* We need to clear all the patcher references from the codeinfo
228            since they all will be regenerated */
229
230         patcher_list_reset(code);
231
232 #if defined(ENABLE_REPLACEMENT)
233         code->rplpoints     = NULL;
234         code->rplpointcount = 0;
235         code->regalloc      = NULL;
236         code->regalloccount = 0;
237         code->globalcount   = 0;
238 #endif
239 }
240
241
242 /* codegen_generate ************************************************************
243
244    Generates the code for the currently compiled method.
245
246 *******************************************************************************/
247
248 bool codegen_generate(jitdata *jd)
249 {
250         codegendata *cd;
251
252         /* get required compiler data */
253
254         cd = jd->cd;
255
256         /* call the machine-dependent code generation function */
257
258         if (!codegen_emit(jd))
259                 return false;
260
261         /* check for an error */
262
263         if (CODEGENDATA_HAS_FLAG_ERROR(cd)) {
264                 /* check for long-branches flag, if it is set we recompile the
265                    method */
266
267 #if !defined(NDEBUG)
268         if (compileverbose)
269             log_message_method("Re-generating code: ", jd->m);
270 #endif
271
272                 /* XXX maybe we should tag long-branches-methods for recompilation */
273
274                 if (CODEGENDATA_HAS_FLAG_LONGBRANCHES(cd)) {
275                         /* we have to reset the codegendata structure first */
276
277                         codegen_reset(jd);
278
279                         /* and restart the compiler run */
280
281                         if (!codegen_emit(jd))
282                                 return false;
283                 }
284                 else {
285                         vm_abort("codegen_generate: unknown error occurred during codegen_emit: flags=%x\n", cd->flags);
286                 }
287
288 #if !defined(NDEBUG)
289         if (compileverbose)
290             log_message_method("Re-generating code done: ", jd->m);
291 #endif
292         }
293
294         /* reallocate the memory and finish the code generation */
295
296         codegen_finish(jd);
297
298         /* everything's ok */
299
300         return true;
301 }
302
303
304 /* codegen_close ***************************************************************
305
306    TODO
307
308 *******************************************************************************/
309
310 void codegen_close(void)
311 {
312         /* TODO: release avl tree on i386 and x86_64 */
313 }
314
315
316 /* codegen_increase ************************************************************
317
318    Doubles code area.
319
320 *******************************************************************************/
321
322 void codegen_increase(codegendata *cd)
323 {
324         u1 *oldmcodebase;
325
326         /* save old mcodebase pointer */
327
328         oldmcodebase = cd->mcodebase;
329
330         /* reallocate to new, doubled memory */
331
332         cd->mcodebase = (u1*) DumpMemory::reallocate(cd->mcodebase,
333                                                                                                  cd->mcodesize,
334                                                                                                  cd->mcodesize * 2);
335         cd->mcodesize *= 2;
336         cd->mcodeend   = cd->mcodebase + cd->mcodesize;
337
338         /* set new mcodeptr */
339
340         cd->mcodeptr = cd->mcodebase + (cd->mcodeptr - oldmcodebase);
341
342 #if defined(__I386__) || defined(__MIPS__) || defined(__X86_64__) || defined(__M68K__) || defined(ENABLE_INTRP) \
343  || defined(__SPARC_64__)
344         /* adjust the pointer to the last patcher position */
345
346         if (cd->lastmcodeptr != NULL)
347                 cd->lastmcodeptr = cd->mcodebase + (cd->lastmcodeptr - oldmcodebase);
348 #endif
349 }
350
351
352 /* codegen_ncode_increase ******************************************************
353
354    Doubles code area.
355
356 *******************************************************************************/
357
358 #if defined(ENABLE_INTRP)
359 u1 *codegen_ncode_increase(codegendata *cd, u1 *ncodeptr)
360 {
361         u1 *oldncodebase;
362
363         /* save old ncodebase pointer */
364
365         oldncodebase = cd->ncodebase;
366
367         /* reallocate to new, doubled memory */
368
369         cd->ncodebase = DMREALLOC(cd->ncodebase,
370                                                           u1,
371                                                           cd->ncodesize,
372                                                           cd->ncodesize * 2);
373         cd->ncodesize *= 2;
374
375         /* return the new ncodeptr */
376
377         return (cd->ncodebase + (ncodeptr - oldncodebase));
378 }
379 #endif
380
381
382 /* codegen_add_branch_ref ******************************************************
383
384    Prepends an branch to the list.
385
386 *******************************************************************************/
387
388 void codegen_add_branch_ref(codegendata *cd, basicblock *target, s4 condition, s4 reg, u4 options)
389 {
390         branchref *br;
391         s4         branchmpc;
392
393         STATISTICS(count_branches_unresolved++);
394
395         /* calculate the mpc of the branch instruction */
396
397         branchmpc = cd->mcodeptr - cd->mcodebase;
398
399         br = (branchref*) DumpMemory::allocate(sizeof(branchref));
400
401         br->branchmpc = branchmpc;
402         br->condition = condition;
403         br->reg       = reg;
404         br->options   = options;
405         br->next      = target->branchrefs;
406
407         target->branchrefs = br;
408 }
409
410
411 /* codegen_resolve_branchrefs **************************************************
412
413    Resolves and patches the branch references of a given basic block.
414
415 *******************************************************************************/
416
417 void codegen_resolve_branchrefs(codegendata *cd, basicblock *bptr)
418 {
419         branchref *br;
420         u1        *mcodeptr;
421
422         /* Save the mcodeptr because in the branch emitting functions
423            we generate code somewhere inside already generated code,
424            but we're still in the actual code generation phase. */
425
426         mcodeptr = cd->mcodeptr;
427
428         /* just to make sure */
429
430         assert(bptr->mpc >= 0);
431
432         for (br = bptr->branchrefs; br != NULL; br = br->next) {
433                 /* temporary set the mcodeptr */
434
435                 cd->mcodeptr = cd->mcodebase + br->branchmpc;
436
437                 /* emit_bccz and emit_branch emit the correct code, even if we
438                    pass condition == BRANCH_UNCONDITIONAL or reg == -1. */
439
440                 emit_bccz(cd, bptr, br->condition, br->reg, br->options);
441         }
442
443         /* restore mcodeptr */
444
445         cd->mcodeptr = mcodeptr;
446 }
447
448
449 /* codegen_branch_label_add ****************************************************
450
451    Append an branch to the label-branch list.
452
453 *******************************************************************************/
454
455 void codegen_branch_label_add(codegendata *cd, s4 label, s4 condition, s4 reg, u4 options)
456 {
457         // Calculate the current mpc.
458         int32_t mpc = cd->mcodeptr - cd->mcodebase;
459
460         branch_label_ref_t* br = (branch_label_ref_t*) DumpMemory::allocate(sizeof(branch_label_ref_t));
461
462         br->mpc       = mpc;
463         br->label     = label;
464         br->condition = condition;
465         br->reg       = reg;
466         br->options   = options;
467
468         // Add the branch to the list.
469         cd->brancheslabel->push_back(br);
470 }
471
472
473 /* codegen_set_replacement_point_notrap ****************************************
474
475    Record the position of a non-trappable replacement point.
476
477 *******************************************************************************/
478
479 #if defined(ENABLE_REPLACEMENT)
480 #if !defined(NDEBUG)
481 void codegen_set_replacement_point_notrap(codegendata *cd, s4 type)
482 #else
483 void codegen_set_replacement_point_notrap(codegendata *cd)
484 #endif
485 {
486         assert(cd->replacementpoint);
487         assert(cd->replacementpoint->type == type);
488         assert(cd->replacementpoint->flags & RPLPOINT_FLAG_NOTRAP);
489
490         cd->replacementpoint->pc = (u1*) (ptrint) (cd->mcodeptr - cd->mcodebase);
491
492         cd->replacementpoint++;
493 }
494 #endif /* defined(ENABLE_REPLACEMENT) */
495
496
497 /* codegen_set_replacement_point ***********************************************
498
499    Record the position of a trappable replacement point.
500
501 *******************************************************************************/
502
503 #if defined(ENABLE_REPLACEMENT)
504 #if !defined(NDEBUG)
505 void codegen_set_replacement_point(codegendata *cd, s4 type)
506 #else
507 void codegen_set_replacement_point(codegendata *cd)
508 #endif
509 {
510         assert(cd->replacementpoint);
511         assert(cd->replacementpoint->type == type);
512         assert(!(cd->replacementpoint->flags & RPLPOINT_FLAG_NOTRAP));
513
514         cd->replacementpoint->pc = (u1*) (ptrint) (cd->mcodeptr - cd->mcodebase);
515
516         cd->replacementpoint++;
517
518 #if !defined(NDEBUG)
519         /* XXX actually we should use an own REPLACEMENT_NOPS here! */
520         if (opt_TestReplacement)
521                 PATCHER_NOPS;
522 #endif
523
524         /* XXX assert(cd->lastmcodeptr <= cd->mcodeptr); */
525
526         cd->lastmcodeptr = cd->mcodeptr + PATCHER_CALL_SIZE;
527 }
528 #endif /* defined(ENABLE_REPLACEMENT) */
529
530
531 /* codegen_finish **************************************************************
532
533    Finishes the code generation. A new memory, large enough for both
534    data and code, is allocated and data and code are copied together
535    to their final layout, unresolved jumps are resolved, ...
536
537 *******************************************************************************/
538
539 void codegen_finish(jitdata *jd)
540 {
541         codeinfo    *code;
542         codegendata *cd;
543         s4           mcodelen;
544 #if defined(ENABLE_INTRP)
545         s4           ncodelen;
546 #endif
547         s4           alignedmcodelen;
548         jumpref     *jr;
549         u1          *epoint;
550         s4           alignedlen;
551
552         /* get required compiler data */
553
554         code = jd->code;
555         cd   = jd->cd;
556
557         /* prevent compiler warning */
558
559 #if defined(ENABLE_INTRP)
560         ncodelen = 0;
561 #endif
562
563         /* calculate the code length */
564
565         mcodelen = (s4) (cd->mcodeptr - cd->mcodebase);
566
567 #if defined(ENABLE_STATISTICS)
568         if (opt_stat) {
569                 count_code_len += mcodelen;
570                 count_data_len += cd->dseglen;
571         }
572 #endif
573
574         alignedmcodelen = MEMORY_ALIGN(mcodelen, MAX_ALIGN);
575
576 #if defined(ENABLE_INTRP)
577         if (opt_intrp)
578                 ncodelen = cd->ncodeptr - cd->ncodebase;
579         else {
580                 ncodelen = 0; /* avoid compiler warning */
581         }
582 #endif
583
584         cd->dseglen = MEMORY_ALIGN(cd->dseglen, MAX_ALIGN);
585         alignedlen = alignedmcodelen + cd->dseglen;
586
587 #if defined(ENABLE_INTRP)
588         if (opt_intrp) {
589                 alignedlen += ncodelen;
590         }
591 #endif
592
593         /* allocate new memory */
594
595         code->mcodelength = mcodelen + cd->dseglen;
596         code->mcode       = CNEW(u1, alignedlen);
597
598         /* set the entrypoint of the method */
599         
600         assert(code->entrypoint == NULL);
601         code->entrypoint = epoint = (code->mcode + cd->dseglen);
602
603         /* fill the data segment (code->entrypoint must already be set!) */
604
605         dseg_finish(jd);
606
607         /* copy code to the new location */
608
609         MCOPY((void *) code->entrypoint, cd->mcodebase, u1, mcodelen);
610
611 #if defined(ENABLE_INTRP)
612         /* relocate native dynamic superinstruction code (if any) */
613
614         if (opt_intrp) {
615                 cd->mcodebase = code->entrypoint;
616
617                 if (ncodelen > 0) {
618                         u1 *ncodebase = code->mcode + cd->dseglen + alignedmcodelen;
619
620                         MCOPY((void *) ncodebase, cd->ncodebase, u1, ncodelen);
621
622                         /* flush the instruction and data caches */
623
624                         md_cacheflush(ncodebase, ncodelen);
625
626                         /* set some cd variables for dynamic_super_rerwite */
627
628                         cd->ncodebase = ncodebase;
629
630                 } else {
631                         cd->ncodebase = NULL;
632                 }
633
634                 dynamic_super_rewrite(cd);
635         }
636 #endif
637
638         /* Create the exception table. */
639
640         exceptiontable_create(jd);
641
642         /* Create the linenumber table. */
643
644         code->linenumbertable = new LinenumberTable(jd);
645
646         /* jump table resolving */
647
648         for (jr = cd->jumpreferences; jr != NULL; jr = jr->next)
649                 *((functionptr *) ((ptrint) epoint + jr->tablepos)) =
650                         (functionptr) ((ptrint) epoint + (ptrint) jr->target->mpc);
651
652         /* patcher resolving */
653
654         patcher_resolve(jd);
655
656 #if defined(ENABLE_REPLACEMENT)
657         /* replacement point resolving */
658         {
659                 int i;
660                 rplpoint *rp;
661
662                 rp = code->rplpoints;
663                 for (i=0; i<code->rplpointcount; ++i, ++rp) {
664                         rp->pc = (u1*) ((ptrint) epoint + (ptrint) rp->pc);
665                 }
666         }
667 #endif /* defined(ENABLE_REPLACEMENT) */
668
669         /* Insert method into methodtree to find the entrypoint. */
670
671         methodtree_insert(code->entrypoint, code->entrypoint + mcodelen);
672
673 #if defined(__I386__) || defined(__X86_64__) || defined(__XDSPCORE__) || defined(__M68K__) || defined(ENABLE_INTRP)
674         /* resolve data segment references */
675
676         dseg_resolve_datareferences(jd);
677 #endif
678
679         /* flush the instruction and data caches */
680
681         md_cacheflush(code->mcode, code->mcodelength);
682 }
683
684
685 /* codegen_start_native_call ***************************************************
686
687    Prepares the stuff required for a native (JNI) function call:
688
689    - adds a stackframe info structure to the chain, for stacktraces
690    - prepares the local references table on the stack
691
692    The layout of the native stub stackframe should look like this:
693
694    +---------------------------+ <- java SP (of parent Java function)
695    | return address            |
696    +---------------------------+ <- data SP
697    |                           |
698    | stackframe info structure |
699    |                           |
700    +---------------------------+
701    |                           |
702    | local references table    |
703    |                           |
704    +---------------------------+
705    |                           |
706    | saved registers (if any)  |
707    |                           |
708    +---------------------------+
709    |                           |
710    | arguments (if any)        |
711    |                           |
712    +---------------------------+ <- current SP (native stub)
713
714 *******************************************************************************/
715
716 java_handle_t *codegen_start_native_call(u1 *sp, u1 *pv)
717 {
718         stackframeinfo_t *sfi;
719         localref_table   *lrt;
720         methodinfo       *m;
721         int32_t           framesize;
722
723         uint8_t  *datasp;
724         uint8_t  *javasp;
725         uint64_t *arg_regs;
726         uint64_t *arg_stack;
727
728         STATISTICS(count_calls_java_to_native++);
729
730         /* Get the methodinfo. */
731
732         m = code_get_methodinfo_for_pv(pv);
733
734         assert(m);
735
736         framesize = *((int32_t *) (pv + FrameSize));
737
738         assert(framesize >= (int32_t) (sizeof(stackframeinfo_t) + sizeof(localref_table)));
739
740         /* calculate needed values */
741
742 #if defined(__ALPHA__) || defined(__ARM__)
743         datasp    = sp + framesize - SIZEOF_VOID_P;
744         javasp    = sp + framesize;
745         arg_regs  = (uint64_t *) sp;
746         arg_stack = (uint64_t *) javasp;
747 #elif defined(__MIPS__)
748         /* MIPS always uses 8 bytes to store the RA */
749         datasp    = sp + framesize - 8;
750         javasp    = sp + framesize;
751 #elif defined(__S390__)
752         datasp    = sp + framesize - 8;
753         javasp    = sp + framesize;
754         arg_regs  = (uint64_t *) (sp + 96);
755         arg_stack = (uint64_t *) javasp;
756 #elif defined(__I386__) || defined(__M68K__) || defined(__X86_64__)
757         datasp    = sp + framesize;
758         javasp    = sp + framesize + SIZEOF_VOID_P;
759         arg_regs  = (uint64_t *) sp;
760         arg_stack = (uint64_t *) javasp;
761 #elif defined(__POWERPC__)
762         datasp    = sp + framesize;
763         javasp    = sp + framesize;
764         arg_regs  = (uint64_t *) (sp + LA_SIZE + 4 * SIZEOF_VOID_P);
765         arg_stack = (uint64_t *) javasp;
766 #elif defined(__POWERPC64__)
767         datasp    = sp + framesize;
768         javasp    = sp + framesize;
769         arg_regs  = (uint64_t *) (sp + PA_SIZE + LA_SIZE + 4 * SIZEOF_VOID_P);
770         arg_stack = (uint64_t *) javasp;
771 #else
772         /* XXX is was unable to do this port for SPARC64, sorry. (-michi) */
773         /* XXX maybe we need to pass the RA as argument there */
774         vm_abort("codegen_start_native_call: unsupported architecture");
775 #endif
776
777         /* get data structures from stack */
778
779         sfi = (stackframeinfo_t *) (datasp - sizeof(stackframeinfo_t));
780         lrt = (localref_table *)   (datasp - sizeof(stackframeinfo_t) - 
781                                                                 sizeof(localref_table));
782
783 #if defined(ENABLE_JNI)
784         /* add current JNI local references table to this thread */
785
786         localref_table_add(lrt);
787 #endif
788
789 #if !defined(NDEBUG)
790 # if defined(__ALPHA__) || defined(__I386__) || defined(__M68K__) || defined(__POWERPC__) || defined(__POWERPC64__) || defined(__S390__) || defined(__X86_64__)
791         /* print the call-trace if necesarry */
792         /* BEFORE: filling the local reference table */
793
794         if (opt_TraceJavaCalls)
795                 trace_java_call_enter(m, arg_regs, arg_stack);
796 # endif
797 #endif
798
799 #if defined(ENABLE_HANDLES)
800         /* place all references into the local reference table */
801         /* BEFORE: creating stackframeinfo */
802
803         localref_native_enter(m, arg_regs, arg_stack);
804 #endif
805
806         /* Add a stackframeinfo for this native method.  We don't have RA
807            and XPC here.  These are determined in
808            stacktrace_stackframeinfo_add. */
809
810         stacktrace_stackframeinfo_add(sfi, pv, sp, NULL, NULL);
811
812         /* Return a wrapped classinfo for static methods. */
813
814         if (m->flags & ACC_STATIC)
815                 return (java_handle_t *) LLNI_classinfo_wrap(m->clazz);
816         else
817                 return NULL;
818 }
819
820
821 /* codegen_finish_native_call **************************************************
822
823    Removes the stuff required for a native (JNI) function call.
824    Additionally it checks for an exceptions and in case, get the
825    exception object and clear the pointer.
826
827 *******************************************************************************/
828
829 java_object_t *codegen_finish_native_call(u1 *sp, u1 *pv)
830 {
831         stackframeinfo_t *sfi;
832         java_handle_t    *e;
833         java_object_t    *o;
834         codeinfo         *code;
835         methodinfo       *m;
836         int32_t           framesize;
837
838         uint8_t  *datasp;
839         uint64_t *ret_regs;
840
841         /* get information from method header */
842
843         code = code_get_codeinfo_for_pv(pv);
844
845         framesize = *((int32_t *) (pv + FrameSize));
846
847         assert(code);
848
849         /* get the methodinfo */
850
851         m = code->m;
852         assert(m);
853
854         /* calculate needed values */
855
856 #if defined(__ALPHA__) || defined(__ARM__)
857         datasp   = sp + framesize - SIZEOF_VOID_P;
858         ret_regs = (uint64_t *) sp;
859 #elif defined(__MIPS__)
860         /* MIPS always uses 8 bytes to store the RA */
861         datasp   = sp + framesize - 8;
862 #elif defined(__S390__)
863         datasp   = sp + framesize - 8;
864         ret_regs = (uint64_t *) (sp + 96);
865 #elif defined(__I386__)
866         datasp   = sp + framesize;
867         ret_regs = (uint64_t *) (sp + 2 * SIZEOF_VOID_P);
868 #elif defined(__M68K__)
869         datasp   = sp + framesize;
870         ret_regs = (uint64_t *) (sp + 2 * 8);
871 #elif defined(__X86_64__)
872         datasp   = sp + framesize;
873         ret_regs = (uint64_t *) sp;
874 #elif defined(__POWERPC__)
875         datasp   = sp + framesize;
876         ret_regs = (uint64_t *) (sp + LA_SIZE + 2 * SIZEOF_VOID_P);
877 #elif defined(__POWERPC64__)
878         datasp   = sp + framesize;
879         ret_regs = (uint64_t *) (sp + PA_SIZE + LA_SIZE + 2 * SIZEOF_VOID_P);
880 #else
881         vm_abort("codegen_finish_native_call: unsupported architecture");
882 #endif
883
884         /* get data structures from stack */
885
886         sfi = (stackframeinfo_t *) (datasp - sizeof(stackframeinfo_t));
887
888         /* Remove current stackframeinfo from chain. */
889
890         stacktrace_stackframeinfo_remove(sfi);
891
892 #if defined(ENABLE_HANDLES)
893         /* unwrap the return value from the local reference table */
894         /* AFTER: removing the stackframeinfo */
895         /* BEFORE: releasing the local reference table */
896
897         localref_native_exit(m, ret_regs);
898 #endif
899
900         /* get and unwrap the exception */
901         /* AFTER: removing the stackframe info */
902         /* BEFORE: releasing the local reference table */
903
904         e = exceptions_get_and_clear_exception();
905         o = LLNI_UNWRAP(e);
906
907 #if defined(ENABLE_JNI)
908         /* release JNI local references table for this thread */
909
910         localref_frame_pop_all();
911         localref_table_remove();
912 #endif
913
914 #if !defined(NDEBUG)
915 # if defined(__ALPHA__) || defined(__I386__) || defined(__M68K__) || defined(__POWERPC__) || defined(__POWERPC64__) || defined(__S390__) || defined(__X86_64__)
916         /* print the call-trace if necesarry */
917         /* AFTER: unwrapping the return value */
918
919         if (opt_TraceJavaCalls)
920                 trace_java_call_exit(m, ret_regs);
921 # endif
922 #endif
923
924         return o;
925 }
926
927
928 /* codegen_reg_of_var **********************************************************
929
930    This function determines a register, to which the result of an
931    operation should go, when it is ultimatively intended to store the
932    result in pseudoregister v.  If v is assigned to an actual
933    register, this register will be returned.  Otherwise (when v is
934    spilled) this function returns tempregnum.  If not already done,
935    regoff and flags are set in the stack location.
936        
937 *******************************************************************************/
938
939 s4 codegen_reg_of_var(u2 opcode, varinfo *v, s4 tempregnum)
940 {
941         if (!(v->flags & INMEMORY))
942                 return v->vv.regoff;
943
944         return tempregnum;
945 }
946
947
948 /* codegen_reg_of_dst **********************************************************
949
950    This function determines a register, to which the result of an
951    operation should go, when it is ultimatively intended to store the
952    result in iptr->dst.var.  If dst.var is assigned to an actual
953    register, this register will be returned.  Otherwise (when it is
954    spilled) this function returns tempregnum.  If not already done,
955    regoff and flags are set in the stack location.
956        
957 *******************************************************************************/
958
959 s4 codegen_reg_of_dst(jitdata *jd, instruction *iptr, s4 tempregnum)
960 {
961         return codegen_reg_of_var(iptr->opc, VAROP(iptr->dst), tempregnum);
962 }
963
964
965 /* codegen_emit_phi_moves ****************************************************
966
967    Emits phi moves at the end of the basicblock.
968
969 *******************************************************************************/
970
971 #if defined(ENABLE_SSA)
972 void codegen_emit_phi_moves(jitdata *jd, basicblock *bptr)
973 {
974         int lt_d,lt_s,i;
975         lsradata *ls;
976         codegendata *cd;
977         varinfo *s, *d;
978         instruction tmp_i;
979
980         cd = jd->cd;
981         ls = jd->ls;
982
983         MCODECHECK(512);
984
985         /* Moves from phi functions with highest indices have to be */
986         /* inserted first, since this is the order as is used for   */
987         /* conflict resolution */
988
989         for(i = ls->num_phi_moves[bptr->nr] - 1; i >= 0 ; i--) {
990                 lt_d = ls->phi_moves[bptr->nr][i][0];
991                 lt_s = ls->phi_moves[bptr->nr][i][1];
992 #if defined(SSA_DEBUG_VERBOSE)
993                 if (compileverbose)
994                         printf("BB %3i Move %3i <- %3i ", bptr->nr, lt_d, lt_s);
995 #endif
996                 if (lt_s == UNUSED) {
997 #if defined(SSA_DEBUG_VERBOSE)
998                 if (compileverbose)
999                         printf(" ... not processed \n");
1000 #endif
1001                         continue;
1002                 }
1003                         
1004                 d = VAR(ls->lifetime[lt_d].v_index);
1005                 s = VAR(ls->lifetime[lt_s].v_index);
1006                 
1007
1008                 if (d->type == -1) {
1009 #if defined(SSA_DEBUG_VERBOSE)
1010                         if (compileverbose)
1011                                 printf("...returning - phi lifetimes where joined\n");
1012 #endif
1013                         continue;
1014                 }
1015
1016                 if (s->type == -1) {
1017 #if defined(SSA_DEBUG_VERBOSE)
1018                         if (compileverbose)
1019                                 printf("...returning - phi lifetimes where joined\n");
1020 #endif
1021                         continue;
1022                 }
1023
1024                 tmp_i.opc = 0;
1025                 tmp_i.s1.varindex = ls->lifetime[lt_s].v_index;
1026                 tmp_i.dst.varindex = ls->lifetime[lt_d].v_index;
1027                 emit_copy(jd, &tmp_i);
1028
1029 #if defined(SSA_DEBUG_VERBOSE)
1030                 if (compileverbose) {
1031                         if (IS_INMEMORY(d->flags) && IS_INMEMORY(s->flags)) {
1032                                 /* mem -> mem */
1033                                 printf("M%3i <- M%3i",d->vv.regoff,s->vv.regoff);
1034                         }
1035                         else if (IS_INMEMORY(s->flags)) {
1036                                 /* mem -> reg */
1037                                 printf("R%3i <- M%3i",d->vv.regoff,s->vv.regoff);
1038                         }
1039                         else if (IS_INMEMORY(d->flags)) {
1040                                 /* reg -> mem */
1041                                 printf("M%3i <- R%3i",d->vv.regoff,s->vv.regoff);
1042                         }
1043                         else {
1044                                 /* reg -> reg */
1045                                 printf("R%3i <- R%3i",d->vv.regoff,s->vv.regoff);
1046                         }
1047                         printf("\n");
1048                 }
1049 #endif /* defined(SSA_DEBUG_VERBOSE) */
1050         }
1051 }
1052 #endif /* defined(ENABLE_SSA) */
1053
1054
1055 /* REMOVEME When we have exception handling in C. */
1056
1057 void *md_asm_codegen_get_pv_from_pc(void *ra)
1058 {
1059         return md_codegen_get_pv_from_pc(ra);
1060 }
1061
1062
1063 /*
1064  * These are local overrides for various environment variables in Emacs.
1065  * Please do not remove this and leave it at the end of the file, where
1066  * Emacs will automagically detect them.
1067  * ---------------------------------------------------------------------
1068  * Local variables:
1069  * mode: c++
1070  * indent-tabs-mode: t
1071  * c-basic-offset: 4
1072  * tab-width: 4
1073  * End:
1074  * vim:noexpandtab:sw=4:ts=4:
1075  */