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