* src/vm/jit/codegen-common.cpp (codegen_start_native_call) [__MIPS__],
[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.hpp"
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 # if SIZEOF_VOID_P == 8
758         arg_regs  = (uint64_t *) sp;
759 # else
760         arg_regs  = (uint64_t *) (sp + 5 * 8);
761 # endif
762         arg_stack = (uint64_t *) javasp;
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(__MIPS__) || 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 # if SIZEOF_VOID_P == 8
875         ret_regs = (uint64_t *) sp;
876 # else
877         ret_regs = (uint64_t *) (sp + 1 * 8);
878 # endif
879 #elif defined(__S390__)
880         datasp   = sp + framesize - 8;
881         ret_regs = (uint64_t *) (sp + 96);
882 #elif defined(__I386__)
883         datasp   = sp + framesize;
884         ret_regs = (uint64_t *) (sp + 2 * SIZEOF_VOID_P);
885 #elif defined(__M68K__)
886         datasp   = sp + framesize;
887         ret_regs = (uint64_t *) (sp + 2 * 8);
888 #elif defined(__X86_64__)
889         datasp   = sp + framesize;
890         ret_regs = (uint64_t *) sp;
891 #elif defined(__POWERPC__)
892         datasp   = sp + framesize;
893         ret_regs = (uint64_t *) (sp + LA_SIZE + 2 * SIZEOF_VOID_P);
894 #elif defined(__POWERPC64__)
895         datasp   = sp + framesize;
896         ret_regs = (uint64_t *) (sp + PA_SIZE + LA_SIZE + 2 * SIZEOF_VOID_P);
897 #else
898         vm_abort("codegen_finish_native_call: unsupported architecture");
899 #endif
900
901         /* get data structures from stack */
902
903         sfi = (stackframeinfo_t *) (datasp - sizeof(stackframeinfo_t));
904
905         /* Remove current stackframeinfo from chain. */
906
907         stacktrace_stackframeinfo_remove(sfi);
908
909 #if defined(ENABLE_HANDLES)
910         /* unwrap the return value from the local reference table */
911         /* AFTER: removing the stackframeinfo */
912         /* BEFORE: releasing the local reference table */
913
914         localref_native_exit(m, ret_regs);
915 #endif
916
917         /* get and unwrap the exception */
918         /* AFTER: removing the stackframe info */
919         /* BEFORE: releasing the local reference table */
920
921         e = exceptions_get_and_clear_exception();
922         o = LLNI_UNWRAP(e);
923
924 #if defined(ENABLE_JNI)
925         /* release JNI local references table for this thread */
926
927         localref_frame_pop_all();
928         localref_table_remove();
929 #endif
930
931 #if !defined(NDEBUG)
932 # if defined(__ALPHA__) || defined(__I386__) || defined(__M68K__) || defined(__MIPS__) || defined(__POWERPC__) || defined(__POWERPC64__) || defined(__S390__) || defined(__X86_64__)
933         /* print the call-trace if necesarry */
934         /* AFTER: unwrapping the return value */
935
936         if (opt_TraceJavaCalls)
937                 trace_java_call_exit(m, ret_regs);
938 # endif
939 #endif
940
941         return o;
942 }
943
944
945 /* codegen_reg_of_var **********************************************************
946
947    This function determines a register, to which the result of an
948    operation should go, when it is ultimatively intended to store the
949    result in pseudoregister v.  If v is assigned to an actual
950    register, this register will be returned.  Otherwise (when v is
951    spilled) this function returns tempregnum.  If not already done,
952    regoff and flags are set in the stack location.
953        
954 *******************************************************************************/
955
956 s4 codegen_reg_of_var(u2 opcode, varinfo *v, s4 tempregnum)
957 {
958         if (!(v->flags & INMEMORY))
959                 return v->vv.regoff;
960
961         return tempregnum;
962 }
963
964
965 /* codegen_reg_of_dst **********************************************************
966
967    This function determines a register, to which the result of an
968    operation should go, when it is ultimatively intended to store the
969    result in iptr->dst.var.  If dst.var is assigned to an actual
970    register, this register will be returned.  Otherwise (when it is
971    spilled) this function returns tempregnum.  If not already done,
972    regoff and flags are set in the stack location.
973        
974 *******************************************************************************/
975
976 s4 codegen_reg_of_dst(jitdata *jd, instruction *iptr, s4 tempregnum)
977 {
978         return codegen_reg_of_var(iptr->opc, VAROP(iptr->dst), tempregnum);
979 }
980
981
982 /* codegen_emit_phi_moves ****************************************************
983
984    Emits phi moves at the end of the basicblock.
985
986 *******************************************************************************/
987
988 #if defined(ENABLE_SSA)
989 void codegen_emit_phi_moves(jitdata *jd, basicblock *bptr)
990 {
991         int lt_d,lt_s,i;
992         lsradata *ls;
993         codegendata *cd;
994         varinfo *s, *d;
995         instruction tmp_i;
996
997         cd = jd->cd;
998         ls = jd->ls;
999
1000         MCODECHECK(512);
1001
1002         /* Moves from phi functions with highest indices have to be */
1003         /* inserted first, since this is the order as is used for   */
1004         /* conflict resolution */
1005
1006         for(i = ls->num_phi_moves[bptr->nr] - 1; i >= 0 ; i--) {
1007                 lt_d = ls->phi_moves[bptr->nr][i][0];
1008                 lt_s = ls->phi_moves[bptr->nr][i][1];
1009 #if defined(SSA_DEBUG_VERBOSE)
1010                 if (compileverbose)
1011                         printf("BB %3i Move %3i <- %3i ", bptr->nr, lt_d, lt_s);
1012 #endif
1013                 if (lt_s == UNUSED) {
1014 #if defined(SSA_DEBUG_VERBOSE)
1015                 if (compileverbose)
1016                         printf(" ... not processed \n");
1017 #endif
1018                         continue;
1019                 }
1020                         
1021                 d = VAR(ls->lifetime[lt_d].v_index);
1022                 s = VAR(ls->lifetime[lt_s].v_index);
1023                 
1024
1025                 if (d->type == -1) {
1026 #if defined(SSA_DEBUG_VERBOSE)
1027                         if (compileverbose)
1028                                 printf("...returning - phi lifetimes where joined\n");
1029 #endif
1030                         continue;
1031                 }
1032
1033                 if (s->type == -1) {
1034 #if defined(SSA_DEBUG_VERBOSE)
1035                         if (compileverbose)
1036                                 printf("...returning - phi lifetimes where joined\n");
1037 #endif
1038                         continue;
1039                 }
1040
1041                 tmp_i.opc = 0;
1042                 tmp_i.s1.varindex = ls->lifetime[lt_s].v_index;
1043                 tmp_i.dst.varindex = ls->lifetime[lt_d].v_index;
1044                 emit_copy(jd, &tmp_i);
1045
1046 #if defined(SSA_DEBUG_VERBOSE)
1047                 if (compileverbose) {
1048                         if (IS_INMEMORY(d->flags) && IS_INMEMORY(s->flags)) {
1049                                 /* mem -> mem */
1050                                 printf("M%3i <- M%3i",d->vv.regoff,s->vv.regoff);
1051                         }
1052                         else if (IS_INMEMORY(s->flags)) {
1053                                 /* mem -> reg */
1054                                 printf("R%3i <- M%3i",d->vv.regoff,s->vv.regoff);
1055                         }
1056                         else if (IS_INMEMORY(d->flags)) {
1057                                 /* reg -> mem */
1058                                 printf("M%3i <- R%3i",d->vv.regoff,s->vv.regoff);
1059                         }
1060                         else {
1061                                 /* reg -> reg */
1062                                 printf("R%3i <- R%3i",d->vv.regoff,s->vv.regoff);
1063                         }
1064                         printf("\n");
1065                 }
1066 #endif /* defined(SSA_DEBUG_VERBOSE) */
1067         }
1068 }
1069 #endif /* defined(ENABLE_SSA) */
1070
1071
1072 /* REMOVEME When we have exception handling in C. */
1073
1074 void *md_asm_codegen_get_pv_from_pc(void *ra)
1075 {
1076         return md_codegen_get_pv_from_pc(ra);
1077 }
1078
1079
1080 /*
1081  * These are local overrides for various environment variables in Emacs.
1082  * Please do not remove this and leave it at the end of the file, where
1083  * Emacs will automagically detect them.
1084  * ---------------------------------------------------------------------
1085  * Local variables:
1086  * mode: c++
1087  * indent-tabs-mode: t
1088  * c-basic-offset: 4
1089  * tab-width: 4
1090  * End:
1091  * vim:noexpandtab:sw=4:ts=4:
1092  */