* src/toolbox/logging.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.hpp"
58 #include "toolbox/logging.hpp"
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.hpp"
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         // Set flags as requested.
140         if (opt_AlwaysEmitLongBranches) {
141                 cd->flags = CODEGENDATA_FLAG_LONGBRANCHES;
142         }
143         else {
144                 cd->flags = 0;
145         }
146
147         cd->mcodebase    = (u1*) DumpMemory::allocate(MCODEINITSIZE);
148         cd->mcodeend     = cd->mcodebase + MCODEINITSIZE;
149         cd->mcodesize    = MCODEINITSIZE;
150
151         /* initialize mcode variables */
152
153         cd->mcodeptr     = cd->mcodebase;
154         cd->lastmcodeptr = cd->mcodebase;
155
156 #if defined(ENABLE_INTRP)
157         /* native dynamic superinstructions variables */
158
159         if (opt_intrp) {
160                 cd->ncodebase = (u1*) DumpMemory::allocate(NCODEINITSIZE);
161                 cd->ncodesize = NCODEINITSIZE;
162
163                 /* initialize ncode variables */
164         
165                 cd->ncodeptr = cd->ncodebase;
166
167                 cd->lastinstwithoutdispatch = ~0; /* no inst without dispatch */
168                 cd->superstarts = NULL;
169         }
170 #endif
171
172         cd->dseg           = NULL;
173         cd->dseglen        = 0;
174
175         cd->jumpreferences = NULL;
176
177 #if defined(__I386__) || defined(__X86_64__) || defined(__XDSPCORE__) || defined(__M68K__) || defined(ENABLE_INTRP)
178         cd->datareferences = NULL;
179 #endif
180
181         cd->brancheslabel  = new DumpList<branch_label_ref_t*>();
182         cd->linenumbers    = new DumpList<Linenumber>();
183 }
184
185
186 /* codegen_reset ***************************************************************
187
188    Resets the codegen data structure so we can recompile the method.
189
190 *******************************************************************************/
191
192 static void codegen_reset(jitdata *jd)
193 {
194         codeinfo    *code;
195         codegendata *cd;
196         basicblock  *bptr;
197
198         /* get required compiler data */
199
200         code = jd->code;
201         cd   = jd->cd;
202
203         /* reset error flag */
204
205         cd->flags          &= ~CODEGENDATA_FLAG_ERROR;
206
207         /* reset some members, we reuse the code memory already allocated
208            as this should have almost the correct size */
209
210         cd->mcodeptr        = cd->mcodebase;
211         cd->lastmcodeptr    = cd->mcodebase;
212
213         cd->dseg            = NULL;
214         cd->dseglen         = 0;
215
216         cd->jumpreferences  = NULL;
217
218 #if defined(__I386__) || defined(__X86_64__) || defined(__XDSPCORE__) || defined(__M68K__) || defined(ENABLE_INTRP)
219         cd->datareferences  = NULL;
220 #endif
221
222         cd->brancheslabel   = new DumpList<branch_label_ref_t*>();
223         cd->linenumbers     = new DumpList<Linenumber>();
224         
225         /* We need to clear the mpc and the branch references from all
226            basic blocks as they will definitely change. */
227
228         for (bptr = jd->basicblocks; bptr != NULL; bptr = bptr->next) {
229                 bptr->mpc        = -1;
230                 bptr->branchrefs = NULL;
231         }
232
233         /* We need to clear all the patcher references from the codeinfo
234            since they all will be regenerated */
235
236         patcher_list_reset(code);
237
238 #if defined(ENABLE_REPLACEMENT)
239         code->rplpoints     = NULL;
240         code->rplpointcount = 0;
241         code->regalloc      = NULL;
242         code->regalloccount = 0;
243         code->globalcount   = 0;
244 #endif
245 }
246
247
248 /* codegen_generate ************************************************************
249
250    Generates the code for the currently compiled method.
251
252 *******************************************************************************/
253
254 bool codegen_generate(jitdata *jd)
255 {
256         codegendata *cd;
257
258         /* get required compiler data */
259
260         cd = jd->cd;
261
262         /* call the machine-dependent code generation function */
263
264         if (!codegen_emit(jd))
265                 return false;
266
267         /* check for an error */
268
269         if (CODEGENDATA_HAS_FLAG_ERROR(cd)) {
270                 /* check for long-branches flag, if it is set we recompile the
271                    method */
272
273 #if !defined(NDEBUG)
274         if (compileverbose)
275             log_message_method("Re-generating code: ", jd->m);
276 #endif
277
278                 /* XXX maybe we should tag long-branches-methods for recompilation */
279
280                 if (CODEGENDATA_HAS_FLAG_LONGBRANCHES(cd)) {
281                         /* we have to reset the codegendata structure first */
282
283                         codegen_reset(jd);
284
285                         /* and restart the compiler run */
286
287                         if (!codegen_emit(jd))
288                                 return false;
289                 }
290                 else {
291                         vm_abort("codegen_generate: unknown error occurred during codegen_emit: flags=%x\n", cd->flags);
292                 }
293
294 #if !defined(NDEBUG)
295         if (compileverbose)
296             log_message_method("Re-generating code done: ", jd->m);
297 #endif
298         }
299
300         /* reallocate the memory and finish the code generation */
301
302         codegen_finish(jd);
303
304         /* everything's ok */
305
306         return true;
307 }
308
309
310 /* codegen_close ***************************************************************
311
312    TODO
313
314 *******************************************************************************/
315
316 void codegen_close(void)
317 {
318         /* TODO: release avl tree on i386 and x86_64 */
319 }
320
321
322 /* codegen_increase ************************************************************
323
324    Doubles code area.
325
326 *******************************************************************************/
327
328 void codegen_increase(codegendata *cd)
329 {
330         u1 *oldmcodebase;
331
332         /* save old mcodebase pointer */
333
334         oldmcodebase = cd->mcodebase;
335
336         /* reallocate to new, doubled memory */
337
338         cd->mcodebase = (u1*) DumpMemory::reallocate(cd->mcodebase,
339                                                                                                  cd->mcodesize,
340                                                                                                  cd->mcodesize * 2);
341         cd->mcodesize *= 2;
342         cd->mcodeend   = cd->mcodebase + cd->mcodesize;
343
344         /* set new mcodeptr */
345
346         cd->mcodeptr = cd->mcodebase + (cd->mcodeptr - oldmcodebase);
347
348 #if defined(__I386__) || defined(__MIPS__) || defined(__X86_64__) || defined(__M68K__) || defined(ENABLE_INTRP) \
349  || defined(__SPARC_64__)
350         /* adjust the pointer to the last patcher position */
351
352         if (cd->lastmcodeptr != NULL)
353                 cd->lastmcodeptr = cd->mcodebase + (cd->lastmcodeptr - oldmcodebase);
354 #endif
355 }
356
357
358 /* codegen_ncode_increase ******************************************************
359
360    Doubles code area.
361
362 *******************************************************************************/
363
364 #if defined(ENABLE_INTRP)
365 u1 *codegen_ncode_increase(codegendata *cd, u1 *ncodeptr)
366 {
367         u1 *oldncodebase;
368
369         /* save old ncodebase pointer */
370
371         oldncodebase = cd->ncodebase;
372
373         /* reallocate to new, doubled memory */
374
375         cd->ncodebase = DMREALLOC(cd->ncodebase,
376                                                           u1,
377                                                           cd->ncodesize,
378                                                           cd->ncodesize * 2);
379         cd->ncodesize *= 2;
380
381         /* return the new ncodeptr */
382
383         return (cd->ncodebase + (ncodeptr - oldncodebase));
384 }
385 #endif
386
387
388 /* codegen_add_branch_ref ******************************************************
389
390    Prepends an branch to the list.
391
392 *******************************************************************************/
393
394 void codegen_add_branch_ref(codegendata *cd, basicblock *target, s4 condition, s4 reg, u4 options)
395 {
396         branchref *br;
397         s4         branchmpc;
398
399         STATISTICS(count_branches_unresolved++);
400
401         /* calculate the mpc of the branch instruction */
402
403         branchmpc = cd->mcodeptr - cd->mcodebase;
404
405         br = (branchref*) DumpMemory::allocate(sizeof(branchref));
406
407         br->branchmpc = branchmpc;
408         br->condition = condition;
409         br->reg       = reg;
410         br->options   = options;
411         br->next      = target->branchrefs;
412
413         target->branchrefs = br;
414 }
415
416
417 /* codegen_resolve_branchrefs **************************************************
418
419    Resolves and patches the branch references of a given basic block.
420
421 *******************************************************************************/
422
423 void codegen_resolve_branchrefs(codegendata *cd, basicblock *bptr)
424 {
425         branchref *br;
426         u1        *mcodeptr;
427
428         /* Save the mcodeptr because in the branch emitting functions
429            we generate code somewhere inside already generated code,
430            but we're still in the actual code generation phase. */
431
432         mcodeptr = cd->mcodeptr;
433
434         /* just to make sure */
435
436         assert(bptr->mpc >= 0);
437
438         for (br = bptr->branchrefs; br != NULL; br = br->next) {
439                 /* temporary set the mcodeptr */
440
441                 cd->mcodeptr = cd->mcodebase + br->branchmpc;
442
443                 /* emit_bccz and emit_branch emit the correct code, even if we
444                    pass condition == BRANCH_UNCONDITIONAL or reg == -1. */
445
446                 emit_bccz(cd, bptr, br->condition, br->reg, br->options);
447         }
448
449         /* restore mcodeptr */
450
451         cd->mcodeptr = mcodeptr;
452 }
453
454
455 /* codegen_branch_label_add ****************************************************
456
457    Append an branch to the label-branch list.
458
459 *******************************************************************************/
460
461 void codegen_branch_label_add(codegendata *cd, s4 label, s4 condition, s4 reg, u4 options)
462 {
463         // Calculate the current mpc.
464         int32_t mpc = cd->mcodeptr - cd->mcodebase;
465
466         branch_label_ref_t* br = (branch_label_ref_t*) DumpMemory::allocate(sizeof(branch_label_ref_t));
467
468         br->mpc       = mpc;
469         br->label     = label;
470         br->condition = condition;
471         br->reg       = reg;
472         br->options   = options;
473
474         // Add the branch to the list.
475         cd->brancheslabel->push_back(br);
476 }
477
478
479 /* codegen_set_replacement_point_notrap ****************************************
480
481    Record the position of a non-trappable replacement point.
482
483 *******************************************************************************/
484
485 #if defined(ENABLE_REPLACEMENT)
486 #if !defined(NDEBUG)
487 void codegen_set_replacement_point_notrap(codegendata *cd, s4 type)
488 #else
489 void codegen_set_replacement_point_notrap(codegendata *cd)
490 #endif
491 {
492         assert(cd->replacementpoint);
493         assert(cd->replacementpoint->type == type);
494         assert(cd->replacementpoint->flags & RPLPOINT_FLAG_NOTRAP);
495
496         cd->replacementpoint->pc = (u1*) (ptrint) (cd->mcodeptr - cd->mcodebase);
497
498         cd->replacementpoint++;
499 }
500 #endif /* defined(ENABLE_REPLACEMENT) */
501
502
503 /* codegen_set_replacement_point ***********************************************
504
505    Record the position of a trappable replacement point.
506
507 *******************************************************************************/
508
509 #if defined(ENABLE_REPLACEMENT)
510 #if !defined(NDEBUG)
511 void codegen_set_replacement_point(codegendata *cd, s4 type)
512 #else
513 void codegen_set_replacement_point(codegendata *cd)
514 #endif
515 {
516         assert(cd->replacementpoint);
517         assert(cd->replacementpoint->type == type);
518         assert(!(cd->replacementpoint->flags & RPLPOINT_FLAG_NOTRAP));
519
520         cd->replacementpoint->pc = (u1*) (ptrint) (cd->mcodeptr - cd->mcodebase);
521
522         cd->replacementpoint++;
523
524 #if !defined(NDEBUG)
525         /* XXX actually we should use an own REPLACEMENT_NOPS here! */
526         if (opt_TestReplacement)
527                 PATCHER_NOPS;
528 #endif
529
530         /* XXX assert(cd->lastmcodeptr <= cd->mcodeptr); */
531
532         cd->lastmcodeptr = cd->mcodeptr + PATCHER_CALL_SIZE;
533 }
534 #endif /* defined(ENABLE_REPLACEMENT) */
535
536
537 /* codegen_finish **************************************************************
538
539    Finishes the code generation. A new memory, large enough for both
540    data and code, is allocated and data and code are copied together
541    to their final layout, unresolved jumps are resolved, ...
542
543 *******************************************************************************/
544
545 void codegen_finish(jitdata *jd)
546 {
547         codeinfo    *code;
548         codegendata *cd;
549         s4           mcodelen;
550 #if defined(ENABLE_INTRP)
551         s4           ncodelen;
552 #endif
553         s4           alignedmcodelen;
554         jumpref     *jr;
555         u1          *epoint;
556         s4           alignedlen;
557
558         /* get required compiler data */
559
560         code = jd->code;
561         cd   = jd->cd;
562
563         /* prevent compiler warning */
564
565 #if defined(ENABLE_INTRP)
566         ncodelen = 0;
567 #endif
568
569         /* calculate the code length */
570
571         mcodelen = (s4) (cd->mcodeptr - cd->mcodebase);
572
573 #if defined(ENABLE_STATISTICS)
574         if (opt_stat) {
575                 count_code_len += mcodelen;
576                 count_data_len += cd->dseglen;
577         }
578 #endif
579
580         alignedmcodelen = MEMORY_ALIGN(mcodelen, MAX_ALIGN);
581
582 #if defined(ENABLE_INTRP)
583         if (opt_intrp)
584                 ncodelen = cd->ncodeptr - cd->ncodebase;
585         else {
586                 ncodelen = 0; /* avoid compiler warning */
587         }
588 #endif
589
590         cd->dseglen = MEMORY_ALIGN(cd->dseglen, MAX_ALIGN);
591         alignedlen = alignedmcodelen + cd->dseglen;
592
593 #if defined(ENABLE_INTRP)
594         if (opt_intrp) {
595                 alignedlen += ncodelen;
596         }
597 #endif
598
599         /* allocate new memory */
600
601         code->mcodelength = mcodelen + cd->dseglen;
602         code->mcode       = CNEW(u1, alignedlen);
603
604         /* set the entrypoint of the method */
605         
606         assert(code->entrypoint == NULL);
607         code->entrypoint = epoint = (code->mcode + cd->dseglen);
608
609         /* fill the data segment (code->entrypoint must already be set!) */
610
611         dseg_finish(jd);
612
613         /* copy code to the new location */
614
615         MCOPY((void *) code->entrypoint, cd->mcodebase, u1, mcodelen);
616
617 #if defined(ENABLE_INTRP)
618         /* relocate native dynamic superinstruction code (if any) */
619
620         if (opt_intrp) {
621                 cd->mcodebase = code->entrypoint;
622
623                 if (ncodelen > 0) {
624                         u1 *ncodebase = code->mcode + cd->dseglen + alignedmcodelen;
625
626                         MCOPY((void *) ncodebase, cd->ncodebase, u1, ncodelen);
627
628                         /* flush the instruction and data caches */
629
630                         md_cacheflush(ncodebase, ncodelen);
631
632                         /* set some cd variables for dynamic_super_rerwite */
633
634                         cd->ncodebase = ncodebase;
635
636                 } else {
637                         cd->ncodebase = NULL;
638                 }
639
640                 dynamic_super_rewrite(cd);
641         }
642 #endif
643
644         /* Create the exception table. */
645
646         exceptiontable_create(jd);
647
648         /* Create the linenumber table. */
649
650         code->linenumbertable = new LinenumberTable(jd);
651
652         /* jump table resolving */
653
654         for (jr = cd->jumpreferences; jr != NULL; jr = jr->next)
655                 *((functionptr *) ((ptrint) epoint + jr->tablepos)) =
656                         (functionptr) ((ptrint) epoint + (ptrint) jr->target->mpc);
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  */