* src/vm/jit/codegen-common.c: Moved to .cpp.
[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.h"
58 #include "toolbox/logging.h"
59
60 #include "native/llni.h"
61 #include "native/localref.h"
62 #include "native/native.h"
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.h"
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.h"
88 #include "vm/jit/methodheader.h"
89 #include "vm/jit/methodtree.h"
90 #include "vm/jit/patcher-common.h"
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.h"
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  = list_create_dump(OFFSET(branch_label_ref_t, linkage));
176         cd->linenumbers    = list_create_dump(OFFSET(linenumbertable_list_entry_t, linkage));
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   = list_create_dump(OFFSET(branch_label_ref_t, linkage));
217         cd->linenumbers     = list_create_dump(OFFSET(linenumbertable_list_entry_t, linkage));
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         list_t             *l;
458         branch_label_ref_t *br;
459         s4                  mpc;
460
461         /* Get the label list. */
462
463         l = cd->brancheslabel;
464         
465         /* calculate the current mpc */
466
467         mpc = cd->mcodeptr - cd->mcodebase;
468
469         br = (branch_label_ref_t*) DumpMemory::allocate(sizeof(branch_label_ref_t));
470
471         br->mpc       = mpc;
472         br->label     = label;
473         br->condition = condition;
474         br->reg       = reg;
475         br->options   = options;
476
477         /* Add the branch to the list. */
478
479         list_add_last(l, br);
480 }
481
482
483 /* codegen_set_replacement_point_notrap ****************************************
484
485    Record the position of a non-trappable replacement point.
486
487 *******************************************************************************/
488
489 #if defined(ENABLE_REPLACEMENT)
490 #if !defined(NDEBUG)
491 void codegen_set_replacement_point_notrap(codegendata *cd, s4 type)
492 #else
493 void codegen_set_replacement_point_notrap(codegendata *cd)
494 #endif
495 {
496         assert(cd->replacementpoint);
497         assert(cd->replacementpoint->type == type);
498         assert(cd->replacementpoint->flags & RPLPOINT_FLAG_NOTRAP);
499
500         cd->replacementpoint->pc = (u1*) (ptrint) (cd->mcodeptr - cd->mcodebase);
501
502         cd->replacementpoint++;
503 }
504 #endif /* defined(ENABLE_REPLACEMENT) */
505
506
507 /* codegen_set_replacement_point ***********************************************
508
509    Record the position of a trappable replacement point.
510
511 *******************************************************************************/
512
513 #if defined(ENABLE_REPLACEMENT)
514 #if !defined(NDEBUG)
515 void codegen_set_replacement_point(codegendata *cd, s4 type)
516 #else
517 void codegen_set_replacement_point(codegendata *cd)
518 #endif
519 {
520         assert(cd->replacementpoint);
521         assert(cd->replacementpoint->type == type);
522         assert(!(cd->replacementpoint->flags & RPLPOINT_FLAG_NOTRAP));
523
524         cd->replacementpoint->pc = (u1*) (ptrint) (cd->mcodeptr - cd->mcodebase);
525
526         cd->replacementpoint++;
527
528 #if !defined(NDEBUG)
529         /* XXX actually we should use an own REPLACEMENT_NOPS here! */
530         if (opt_TestReplacement)
531                 PATCHER_NOPS;
532 #endif
533
534         /* XXX assert(cd->lastmcodeptr <= cd->mcodeptr); */
535
536         cd->lastmcodeptr = cd->mcodeptr + PATCHER_CALL_SIZE;
537 }
538 #endif /* defined(ENABLE_REPLACEMENT) */
539
540
541 /* codegen_finish **************************************************************
542
543    Finishes the code generation. A new memory, large enough for both
544    data and code, is allocated and data and code are copied together
545    to their final layout, unresolved jumps are resolved, ...
546
547 *******************************************************************************/
548
549 void codegen_finish(jitdata *jd)
550 {
551         codeinfo    *code;
552         codegendata *cd;
553         s4           mcodelen;
554 #if defined(ENABLE_INTRP)
555         s4           ncodelen;
556 #endif
557         s4           alignedmcodelen;
558         jumpref     *jr;
559         u1          *epoint;
560         s4           alignedlen;
561
562         /* get required compiler data */
563
564         code = jd->code;
565         cd   = jd->cd;
566
567         /* prevent compiler warning */
568
569 #if defined(ENABLE_INTRP)
570         ncodelen = 0;
571 #endif
572
573         /* calculate the code length */
574
575         mcodelen = (s4) (cd->mcodeptr - cd->mcodebase);
576
577 #if defined(ENABLE_STATISTICS)
578         if (opt_stat) {
579                 count_code_len += mcodelen;
580                 count_data_len += cd->dseglen;
581         }
582 #endif
583
584         alignedmcodelen = MEMORY_ALIGN(mcodelen, MAX_ALIGN);
585
586 #if defined(ENABLE_INTRP)
587         if (opt_intrp)
588                 ncodelen = cd->ncodeptr - cd->ncodebase;
589         else {
590                 ncodelen = 0; /* avoid compiler warning */
591         }
592 #endif
593
594         cd->dseglen = MEMORY_ALIGN(cd->dseglen, MAX_ALIGN);
595         alignedlen = alignedmcodelen + cd->dseglen;
596
597 #if defined(ENABLE_INTRP)
598         if (opt_intrp) {
599                 alignedlen += ncodelen;
600         }
601 #endif
602
603         /* allocate new memory */
604
605         code->mcodelength = mcodelen + cd->dseglen;
606         code->mcode       = CNEW(u1, alignedlen);
607
608         /* set the entrypoint of the method */
609         
610         assert(code->entrypoint == NULL);
611         code->entrypoint = epoint = (code->mcode + cd->dseglen);
612
613         /* fill the data segment (code->entrypoint must already be set!) */
614
615         dseg_finish(jd);
616
617         /* copy code to the new location */
618
619         MCOPY((void *) code->entrypoint, cd->mcodebase, u1, mcodelen);
620
621 #if defined(ENABLE_INTRP)
622         /* relocate native dynamic superinstruction code (if any) */
623
624         if (opt_intrp) {
625                 cd->mcodebase = code->entrypoint;
626
627                 if (ncodelen > 0) {
628                         u1 *ncodebase = code->mcode + cd->dseglen + alignedmcodelen;
629
630                         MCOPY((void *) ncodebase, cd->ncodebase, u1, ncodelen);
631
632                         /* flush the instruction and data caches */
633
634                         md_cacheflush(ncodebase, ncodelen);
635
636                         /* set some cd variables for dynamic_super_rerwite */
637
638                         cd->ncodebase = ncodebase;
639
640                 } else {
641                         cd->ncodebase = NULL;
642                 }
643
644                 dynamic_super_rewrite(cd);
645         }
646 #endif
647
648         /* Create the exception table. */
649
650         exceptiontable_create(jd);
651
652         /* Create the linenumber table. */
653
654         linenumbertable_create(jd);
655
656         /* jump table resolving */
657
658         for (jr = cd->jumpreferences; jr != NULL; jr = jr->next)
659                 *((functionptr *) ((ptrint) epoint + jr->tablepos)) =
660                         (functionptr) ((ptrint) epoint + (ptrint) jr->target->mpc);
661
662         /* patcher resolving */
663
664         patcher_resolve(jd);
665
666 #if defined(ENABLE_REPLACEMENT)
667         /* replacement point resolving */
668         {
669                 int i;
670                 rplpoint *rp;
671
672                 rp = code->rplpoints;
673                 for (i=0; i<code->rplpointcount; ++i, ++rp) {
674                         rp->pc = (u1*) ((ptrint) epoint + (ptrint) rp->pc);
675                 }
676         }
677 #endif /* defined(ENABLE_REPLACEMENT) */
678
679         /* Insert method into methodtree to find the entrypoint. */
680
681         methodtree_insert(code->entrypoint, code->entrypoint + mcodelen);
682
683 #if defined(__I386__) || defined(__X86_64__) || defined(__XDSPCORE__) || defined(__M68K__) || defined(ENABLE_INTRP)
684         /* resolve data segment references */
685
686         dseg_resolve_datareferences(jd);
687 #endif
688
689         /* flush the instruction and data caches */
690
691         md_cacheflush(code->mcode, code->mcodelength);
692 }
693
694
695 /* codegen_start_native_call ***************************************************
696
697    Prepares the stuff required for a native (JNI) function call:
698
699    - adds a stackframe info structure to the chain, for stacktraces
700    - prepares the local references table on the stack
701
702    The layout of the native stub stackframe should look like this:
703
704    +---------------------------+ <- java SP (of parent Java function)
705    | return address            |
706    +---------------------------+ <- data SP
707    |                           |
708    | stackframe info structure |
709    |                           |
710    +---------------------------+
711    |                           |
712    | local references table    |
713    |                           |
714    +---------------------------+
715    |                           |
716    | saved registers (if any)  |
717    |                           |
718    +---------------------------+
719    |                           |
720    | arguments (if any)        |
721    |                           |
722    +---------------------------+ <- current SP (native stub)
723
724 *******************************************************************************/
725
726 java_handle_t *codegen_start_native_call(u1 *sp, u1 *pv)
727 {
728         stackframeinfo_t *sfi;
729         localref_table   *lrt;
730         methodinfo       *m;
731         int32_t           framesize;
732
733         uint8_t  *datasp;
734         uint8_t  *javasp;
735         uint64_t *arg_regs;
736         uint64_t *arg_stack;
737
738         STATISTICS(count_calls_java_to_native++);
739
740         /* Get the methodinfo. */
741
742         m = code_get_methodinfo_for_pv(pv);
743
744         assert(m);
745
746         framesize = *((int32_t *) (pv + FrameSize));
747
748         assert(framesize >= (int32_t) (sizeof(stackframeinfo_t) + sizeof(localref_table)));
749
750         /* calculate needed values */
751
752 #if defined(__ALPHA__) || defined(__ARM__)
753         datasp    = sp + framesize - SIZEOF_VOID_P;
754         javasp    = sp + framesize;
755         arg_regs  = (uint64_t *) sp;
756         arg_stack = (uint64_t *) javasp;
757 #elif defined(__MIPS__)
758         /* MIPS always uses 8 bytes to store the RA */
759         datasp    = sp + framesize - 8;
760         javasp    = sp + framesize;
761 #elif defined(__S390__)
762         datasp    = sp + framesize - 8;
763         javasp    = sp + framesize;
764         arg_regs  = (uint64_t *) (sp + 96);
765         arg_stack = (uint64_t *) javasp;
766 #elif defined(__I386__) || defined(__M68K__) || defined(__X86_64__)
767         datasp    = sp + framesize;
768         javasp    = sp + framesize + SIZEOF_VOID_P;
769         arg_regs  = (uint64_t *) sp;
770         arg_stack = (uint64_t *) javasp;
771 #elif defined(__POWERPC__)
772         datasp    = sp + framesize;
773         javasp    = sp + framesize;
774         arg_regs  = (uint64_t *) (sp + LA_SIZE + 4 * SIZEOF_VOID_P);
775         arg_stack = (uint64_t *) javasp;
776 #elif defined(__POWERPC64__)
777         datasp    = sp + framesize;
778         javasp    = sp + framesize;
779         arg_regs  = (uint64_t *) (sp + PA_SIZE + LA_SIZE + 4 * SIZEOF_VOID_P);
780         arg_stack = (uint64_t *) javasp;
781 #else
782         /* XXX is was unable to do this port for SPARC64, sorry. (-michi) */
783         /* XXX maybe we need to pass the RA as argument there */
784         vm_abort("codegen_start_native_call: unsupported architecture");
785 #endif
786
787         /* get data structures from stack */
788
789         sfi = (stackframeinfo_t *) (datasp - sizeof(stackframeinfo_t));
790         lrt = (localref_table *)   (datasp - sizeof(stackframeinfo_t) - 
791                                                                 sizeof(localref_table));
792
793 #if defined(ENABLE_JNI)
794         /* add current JNI local references table to this thread */
795
796         localref_table_add(lrt);
797 #endif
798
799 #if !defined(NDEBUG)
800 # if defined(__ALPHA__) || defined(__I386__) || defined(__M68K__) || defined(__POWERPC__) || defined(__POWERPC64__) || defined(__S390__) || defined(__X86_64__)
801         /* print the call-trace if necesarry */
802         /* BEFORE: filling the local reference table */
803
804         if (opt_TraceJavaCalls)
805                 trace_java_call_enter(m, arg_regs, arg_stack);
806 # endif
807 #endif
808
809 #if defined(ENABLE_HANDLES)
810         /* place all references into the local reference table */
811         /* BEFORE: creating stackframeinfo */
812
813         localref_native_enter(m, arg_regs, arg_stack);
814 #endif
815
816         /* Add a stackframeinfo for this native method.  We don't have RA
817            and XPC here.  These are determined in
818            stacktrace_stackframeinfo_add. */
819
820         stacktrace_stackframeinfo_add(sfi, pv, sp, NULL, NULL);
821
822         /* Return a wrapped classinfo for static methods. */
823
824         if (m->flags & ACC_STATIC)
825                 return (java_handle_t *) LLNI_classinfo_wrap(m->clazz);
826         else
827                 return NULL;
828 }
829
830
831 /* codegen_finish_native_call **************************************************
832
833    Removes the stuff required for a native (JNI) function call.
834    Additionally it checks for an exceptions and in case, get the
835    exception object and clear the pointer.
836
837 *******************************************************************************/
838
839 java_object_t *codegen_finish_native_call(u1 *sp, u1 *pv)
840 {
841         stackframeinfo_t *sfi;
842         java_handle_t    *e;
843         java_object_t    *o;
844         codeinfo         *code;
845         methodinfo       *m;
846         int32_t           framesize;
847
848         uint8_t  *datasp;
849         uint64_t *ret_regs;
850
851         /* get information from method header */
852
853         code = code_get_codeinfo_for_pv(pv);
854
855         framesize = *((int32_t *) (pv + FrameSize));
856
857         assert(code);
858
859         /* get the methodinfo */
860
861         m = code->m;
862         assert(m);
863
864         /* calculate needed values */
865
866 #if defined(__ALPHA__) || defined(__ARM__)
867         datasp   = sp + framesize - SIZEOF_VOID_P;
868         ret_regs = (uint64_t *) sp;
869 #elif defined(__MIPS__)
870         /* MIPS always uses 8 bytes to store the RA */
871         datasp   = sp + framesize - 8;
872 #elif defined(__S390__)
873         datasp   = sp + framesize - 8;
874         ret_regs = (uint64_t *) (sp + 96);
875 #elif defined(__I386__)
876         datasp   = sp + framesize;
877         ret_regs = (uint64_t *) (sp + 2 * SIZEOF_VOID_P);
878 #elif defined(__M68K__)
879         datasp   = sp + framesize;
880         ret_regs = (uint64_t *) (sp + 2 * 8);
881 #elif defined(__X86_64__)
882         datasp   = sp + framesize;
883         ret_regs = (uint64_t *) sp;
884 #elif defined(__POWERPC__)
885         datasp   = sp + framesize;
886         ret_regs = (uint64_t *) (sp + LA_SIZE + 2 * SIZEOF_VOID_P);
887 #elif defined(__POWERPC64__)
888         datasp   = sp + framesize;
889         ret_regs = (uint64_t *) (sp + PA_SIZE + LA_SIZE + 2 * SIZEOF_VOID_P);
890 #else
891         vm_abort("codegen_finish_native_call: unsupported architecture");
892 #endif
893
894         /* get data structures from stack */
895
896         sfi = (stackframeinfo_t *) (datasp - sizeof(stackframeinfo_t));
897
898         /* Remove current stackframeinfo from chain. */
899
900         stacktrace_stackframeinfo_remove(sfi);
901
902 #if defined(ENABLE_HANDLES)
903         /* unwrap the return value from the local reference table */
904         /* AFTER: removing the stackframeinfo */
905         /* BEFORE: releasing the local reference table */
906
907         localref_native_exit(m, ret_regs);
908 #endif
909
910         /* get and unwrap the exception */
911         /* AFTER: removing the stackframe info */
912         /* BEFORE: releasing the local reference table */
913
914         e = exceptions_get_and_clear_exception();
915         o = LLNI_UNWRAP(e);
916
917 #if defined(ENABLE_JNI)
918         /* release JNI local references table for this thread */
919
920         localref_frame_pop_all();
921         localref_table_remove();
922 #endif
923
924 #if !defined(NDEBUG)
925 # if defined(__ALPHA__) || defined(__I386__) || defined(__M68K__) || defined(__POWERPC__) || defined(__POWERPC64__) || defined(__S390__) || defined(__X86_64__)
926         /* print the call-trace if necesarry */
927         /* AFTER: unwrapping the return value */
928
929         if (opt_TraceJavaCalls)
930                 trace_java_call_exit(m, ret_regs);
931 # endif
932 #endif
933
934         return o;
935 }
936
937
938 /* codegen_reg_of_var **********************************************************
939
940    This function determines a register, to which the result of an
941    operation should go, when it is ultimatively intended to store the
942    result in pseudoregister v.  If v is assigned to an actual
943    register, this register will be returned.  Otherwise (when v is
944    spilled) this function returns tempregnum.  If not already done,
945    regoff and flags are set in the stack location.
946        
947 *******************************************************************************/
948
949 s4 codegen_reg_of_var(u2 opcode, varinfo *v, s4 tempregnum)
950 {
951         if (!(v->flags & INMEMORY))
952                 return v->vv.regoff;
953
954         return tempregnum;
955 }
956
957
958 /* codegen_reg_of_dst **********************************************************
959
960    This function determines a register, to which the result of an
961    operation should go, when it is ultimatively intended to store the
962    result in iptr->dst.var.  If dst.var is assigned to an actual
963    register, this register will be returned.  Otherwise (when it is
964    spilled) this function returns tempregnum.  If not already done,
965    regoff and flags are set in the stack location.
966        
967 *******************************************************************************/
968
969 s4 codegen_reg_of_dst(jitdata *jd, instruction *iptr, s4 tempregnum)
970 {
971         return codegen_reg_of_var(iptr->opc, VAROP(iptr->dst), tempregnum);
972 }
973
974
975 /* codegen_emit_phi_moves ****************************************************
976
977    Emits phi moves at the end of the basicblock.
978
979 *******************************************************************************/
980
981 #if defined(ENABLE_SSA)
982 void codegen_emit_phi_moves(jitdata *jd, basicblock *bptr)
983 {
984         int lt_d,lt_s,i;
985         lsradata *ls;
986         codegendata *cd;
987         varinfo *s, *d;
988         instruction tmp_i;
989
990         cd = jd->cd;
991         ls = jd->ls;
992
993         MCODECHECK(512);
994
995         /* Moves from phi functions with highest indices have to be */
996         /* inserted first, since this is the order as is used for   */
997         /* conflict resolution */
998
999         for(i = ls->num_phi_moves[bptr->nr] - 1; i >= 0 ; i--) {
1000                 lt_d = ls->phi_moves[bptr->nr][i][0];
1001                 lt_s = ls->phi_moves[bptr->nr][i][1];
1002 #if defined(SSA_DEBUG_VERBOSE)
1003                 if (compileverbose)
1004                         printf("BB %3i Move %3i <- %3i ", bptr->nr, lt_d, lt_s);
1005 #endif
1006                 if (lt_s == UNUSED) {
1007 #if defined(SSA_DEBUG_VERBOSE)
1008                 if (compileverbose)
1009                         printf(" ... not processed \n");
1010 #endif
1011                         continue;
1012                 }
1013                         
1014                 d = VAR(ls->lifetime[lt_d].v_index);
1015                 s = VAR(ls->lifetime[lt_s].v_index);
1016                 
1017
1018                 if (d->type == -1) {
1019 #if defined(SSA_DEBUG_VERBOSE)
1020                         if (compileverbose)
1021                                 printf("...returning - phi lifetimes where joined\n");
1022 #endif
1023                         continue;
1024                 }
1025
1026                 if (s->type == -1) {
1027 #if defined(SSA_DEBUG_VERBOSE)
1028                         if (compileverbose)
1029                                 printf("...returning - phi lifetimes where joined\n");
1030 #endif
1031                         continue;
1032                 }
1033
1034                 tmp_i.opc = 0;
1035                 tmp_i.s1.varindex = ls->lifetime[lt_s].v_index;
1036                 tmp_i.dst.varindex = ls->lifetime[lt_d].v_index;
1037                 emit_copy(jd, &tmp_i);
1038
1039 #if defined(SSA_DEBUG_VERBOSE)
1040                 if (compileverbose) {
1041                         if (IS_INMEMORY(d->flags) && IS_INMEMORY(s->flags)) {
1042                                 /* mem -> mem */
1043                                 printf("M%3i <- M%3i",d->vv.regoff,s->vv.regoff);
1044                         }
1045                         else if (IS_INMEMORY(s->flags)) {
1046                                 /* mem -> reg */
1047                                 printf("R%3i <- M%3i",d->vv.regoff,s->vv.regoff);
1048                         }
1049                         else if (IS_INMEMORY(d->flags)) {
1050                                 /* reg -> mem */
1051                                 printf("M%3i <- R%3i",d->vv.regoff,s->vv.regoff);
1052                         }
1053                         else {
1054                                 /* reg -> reg */
1055                                 printf("R%3i <- R%3i",d->vv.regoff,s->vv.regoff);
1056                         }
1057                         printf("\n");
1058                 }
1059 #endif /* defined(SSA_DEBUG_VERBOSE) */
1060         }
1061 }
1062 #endif /* defined(ENABLE_SSA) */
1063
1064
1065 /* REMOVEME When we have exception handling in C. */
1066
1067 void *md_asm_codegen_get_pv_from_pc(void *ra)
1068 {
1069         return md_codegen_get_pv_from_pc(ra);
1070 }
1071
1072
1073 /*
1074  * These are local overrides for various environment variables in Emacs.
1075  * Please do not remove this and leave it at the end of the file, where
1076  * Emacs will automagically detect them.
1077  * ---------------------------------------------------------------------
1078  * Local variables:
1079  * mode: c++
1080  * indent-tabs-mode: t
1081  * c-basic-offset: 4
1082  * tab-width: 4
1083  * End:
1084  * vim:noexpandtab:sw=4:ts=4:
1085  */