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