* src/vm/jit/codegen-common.c (codegen_disassemble_stub): Renamed and works with
[cacao.git] / src / vm / jit / codegen-common.c
1 /* src/vm/jit/codegen-common.c - architecture independent code generator stuff
2
3    Copyright (C) 1996-2005, 2006, 2007 R. Grafl, A. Krall, C. Kruegel,
4    C. Oates, R. Obermaisser, M. Platter, M. Probst, S. Ring,
5    E. Steiner, C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich,
6    J. Wenninger, Institut f. Computersprachen - TU Wien
7
8    This file is part of CACAO.
9
10    This program is free software; you can redistribute it and/or
11    modify it under the terms of the GNU General Public License as
12    published by the Free Software Foundation; either version 2, or (at
13    your option) any later version.
14
15    This program is distributed in the hope that it will be useful, but
16    WITHOUT ANY WARRANTY; without even the implied warranty of
17    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
18    General Public License for more details.
19
20    You should have received a copy of the GNU General Public License
21    along with this program; if not, write to the Free Software
22    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
23    02110-1301, USA.
24
25    All functions assume the following code area / data area layout:
26
27    +-----------+
28    |           |
29    | code area | code area grows to higher addresses
30    |           |
31    +-----------+ <-- start of procedure
32    |           |
33    | data area | data area grows to lower addresses
34    |           |
35    +-----------+
36
37    The functions first write into a temporary code/data area allocated by
38    "codegen_init". "codegen_finish" copies the code and data area into permanent
39    memory. All functions writing values into the data area return the offset
40    relative the begin of the code area (start of procedure).    
41
42 */
43
44
45 #include "config.h"
46
47 #include <assert.h>
48 #include <string.h>
49
50 #include "vm/types.h"
51
52 #if defined(ENABLE_JIT)
53 /* this is required PATCHER_CALL_SIZE */
54 # include "codegen.h"
55 #endif
56
57 #include "md-abi.h"
58
59 #include "mm/memory.h"
60
61 #include "toolbox/avl.h"
62 #include "toolbox/list.h"
63 #include "toolbox/logging.h"
64
65 #include "native/jni.h"
66 #include "native/llni.h"
67 #include "native/localref.h"
68 #include "native/native.h"
69
70 #include "native/include/java_lang_Class.h"
71
72 #include "threads/threads-common.h"
73
74 #include "vm/builtin.h"
75 #include "vm/exceptions.h"
76 #include "vm/stringlocal.h"
77
78 #include "vm/jit/abi.h"
79 #include "vm/jit/asmpart.h"
80 #include "vm/jit/codegen-common.h"
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.h"
88 #include "vm/jit/jit.h"
89 #include "vm/jit/md.h"
90 #include "vm/jit/methodheader.h"
91 #include "vm/jit/patcher-common.h"
92 #include "vm/jit/replace.h"
93 #if defined(ENABLE_SSA)
94 # include "vm/jit/optimizing/lsra.h"
95 # include "vm/jit/optimizing/ssa.h"
96 #endif
97 #include "vm/jit/stacktrace.h"
98 #include "vm/jit/trace.h"
99
100 #if defined(ENABLE_INTRP)
101 #include "vm/jit/intrp/intrp.h"
102 #endif
103
104 #include "vmcore/method.h"
105 #include "vmcore/options.h"
106
107 # include "vmcore/statistics.h"
108
109 #if defined(ENABLE_VMLOG)
110 #include <vmlog_cacao.h>
111 #endif
112
113 #include "show.h"
114
115 /* in this tree we store all method addresses *********************************/
116
117 static avl_tree_t *methodtree = NULL;
118 static s4 methodtree_comparator(const void *treenode, const void *node);
119
120
121 /* codegen_init ****************************************************************
122
123    TODO
124
125 *******************************************************************************/
126
127 void codegen_init(void)
128 {
129         /* this tree is global, not method specific */
130
131         if (!methodtree) {
132 #if defined(ENABLE_JIT)
133                 methodtree_element *mte;
134 #endif
135
136                 methodtree = avl_create(&methodtree_comparator);
137
138 #if defined(ENABLE_JIT)
139                 /* insert asm_vm_call_method */
140
141                 mte = NEW(methodtree_element);
142
143                 mte->startpc = (u1 *) (ptrint) asm_vm_call_method;
144                 mte->endpc   = (u1 *) (ptrint) asm_vm_call_method_end;
145
146                 avl_insert(methodtree, mte);
147 #endif /* defined(ENABLE_JIT) */
148
149         }
150
151 }
152
153
154 /* codegen_setup ***************************************************************
155
156    Allocates and initialises code area, data area and references.
157
158 *******************************************************************************/
159
160 void codegen_setup(jitdata *jd)
161 {
162         methodinfo  *m;
163         codegendata *cd;
164
165         /* get required compiler data */
166
167         m  = jd->m;
168         cd = jd->cd;
169
170         /* initialize members */
171
172         cd->flags        = 0;
173
174         cd->mcodebase    = DMNEW(u1, MCODEINITSIZE);
175         cd->mcodeend     = cd->mcodebase + MCODEINITSIZE;
176         cd->mcodesize    = MCODEINITSIZE;
177
178         /* initialize mcode variables */
179
180         cd->mcodeptr     = cd->mcodebase;
181         cd->lastmcodeptr = cd->mcodebase;
182
183 #if defined(ENABLE_INTRP)
184         /* native dynamic superinstructions variables */
185
186         if (opt_intrp) {
187                 cd->ncodebase = DMNEW(u1, NCODEINITSIZE);
188                 cd->ncodesize = NCODEINITSIZE;
189
190                 /* initialize ncode variables */
191         
192                 cd->ncodeptr = cd->ncodebase;
193
194                 cd->lastinstwithoutdispatch = ~0; /* no inst without dispatch */
195                 cd->superstarts = NULL;
196         }
197 #endif
198
199         cd->dseg           = NULL;
200         cd->dseglen        = 0;
201
202         cd->jumpreferences = NULL;
203
204 #if defined(__I386__) || defined(__X86_64__) || defined(__XDSPCORE__) || defined(__M68K__) || defined(ENABLE_INTRP)
205         cd->datareferences = NULL;
206 #endif
207
208 /*      cd->patchrefs      = list_create_dump(OFFSET(patchref, linkage)); */
209         cd->patchrefs      = NULL;
210         cd->brancheslabel  = list_create_dump(OFFSET(branch_label_ref_t, linkage));
211         cd->listcritical   = list_create_dump(OFFSET(critical_section_ref_t, linkage));
212
213         cd->linenumberreferences = NULL;
214         cd->linenumbertablesizepos = 0;
215         cd->linenumbertablestartpos = 0;
216         cd->linenumbertab = 0;
217 }
218
219
220 /* codegen_reset ***************************************************************
221
222    Resets the codegen data structure so we can recompile the method.
223
224 *******************************************************************************/
225
226 static void codegen_reset(jitdata *jd)
227 {
228         codeinfo    *code;
229         codegendata *cd;
230         basicblock  *bptr;
231
232         /* get required compiler data */
233
234         code = jd->code;
235         cd   = jd->cd;
236
237         /* reset error flag */
238
239         cd->flags          &= ~CODEGENDATA_FLAG_ERROR;
240
241         /* reset some members, we reuse the code memory already allocated
242            as this should have almost the correct size */
243
244         cd->mcodeptr        = cd->mcodebase;
245         cd->lastmcodeptr    = cd->mcodebase;
246
247         cd->dseg            = NULL;
248         cd->dseglen         = 0;
249
250         cd->jumpreferences  = NULL;
251
252 #if defined(__I386__) || defined(__X86_64__) || defined(__XDSPCORE__) || defined(__M68K__) || defined(ENABLE_INTRP)
253         cd->datareferences  = NULL;
254 #endif
255
256 /*      cd->patchrefs       = list_create_dump(OFFSET(patchref, linkage)); */
257         cd->patchrefs       = NULL;
258         cd->brancheslabel   = list_create_dump(OFFSET(branch_label_ref_t, linkage));
259         cd->listcritical    = list_create_dump(OFFSET(critical_section_ref_t, linkage));
260
261         cd->linenumberreferences    = NULL;
262         cd->linenumbertablesizepos  = 0;
263         cd->linenumbertablestartpos = 0;
264         cd->linenumbertab           = 0;
265         
266         /* We need to clear the mpc and the branch references from all
267            basic blocks as they will definitely change. */
268
269         for (bptr = jd->basicblocks; bptr != NULL; bptr = bptr->next) {
270                 bptr->mpc        = -1;
271                 bptr->branchrefs = NULL;
272         }
273
274         /* We need to clear all the patcher references from the codeinfo
275            since they all will be regenerated */
276
277         patcher_list_reset(code);
278
279 #if defined(ENABLE_REPLACEMENT)
280         code->rplpoints     = NULL;
281         code->rplpointcount = 0;
282         code->regalloc      = NULL;
283         code->regalloccount = 0;
284         code->globalcount   = 0;
285 #endif
286 }
287
288
289 /* codegen_generate ************************************************************
290
291    Generates the code for the currently compiled method.
292
293 *******************************************************************************/
294
295 bool codegen_generate(jitdata *jd)
296 {
297         codegendata *cd;
298
299         /* get required compiler data */
300
301         cd = jd->cd;
302
303         /* call the machine-dependent code generation function */
304
305         if (!codegen_emit(jd))
306                 return false;
307
308         /* check for an error */
309
310         if (CODEGENDATA_HAS_FLAG_ERROR(cd)) {
311                 /* check for long-branches flag, if it is set we recompile the
312                    method */
313
314 #if !defined(NDEBUG)
315         if (compileverbose)
316             log_message_method("Re-generating code: ", jd->m);
317 #endif
318
319                 /* XXX maybe we should tag long-branches-methods for recompilation */
320
321                 if (CODEGENDATA_HAS_FLAG_LONGBRANCHES(cd)) {
322                         /* we have to reset the codegendata structure first */
323
324                         codegen_reset(jd);
325
326                         /* and restart the compiler run */
327
328                         if (!codegen_emit(jd))
329                                 return false;
330                 }
331                 else {
332                         vm_abort("codegen_generate: unknown error occurred during codegen_emit: flags=%x\n", cd->flags);
333                 }
334
335 #if !defined(NDEBUG)
336         if (compileverbose)
337             log_message_method("Re-generating code done: ", jd->m);
338 #endif
339         }
340
341         /* reallocate the memory and finish the code generation */
342
343         codegen_finish(jd);
344
345         /* everything's ok */
346
347         return true;
348 }
349
350
351 /* codegen_close ***************************************************************
352
353    TODO
354
355 *******************************************************************************/
356
357 void codegen_close(void)
358 {
359         /* TODO: release avl tree on i386 and x86_64 */
360 }
361
362
363 /* codegen_increase ************************************************************
364
365    Doubles code area.
366
367 *******************************************************************************/
368
369 void codegen_increase(codegendata *cd)
370 {
371         u1 *oldmcodebase;
372
373         /* save old mcodebase pointer */
374
375         oldmcodebase = cd->mcodebase;
376
377         /* reallocate to new, doubled memory */
378
379         cd->mcodebase = DMREALLOC(cd->mcodebase,
380                                                           u1,
381                                                           cd->mcodesize,
382                                                           cd->mcodesize * 2);
383         cd->mcodesize *= 2;
384         cd->mcodeend   = cd->mcodebase + cd->mcodesize;
385
386         /* set new mcodeptr */
387
388         cd->mcodeptr = cd->mcodebase + (cd->mcodeptr - oldmcodebase);
389
390 #if defined(__I386__) || defined(__MIPS__) || defined(__X86_64__) || defined(__M68K__) || defined(ENABLE_INTRP) \
391  || defined(__SPARC_64__)
392         /* adjust the pointer to the last patcher position */
393
394         if (cd->lastmcodeptr != NULL)
395                 cd->lastmcodeptr = cd->mcodebase + (cd->lastmcodeptr - oldmcodebase);
396 #endif
397 }
398
399
400 /* codegen_ncode_increase ******************************************************
401
402    Doubles code area.
403
404 *******************************************************************************/
405
406 #if defined(ENABLE_INTRP)
407 u1 *codegen_ncode_increase(codegendata *cd, u1 *ncodeptr)
408 {
409         u1 *oldncodebase;
410
411         /* save old ncodebase pointer */
412
413         oldncodebase = cd->ncodebase;
414
415         /* reallocate to new, doubled memory */
416
417         cd->ncodebase = DMREALLOC(cd->ncodebase,
418                                                           u1,
419                                                           cd->ncodesize,
420                                                           cd->ncodesize * 2);
421         cd->ncodesize *= 2;
422
423         /* return the new ncodeptr */
424
425         return (cd->ncodebase + (ncodeptr - oldncodebase));
426 }
427 #endif
428
429
430 /* codegen_add_branch_ref ******************************************************
431
432    Prepends an branch to the list.
433
434 *******************************************************************************/
435
436 void codegen_add_branch_ref(codegendata *cd, basicblock *target, s4 condition, s4 reg, u4 options)
437 {
438         branchref *br;
439         s4         branchmpc;
440
441         STATISTICS(count_branches_unresolved++);
442
443         /* calculate the mpc of the branch instruction */
444
445         branchmpc = cd->mcodeptr - cd->mcodebase;
446
447         br = DNEW(branchref);
448
449         br->branchmpc = branchmpc;
450         br->condition = condition;
451         br->reg       = reg;
452         br->options   = options;
453         br->next      = target->branchrefs;
454
455         target->branchrefs = br;
456 }
457
458
459 /* codegen_resolve_branchrefs **************************************************
460
461    Resolves and patches the branch references of a given basic block.
462
463 *******************************************************************************/
464
465 void codegen_resolve_branchrefs(codegendata *cd, basicblock *bptr)
466 {
467         branchref *br;
468         u1        *mcodeptr;
469
470         /* Save the mcodeptr because in the branch emitting functions
471            we generate code somewhere inside already generated code,
472            but we're still in the actual code generation phase. */
473
474         mcodeptr = cd->mcodeptr;
475
476         /* just to make sure */
477
478         assert(bptr->mpc >= 0);
479
480         for (br = bptr->branchrefs; br != NULL; br = br->next) {
481                 /* temporary set the mcodeptr */
482
483                 cd->mcodeptr = cd->mcodebase + br->branchmpc;
484
485                 /* emit_bccz and emit_branch emit the correct code, even if we
486                    pass condition == BRANCH_UNCONDITIONAL or reg == -1. */
487
488                 emit_bccz(cd, bptr, br->condition, br->reg, br->options);
489         }
490
491         /* restore mcodeptr */
492
493         cd->mcodeptr = mcodeptr;
494 }
495
496
497 /* codegen_branch_label_add ****************************************************
498
499    Append an branch to the label-branch list.
500
501 *******************************************************************************/
502
503 void codegen_branch_label_add(codegendata *cd, s4 label, s4 condition, s4 reg, u4 options)
504 {
505         list_t             *list;
506         branch_label_ref_t *br;
507         s4                  mpc;
508
509         /* get the label list */
510
511         list = cd->brancheslabel;
512         
513         /* calculate the current mpc */
514
515         mpc = cd->mcodeptr - cd->mcodebase;
516
517         br = DNEW(branch_label_ref_t);
518
519         br->mpc       = mpc;
520         br->label     = label;
521         br->condition = condition;
522         br->reg       = reg;
523         br->options   = options;
524
525         /* add the branch to the list */
526
527         list_add_last_unsynced(list, br);
528 }
529
530
531 /* codegen_add_patch_ref *******************************************************
532
533    Appends a new patcher reference to the list of patching positions.
534
535 *******************************************************************************/
536
537 void codegen_add_patch_ref(codegendata *cd, functionptr patcher, voidptr ref,
538                                                    s4 disp)
539 {
540         patchref *pr;
541         s4        branchmpc;
542
543         branchmpc = cd->mcodeptr - cd->mcodebase;
544
545         pr = DNEW(patchref);
546
547         pr->branchpos = branchmpc;
548         pr->disp      = disp;
549         pr->patcher   = patcher;
550         pr->ref       = ref;
551
552 /*      list_add_first(cd->patchrefs, pr); */
553         pr->next      = cd->patchrefs;
554         cd->patchrefs = pr;
555
556         /* Generate NOPs for opt_shownops. */
557
558         if (opt_shownops)
559                 PATCHER_NOPS;
560
561 #if defined(ENABLE_JIT) && (defined(__I386__) || defined(__M68K__) || defined(__MIPS__) \
562  || defined(__SPARC_64__) || defined(__X86_64__))
563
564         /* On some architectures the patcher stub call instruction might
565            be longer than the actual instruction generated.  On this
566            architectures we store the last patcher call position and after
567            the basic block code generation is completed, we check the
568            range and maybe generate some nop's. */
569         /* The nops are generated in codegen_emit in each codegen */
570
571         cd->lastmcodeptr = cd->mcodeptr + PATCHER_CALL_SIZE;
572 #endif
573 }
574
575
576 /* codegen_critical_section_new ************************************************
577
578    Allocates a new critical-section reference and adds it to the
579    critical-section list.
580
581 *******************************************************************************/
582
583 #if defined(ENABLE_THREADS)
584 void codegen_critical_section_new(codegendata *cd)
585 {
586         list_t                 *list;
587         critical_section_ref_t *csr;
588         s4                      mpc;
589
590         /* get the critical section list */
591
592         list = cd->listcritical;
593         
594         /* calculate the current mpc */
595
596         mpc = cd->mcodeptr - cd->mcodebase;
597
598         csr = DNEW(critical_section_ref_t);
599
600         /* We only can set restart right now, as start and end are set by
601            the following, corresponding functions. */
602
603         csr->start   = -1;
604         csr->end     = -1;
605         csr->restart = mpc;
606
607         /* add the branch to the list */
608
609         list_add_last_unsynced(list, csr);
610 }
611 #endif
612
613
614 /* codegen_critical_section_start **********************************************
615
616    Set the start-point of the current critical section (which is the
617    last element of the list).
618
619 *******************************************************************************/
620
621 #if defined(ENABLE_THREADS)
622 void codegen_critical_section_start(codegendata *cd)
623 {
624         list_t                 *list;
625         critical_section_ref_t *csr;
626         s4                      mpc;
627
628         /* get the critical section list */
629
630         list = cd->listcritical;
631         
632         /* calculate the current mpc */
633
634         mpc = cd->mcodeptr - cd->mcodebase;
635
636         /* get the current critical section */
637
638         csr = list_last_unsynced(list);
639
640         /* set the start point */
641
642         assert(csr->start == -1);
643
644         csr->start = mpc;
645 }
646 #endif
647
648
649 /* codegen_critical_section_end ************************************************
650
651    Set the end-point of the current critical section (which is the
652    last element of the list).
653
654 *******************************************************************************/
655
656 #if defined(ENABLE_THREADS)
657 void codegen_critical_section_end(codegendata *cd)
658 {
659         list_t                 *list;
660         critical_section_ref_t *csr;
661         s4                      mpc;
662
663         /* get the critical section list */
664
665         list = cd->listcritical;
666         
667         /* calculate the current mpc */
668
669         mpc = cd->mcodeptr - cd->mcodebase;
670
671         /* get the current critical section */
672
673         csr = list_last_unsynced(list);
674
675         /* set the end point */
676
677         assert(csr->end == -1);
678
679         csr->end = mpc;
680 }
681 #endif
682
683
684 /* codegen_critical_section_finish *********************************************
685
686    Finish the critical sections, create the critical section nodes for
687    the AVL tree and insert them into the tree.
688
689 *******************************************************************************/
690
691 #if defined(ENABLE_THREADS)
692 static void codegen_critical_section_finish(jitdata *jd)
693 {
694         codeinfo    *code;
695         codegendata *cd;
696         list_t                  *list;
697         critical_section_ref_t  *csr;
698         critical_section_node_t *csn;
699
700         /* get required compiler data */
701
702         code = jd->code;
703         cd   = jd->cd;
704
705         /* get the critical section list */
706
707         list = cd->listcritical;
708
709         /* iterate over all critical sections */
710
711         for (csr = list_first_unsynced(list); csr != NULL;
712                  csr = list_next_unsynced(list, csr)) {
713                 /* check if all points are set */
714
715                 assert(csr->start   != -1);
716                 assert(csr->end     != -1);
717                 assert(csr->restart != -1);
718
719                 /* allocate tree node */
720
721                 csn = NEW(critical_section_node_t);
722
723                 csn->start   = code->entrypoint + csr->start;
724                 csn->end     = code->entrypoint + csr->end;
725                 csn->restart = code->entrypoint + csr->restart;
726
727                 /* insert into the tree */
728
729                 critical_section_register(csn);
730         }
731 }
732 #endif
733
734
735 /* methodtree_comparator *******************************************************
736
737    Comparator function used for the AVL tree of methods.
738
739    ARGUMENTS:
740       treenode....the node from the tree
741       node........the node to compare to the tree-node
742
743 *******************************************************************************/
744
745 static s4 methodtree_comparator(const void *treenode, const void *node)
746 {
747         methodtree_element *mte;
748         methodtree_element *mtepc;
749
750         mte   = (methodtree_element *) treenode;
751         mtepc = (methodtree_element *) node;
752
753         /* compare both startpc and endpc of pc, even if they have the same value,
754            otherwise the avl_probe sometimes thinks the element is already in the
755            tree */
756
757 #ifdef __S390__
758         /* On S390 addresses are 31 bit. Compare only 31 bits of value.
759          */
760 #       define ADDR_MASK(a) ((a) & 0x7FFFFFFF)
761 #else
762 #       define ADDR_MASK(a) (a)
763 #endif
764
765         if (ADDR_MASK((long) mte->startpc) <= ADDR_MASK((long) mtepc->startpc) &&
766                 ADDR_MASK((long) mtepc->startpc) <= ADDR_MASK((long) mte->endpc) &&
767                 ADDR_MASK((long) mte->startpc) <= ADDR_MASK((long) mtepc->endpc) &&
768                 ADDR_MASK((long) mtepc->endpc) <= ADDR_MASK((long) mte->endpc)) {
769                 return 0;
770
771         } else if (ADDR_MASK((long) mtepc->startpc) < ADDR_MASK((long) mte->startpc)) {
772                 return -1;
773
774         } else {
775                 return 1;
776         }
777
778 #       undef ADDR_MASK
779 }
780
781
782 /* codegen_insertmethod ********************************************************
783
784    Insert the machine code range of a method into the AVL tree of methods.
785
786 *******************************************************************************/
787
788 void codegen_insertmethod(u1 *startpc, u1 *endpc)
789 {
790         methodtree_element *mte;
791
792         /* allocate new method entry */
793
794         mte = NEW(methodtree_element);
795
796         mte->startpc = startpc;
797         mte->endpc   = endpc;
798
799         /* this function does not return an error, but asserts for
800            duplicate entries */
801
802         avl_insert(methodtree, mte);
803 }
804
805
806 /* codegen_get_pv_from_pc ******************************************************
807
808    Find the PV for the given PC by searching in the AVL tree of
809    methods.
810
811 *******************************************************************************/
812
813 u1 *codegen_get_pv_from_pc(u1 *pc)
814 {
815         methodtree_element  mtepc;
816         methodtree_element *mte;
817
818         /* allocation of the search structure on the stack is much faster */
819
820         mtepc.startpc = pc;
821         mtepc.endpc   = pc;
822
823         mte = avl_find(methodtree, &mtepc);
824
825         if (mte == NULL) {
826                 /* No method was found.  Let's dump a stacktrace. */
827
828 #if defined(ENABLE_VMLOG)
829                 vmlog_cacao_signl("SIGSEGV");
830 #endif
831
832                 log_println("We received a SIGSEGV and tried to handle it, but we were");
833                 log_println("unable to find a Java method at:");
834                 log_println("");
835 #if SIZEOF_VOID_P == 8
836                 log_println("PC=0x%016lx", pc);
837 #else
838                 log_println("PC=0x%08x", pc);
839 #endif
840                 log_println("");
841                 assert(0);
842                 log_println("Dumping the current stacktrace:");
843
844 #if defined(ENABLE_THREADS)
845                 /* XXX michi: This should be available even without threads! */
846                 threads_print_stacktrace();
847 #endif
848
849                 vm_abort("Exiting...");
850         }
851
852         return mte->startpc;
853 }
854
855
856 /* codegen_get_pv_from_pc_nocheck **********************************************
857
858    Find the PV for the given PC by searching in the AVL tree of
859    methods.  This method does not check the return value and is used
860    by the profiler.
861
862 *******************************************************************************/
863
864 u1 *codegen_get_pv_from_pc_nocheck(u1 *pc)
865 {
866         methodtree_element  mtepc;
867         methodtree_element *mte;
868
869         /* allocation of the search structure on the stack is much faster */
870
871         mtepc.startpc = pc;
872         mtepc.endpc   = pc;
873
874         mte = avl_find(methodtree, &mtepc);
875
876         if (mte == NULL)
877                 return NULL;
878         else
879                 return mte->startpc;
880 }
881
882
883 /* codegen_set_replacement_point_notrap ****************************************
884
885    Record the position of a non-trappable replacement point.
886
887 *******************************************************************************/
888
889 #if defined(ENABLE_REPLACEMENT)
890 #if !defined(NDEBUG)
891 void codegen_set_replacement_point_notrap(codegendata *cd, s4 type)
892 #else
893 void codegen_set_replacement_point_notrap(codegendata *cd)
894 #endif
895 {
896         assert(cd->replacementpoint);
897         assert(cd->replacementpoint->type == type);
898         assert(cd->replacementpoint->flags & RPLPOINT_FLAG_NOTRAP);
899
900         cd->replacementpoint->pc = (u1*) (ptrint) (cd->mcodeptr - cd->mcodebase);
901
902         cd->replacementpoint++;
903 }
904 #endif /* defined(ENABLE_REPLACEMENT) */
905
906
907 /* codegen_set_replacement_point ***********************************************
908
909    Record the position of a trappable replacement point.
910
911 *******************************************************************************/
912
913 #if defined(ENABLE_REPLACEMENT)
914 #if !defined(NDEBUG)
915 void codegen_set_replacement_point(codegendata *cd, s4 type)
916 #else
917 void codegen_set_replacement_point(codegendata *cd)
918 #endif
919 {
920         assert(cd->replacementpoint);
921         assert(cd->replacementpoint->type == type);
922         assert(!(cd->replacementpoint->flags & RPLPOINT_FLAG_NOTRAP));
923
924         cd->replacementpoint->pc = (u1*) (ptrint) (cd->mcodeptr - cd->mcodebase);
925
926         cd->replacementpoint++;
927
928         /* XXX assert(cd->lastmcodeptr <= cd->mcodeptr); */
929
930         cd->lastmcodeptr = cd->mcodeptr + PATCHER_CALL_SIZE;
931 }
932 #endif /* defined(ENABLE_REPLACEMENT) */
933
934
935 /* codegen_finish **************************************************************
936
937    Finishes the code generation. A new memory, large enough for both
938    data and code, is allocated and data and code are copied together
939    to their final layout, unresolved jumps are resolved, ...
940
941 *******************************************************************************/
942
943 void codegen_finish(jitdata *jd)
944 {
945         codeinfo    *code;
946         codegendata *cd;
947         s4           mcodelen;
948 #if defined(ENABLE_INTRP)
949         s4           ncodelen;
950 #endif
951         s4           alignedmcodelen;
952         jumpref     *jr;
953         patchref_t  *pr;
954         u1          *epoint;
955         s4           alignedlen;
956
957         /* get required compiler data */
958
959         code = jd->code;
960         cd   = jd->cd;
961
962         /* prevent compiler warning */
963
964 #if defined(ENABLE_INTRP)
965         ncodelen = 0;
966 #endif
967
968         /* calculate the code length */
969
970         mcodelen = (s4) (cd->mcodeptr - cd->mcodebase);
971
972 #if defined(ENABLE_STATISTICS)
973         if (opt_stat) {
974                 count_code_len += mcodelen;
975                 count_data_len += cd->dseglen;
976         }
977 #endif
978
979         alignedmcodelen = MEMORY_ALIGN(mcodelen, MAX_ALIGN);
980
981 #if defined(ENABLE_INTRP)
982         if (opt_intrp)
983                 ncodelen = cd->ncodeptr - cd->ncodebase;
984         else {
985                 ncodelen = 0; /* avoid compiler warning */
986         }
987 #endif
988
989         cd->dseglen = MEMORY_ALIGN(cd->dseglen, MAX_ALIGN);
990         alignedlen = alignedmcodelen + cd->dseglen;
991
992 #if defined(ENABLE_INTRP)
993         if (opt_intrp) {
994                 alignedlen += ncodelen;
995         }
996 #endif
997
998         /* allocate new memory */
999
1000         code->mcodelength = mcodelen + cd->dseglen;
1001         code->mcode       = CNEW(u1, alignedlen);
1002
1003         /* set the entrypoint of the method */
1004         
1005         assert(code->entrypoint == NULL);
1006         code->entrypoint = epoint = (code->mcode + cd->dseglen);
1007
1008         /* fill the data segment (code->entrypoint must already be set!) */
1009
1010         dseg_finish(jd);
1011
1012         /* copy code to the new location */
1013
1014         MCOPY((void *) code->entrypoint, cd->mcodebase, u1, mcodelen);
1015
1016 #if defined(ENABLE_INTRP)
1017         /* relocate native dynamic superinstruction code (if any) */
1018
1019         if (opt_intrp) {
1020                 cd->mcodebase = code->entrypoint;
1021
1022                 if (ncodelen > 0) {
1023                         u1 *ncodebase = code->mcode + cd->dseglen + alignedmcodelen;
1024
1025                         MCOPY((void *) ncodebase, cd->ncodebase, u1, ncodelen);
1026
1027                         /* flush the instruction and data caches */
1028
1029                         md_cacheflush(ncodebase, ncodelen);
1030
1031                         /* set some cd variables for dynamic_super_rerwite */
1032
1033                         cd->ncodebase = ncodebase;
1034
1035                 } else {
1036                         cd->ncodebase = NULL;
1037                 }
1038
1039                 dynamic_super_rewrite(cd);
1040         }
1041 #endif
1042
1043         /* jump table resolving */
1044
1045         for (jr = cd->jumpreferences; jr != NULL; jr = jr->next)
1046                 *((functionptr *) ((ptrint) epoint + jr->tablepos)) =
1047                         (functionptr) ((ptrint) epoint + (ptrint) jr->target->mpc);
1048
1049         /* line number table resolving */
1050         {
1051                 linenumberref *lr;
1052                 ptrint lrtlen = 0;
1053                 ptrint target;
1054
1055                 for (lr = cd->linenumberreferences; lr != NULL; lr = lr->next) {
1056                         lrtlen++;
1057                         target = lr->targetmpc;
1058                         /* if the entry contains an mcode pointer (normal case), resolve it */
1059                         /* (see doc/inlining_stacktrace.txt for details)                    */
1060                         if (lr->linenumber >= -2) {
1061                             target += (ptrint) epoint;
1062                         }
1063                         *((functionptr *) ((ptrint) epoint + (ptrint) lr->tablepos)) = 
1064                                 (functionptr) target;
1065                 }
1066                 
1067                 *((functionptr *) ((ptrint) epoint + cd->linenumbertablestartpos)) =
1068                         (functionptr) ((ptrint) epoint + cd->linenumbertab);
1069
1070                 *((ptrint *) ((ptrint) epoint + cd->linenumbertablesizepos)) = lrtlen;
1071         }
1072
1073         /* patcher resolving */
1074
1075         pr = list_first_unsynced(code->patchers);
1076         while (pr) {
1077                 pr->mpc += (ptrint) epoint;
1078                 pr->datap = (ptrint) (pr->disp + epoint);
1079                 pr = list_next_unsynced(code->patchers, pr);
1080         }
1081
1082 #if defined(ENABLE_REPLACEMENT)
1083         /* replacement point resolving */
1084         {
1085                 int i;
1086                 rplpoint *rp;
1087
1088                 rp = code->rplpoints;
1089                 for (i=0; i<code->rplpointcount; ++i, ++rp) {
1090                         rp->pc = (u1*) ((ptrint) epoint + (ptrint) rp->pc);
1091                 }
1092         }
1093 #endif /* defined(ENABLE_REPLACEMENT) */
1094
1095         /* add method into methodtree to find the entrypoint */
1096
1097         codegen_insertmethod(code->entrypoint, code->entrypoint + mcodelen);
1098
1099 #if defined(__I386__) || defined(__X86_64__) || defined(__XDSPCORE__) || defined(__M68K__) || defined(ENABLE_INTRP)
1100         /* resolve data segment references */
1101
1102         dseg_resolve_datareferences(jd);
1103 #endif
1104
1105 #if defined(ENABLE_THREADS)
1106         /* create cirtical sections */
1107
1108         codegen_critical_section_finish(jd);
1109 #endif
1110
1111         /* flush the instruction and data caches */
1112
1113         md_cacheflush(code->mcode, code->mcodelength);
1114 }
1115
1116
1117 /* codegen_generate_stub_compiler **********************************************
1118
1119    Wrapper for codegen_emit_stub_compiler.
1120
1121    Returns:
1122        pointer to the compiler stub code.
1123
1124 *******************************************************************************/
1125
1126 u1 *codegen_generate_stub_compiler(methodinfo *m)
1127 {
1128         jitdata     *jd;
1129         codegendata *cd;
1130         ptrint      *d;                     /* pointer to data memory             */
1131         u1          *c;                     /* pointer to code memory             */
1132         s4           dumpsize;
1133
1134         /* mark dump memory */
1135
1136         dumpsize = dump_size();
1137
1138         /* allocate required data structures */
1139
1140         jd = DNEW(jitdata);
1141
1142         jd->m     = m;
1143         jd->cd    = DNEW(codegendata);
1144         jd->flags = 0;
1145
1146         /* get required compiler data */
1147
1148         cd = jd->cd;
1149
1150         /* allocate code memory */
1151
1152         c = CNEW(u1, 3 * SIZEOF_VOID_P + COMPILERSTUB_CODESIZE);
1153
1154         /* set pointers correctly */
1155
1156         d = (ptrint *) c;
1157
1158         cd->mcodebase = c;
1159
1160         c = c + 3 * SIZEOF_VOID_P;
1161         cd->mcodeptr = c;
1162
1163         /* NOTE: The codeinfo pointer is actually a pointer to the
1164            methodinfo (this fakes a codeinfo structure). */
1165
1166         d[0] = (ptrint) asm_call_jit_compiler;
1167         d[1] = (ptrint) m;
1168         d[2] = (ptrint) &d[1];                                    /* fake code->m */
1169
1170         /* call the emit function */
1171
1172         codegen_emit_stub_compiler(jd);
1173
1174 #if defined(ENABLE_STATISTICS)
1175         if (opt_stat)
1176                 count_cstub_len += 3 * SIZEOF_VOID_P + COMPILERSTUB_CODESIZE;
1177 #endif
1178
1179         /* flush caches */
1180
1181         md_cacheflush(cd->mcodebase, 3 * SIZEOF_VOID_P + COMPILERSTUB_CODESIZE);
1182
1183         /* release dump memory */
1184
1185         dump_release(dumpsize);
1186
1187         /* return native stub code */
1188
1189         return c;
1190 }
1191
1192
1193 /* codegen_generate_stub_builtin ***********************************************
1194
1195    Wrapper for codegen_emit_stub_builtin.
1196
1197 *******************************************************************************/
1198
1199 void codegen_generate_stub_builtin(methodinfo *m, builtintable_entry *bte)
1200 {
1201 #if defined(__ARM__) || defined(__ALPHA__) || defined(__I386__) || defined(__M68K__) || defined(__POWERPC__) || defined(__SPARC64__) || defined(__X86_64__)
1202         jitdata  *jd;
1203         codeinfo *code;
1204         s4        dumpsize;
1205
1206         /* mark dump memory */
1207
1208         dumpsize = dump_size();
1209
1210         jd = DNEW(jitdata);
1211
1212         jd->m     = m;
1213         jd->cd    = DNEW(codegendata);
1214         jd->rd    = NULL;
1215         jd->flags = 0;
1216
1217         /* Allocate codeinfo memory from the heap as we need to keep them. */
1218
1219         jd->code  = code_codeinfo_new(m); /* XXX check allocation */
1220
1221         /* get required compiler data */
1222
1223         code = jd->code;
1224
1225         /* setup code generation stuff */
1226
1227         codegen_setup(jd);
1228
1229         /* generate the code */
1230
1231 #if defined(ENABLE_JIT)
1232 # if defined(ENABLE_INTRP)
1233         if (!opt_intrp) {
1234 # endif
1235                 assert(bte->fp != NULL);
1236                 codegen_emit_stub_native(jd, bte->md, bte->fp);
1237 # if defined(ENABLE_INTRP)
1238         }
1239 # endif
1240 #endif
1241
1242         /* reallocate the memory and finish the code generation */
1243
1244         codegen_finish(jd);
1245
1246         /* set the stub entry point in the builtin table */
1247
1248         bte->stub = code->entrypoint;
1249
1250 #if defined(ENABLE_STATISTICS)
1251         if (opt_stat)
1252                 size_stub_native += code->mcodelength;
1253 #endif
1254
1255 #if !defined(NDEBUG) && defined(ENABLE_DISASSEMBLER)
1256         /* disassemble native stub */
1257
1258         if (opt_DisassembleStubs) {
1259                 codegen_disassemble_stub(m,
1260                                                                  (u1 *) (ptrint) code->entrypoint,
1261                                                                  (u1 *) (ptrint) code->entrypoint + (code->mcodelength - jd->cd->dseglen));
1262
1263                 /* show data segment */
1264
1265                 if (opt_showddatasegment)
1266                         dseg_display(jd);
1267         }
1268 #endif /* !defined(NDEBUG) && defined(ENABLE_DISASSEMBLER) */
1269
1270         /* release memory */
1271
1272         dump_release(dumpsize);
1273 #endif /* architecture list */
1274 }
1275
1276
1277 /* codegen_generate_stub_native ************************************************
1278
1279    Wrapper for codegen_emit_stub_native.
1280
1281    Returns:
1282        the codeinfo representing the stub code.
1283
1284 *******************************************************************************/
1285
1286 codeinfo *codegen_generate_stub_native(methodinfo *m, functionptr f)
1287 {
1288         jitdata     *jd;
1289         codeinfo    *code;
1290         s4           dumpsize;
1291         methoddesc  *md;
1292         methoddesc  *nmd;       
1293         s4           nativeparams;
1294
1295         /* mark dump memory */
1296
1297         dumpsize = dump_size();
1298
1299         jd = DNEW(jitdata);
1300
1301         jd->m     = m;
1302         jd->cd    = DNEW(codegendata);
1303         jd->rd    = DNEW(registerdata);
1304         jd->flags = 0;
1305
1306         /* Allocate codeinfo memory from the heap as we need to keep them. */
1307
1308         jd->code  = code_codeinfo_new(m); /* XXX check allocation */
1309
1310         /* get required compiler data */
1311
1312         code = jd->code;
1313
1314         /* set the flags for the current JIT run */
1315
1316 #if defined(ENABLE_PROFILING)
1317         if (opt_prof)
1318                 jd->flags |= JITDATA_FLAG_INSTRUMENT;
1319 #endif
1320
1321         if (opt_verbosecall)
1322                 jd->flags |= JITDATA_FLAG_VERBOSECALL;
1323
1324         /* setup code generation stuff */
1325
1326 #if defined(ENABLE_JIT)
1327 # if defined(ENABLE_INTRP)
1328         if (!opt_intrp)
1329 # endif
1330                 reg_setup(jd);
1331 #endif
1332
1333         codegen_setup(jd);
1334
1335         /* create new method descriptor with additional native parameters */
1336
1337         md = m->parseddesc;
1338         nativeparams = (m->flags & ACC_STATIC) ? 2 : 1;
1339         
1340         nmd = (methoddesc *) DMNEW(u1, sizeof(methoddesc) - sizeof(typedesc) +
1341                                                            md->paramcount * sizeof(typedesc) +
1342                                                            nativeparams * sizeof(typedesc));
1343
1344         nmd->paramcount = md->paramcount + nativeparams;
1345
1346         nmd->params = DMNEW(paramdesc, nmd->paramcount);
1347
1348         nmd->paramtypes[0].type = TYPE_ADR; /* add environment pointer            */
1349
1350         if (m->flags & ACC_STATIC)
1351                 nmd->paramtypes[1].type = TYPE_ADR; /* add class pointer              */
1352
1353         MCOPY(nmd->paramtypes + nativeparams, md->paramtypes, typedesc,
1354                   md->paramcount);
1355
1356 #if defined(ENABLE_JIT)
1357 # if defined(ENABLE_INTRP)
1358         if (!opt_intrp)
1359 # endif
1360                 /* pre-allocate the arguments for the native ABI */
1361
1362                 md_param_alloc_native(nmd);
1363 #endif
1364
1365         /* generate the code */
1366
1367 #if defined(ENABLE_JIT)
1368 # if defined(ENABLE_INTRP)
1369         if (opt_intrp)
1370                 intrp_createnativestub(f, jd, nmd);
1371         else
1372 # endif
1373                 codegen_emit_stub_native(jd, nmd, f);
1374 #else
1375         intrp_createnativestub(f, jd, nmd);
1376 #endif
1377
1378         /* reallocate the memory and finish the code generation */
1379
1380         codegen_finish(jd);
1381
1382 #if defined(ENABLE_STATISTICS)
1383         /* must be done after codegen_finish() */
1384
1385         if (opt_stat)
1386                 size_stub_native += code->mcodelength;
1387 #endif
1388
1389 #if !defined(NDEBUG) && defined(ENABLE_DISASSEMBLER)
1390         /* disassemble native stub */
1391
1392         if (opt_DisassembleStubs) {
1393 # if defined(ENABLE_DEBUG_FILTER)
1394                 if (m->filtermatches & SHOW_FILTER_FLAG_SHOW_METHOD)
1395 # endif
1396                 {
1397                         codegen_disassemble_stub(m,
1398                                                                          (u1 *) (ptrint) code->entrypoint,
1399                                                                          (u1 *) (ptrint) code->entrypoint + (code->mcodelength - jd->cd->dseglen));
1400
1401                         /* show data segment */
1402
1403                         if (opt_showddatasegment)
1404                                 dseg_display(jd);
1405                 }
1406         }
1407 #endif /* !defined(NDEBUG) && defined(ENABLE_DISASSEMBLER) */
1408
1409         /* release memory */
1410
1411         dump_release(dumpsize);
1412
1413         /* return native stub code */
1414
1415         return code;
1416 }
1417
1418
1419 /* codegen_disassemble_nativestub **********************************************
1420
1421    Disassembles the generated builtin or native stub.
1422
1423 *******************************************************************************/
1424
1425 #if defined(ENABLE_DISASSEMBLER)
1426 void codegen_disassemble_stub(methodinfo *m, u1 *start, u1 *end)
1427 {
1428         printf("Stub code: ");
1429         if (m->class != NULL)
1430                 utf_fprint_printable_ascii_classname(stdout, m->class->name);
1431         else
1432                 printf("NULL");
1433         printf(".");
1434         utf_fprint_printable_ascii(stdout, m->name);
1435         utf_fprint_printable_ascii(stdout, m->descriptor);
1436         printf("\nLength: %d\n\n", (s4) (end - start));
1437
1438         DISASSEMBLE(start, end);
1439 }
1440 #endif
1441
1442
1443 /* codegen_start_native_call ***************************************************
1444
1445    Prepares the stuff required for a native (JNI) function call:
1446
1447    - adds a stackframe info structure to the chain, for stacktraces
1448    - prepares the local references table on the stack
1449
1450    The layout of the native stub stackframe should look like this:
1451
1452    +---------------------------+ <- java SP (of parent Java function)
1453    | return address            |
1454    +---------------------------+ <- data SP
1455    |                           |
1456    | stackframe info structure |
1457    |                           |
1458    +---------------------------+
1459    |                           |
1460    | local references table    |
1461    |                           |
1462    +---------------------------+
1463    |                           |
1464    | saved registers (if any)  |
1465    |                           |
1466    +---------------------------+
1467    |                           |
1468    | arguments (if any)        |
1469    |                           |
1470    +---------------------------+ <- current SP (native stub)
1471
1472 *******************************************************************************/
1473
1474 java_handle_t *codegen_start_native_call(u1 *currentsp, u1 *pv)
1475 {
1476         stackframeinfo *sfi;
1477         localref_table *lrt;
1478         codeinfo       *code;
1479         methodinfo     *m;
1480         int32_t         framesize;
1481
1482         uint8_t  *datasp;
1483         uint8_t  *javasp;
1484         uint8_t  *javara;
1485         uint64_t *arg_regs;
1486         uint64_t *arg_stack;
1487
1488         STATISTICS(count_calls_java_to_native++);
1489
1490         /* get information from method header */
1491
1492         code      = *((codeinfo **) (pv + CodeinfoPointer));
1493         framesize = *((int32_t *)   (pv + FrameSize));
1494         assert(code);
1495         assert(framesize > sizeof(stackframeinfo) + sizeof(localref_table));
1496
1497         /* get the methodinfo */
1498
1499         m = code->m;
1500         assert(m);
1501
1502         /* calculate needed values */
1503
1504 #if defined(__ALPHA__) || defined(__ARM__)
1505         datasp    = currentsp + framesize - SIZEOF_VOID_P;
1506         javasp    = currentsp + framesize;
1507         javara    = *((uint8_t **) datasp);
1508         arg_regs  = (uint64_t *) currentsp;
1509         arg_stack = (uint64_t *) javasp;
1510 #elif defined(__MIPS__) || defined(__S390__)
1511         /* MIPS and S390 always uses 8 bytes to store the RA */
1512         datasp    = currentsp + framesize - 8;
1513         javasp    = currentsp + framesize;
1514         javara    = *((uint8_t **) datasp);
1515 #elif defined(__I386__) || defined (__M68K__) || defined (__X86_64__)
1516         datasp    = currentsp + framesize;
1517         javasp    = currentsp + framesize + SIZEOF_VOID_P;
1518         javara    = *((uint8_t **) datasp);
1519         arg_regs  = (uint64_t *) currentsp;
1520         arg_stack = (uint64_t *) javasp;
1521 #elif defined(__POWERPC__) || defined(__POWERPC64__)
1522         datasp    = currentsp + framesize;
1523         javasp    = currentsp + framesize;
1524         javara    = *((uint8_t **) (datasp + LA_LR_OFFSET));
1525         arg_regs  = (uint64_t *) (currentsp + LA_SIZE + 4 * SIZEOF_VOID_P);
1526         arg_stack = (uint64_t *) javasp;
1527 #else
1528         /* XXX is was unable to do this port for SPARC64, sorry. (-michi) */
1529         /* XXX maybe we need to pass the RA as argument there */
1530         vm_abort("codegen_start_native_call: unsupported architecture");
1531 #endif
1532
1533 #if !defined(NDEBUG)
1534 # if defined(__POWERPC__) || defined (__X86_64__)
1535         /* print the call-trace if necesarry */
1536
1537         if (opt_TraceJavaCalls)
1538                 trace_java_call_enter(m, arg_regs, arg_stack);
1539 # endif
1540 #endif
1541
1542         /* get data structures from stack */
1543
1544         sfi = (stackframeinfo *) (datasp - sizeof(stackframeinfo));
1545         lrt = (localref_table *) (datasp - sizeof(stackframeinfo) - 
1546                                                           sizeof(localref_table));
1547
1548 #if defined(ENABLE_JNI)
1549         /* add current JNI local references table to this thread */
1550
1551         localref_table_add(lrt);
1552 #endif
1553
1554 #if defined(ENABLE_HANDLES)
1555         /* place all references into the local reference table */
1556
1557         localref_fill(m, arg_regs, arg_stack);
1558 #endif
1559
1560         /* add a stackframeinfo to the chain */
1561
1562         stacktrace_create_native_stackframeinfo(sfi, pv, javasp, javara);
1563
1564         /* return a wrapped classinfo for static native methods */
1565
1566         if (m->flags & ACC_STATIC)
1567                 return LLNI_classinfo_wrap(m->class);
1568         else
1569                 return NULL;
1570 }
1571
1572
1573 /* codegen_finish_native_call **************************************************
1574
1575    Removes the stuff required for a native (JNI) function call.
1576    Additionally it checks for an exceptions and in case, get the
1577    exception object and clear the pointer.
1578
1579 *******************************************************************************/
1580
1581 java_object_t *codegen_finish_native_call(u1 *currentsp, u1 *pv)
1582 {
1583         stackframeinfo *sfi;
1584         java_handle_t  *e;
1585         java_object_t  *o;
1586         codeinfo       *code;
1587         methodinfo     *m;
1588         int32_t         framesize;
1589
1590         uint8_t  *datasp;
1591         uint64_t *ret_regs;
1592
1593         /* get information from method header */
1594
1595         code      = *((codeinfo **) (pv + CodeinfoPointer));
1596         framesize = *((int32_t *)   (pv + FrameSize));
1597         assert(code);
1598
1599         /* get the methodinfo */
1600
1601         m = code->m;
1602         assert(m);
1603
1604         /* calculate needed values */
1605
1606 #if defined(__ALPHA__) || defined(__ARM__)
1607         datasp   = currentsp + framesize - SIZEOF_VOID_P;
1608         ret_regs = (uint64_t *) currentsp;
1609 #elif defined(__MIPS__) || defined(__S390__)
1610         /* MIPS and S390 always uses 8 bytes to store the RA */
1611         datasp   = currentsp + framesize - 8;
1612 #elif defined(__I386__)
1613         datasp   = currentsp + framesize;
1614         ret_regs = (uint64_t *) (currentsp + 2 * SIZEOF_VOID_P);
1615 #elif defined (__M68K__) || defined (__X86_64__)
1616         datasp   = currentsp + framesize;
1617         ret_regs = (uint64_t *) currentsp;
1618 #elif defined(__POWERPC__) || defined(__POWERPC64__)
1619         datasp   = currentsp + framesize;
1620         ret_regs = (uint64_t *) (currentsp + LA_SIZE + 2 * SIZEOF_VOID_P);
1621 #else
1622         vm_abort("codegen_finish_native_call: unsupported architecture");
1623 #endif
1624
1625
1626 #if !defined(NDEBUG)
1627 # if defined(__POWERPC__) || defined (__X86_64__)
1628         /* print the call-trace if necesarry */
1629
1630         if (opt_TraceJavaCalls)
1631                 trace_java_call_exit(m, ret_regs);
1632 # endif
1633 #endif
1634
1635         /* get data structures from stack */
1636
1637         sfi = (stackframeinfo *) (datasp - sizeof(stackframeinfo));
1638
1639         /* remove current stackframeinfo from chain */
1640
1641         stacktrace_remove_stackframeinfo(sfi);
1642
1643         /* XXX unfill lrt here!!! */
1644
1645         /* get and unwrap the exception */
1646         /* ATTENTION: do the this _after_ the stackframeinfo was
1647        removed but _before_ the localref_table gets removed! */
1648
1649         e = exceptions_get_and_clear_exception();
1650         o = LLNI_UNWRAP(e);
1651
1652 #if defined(ENABLE_JNI)
1653         /* release JNI local references table for this thread */
1654
1655         localref_frame_pop_all();
1656         localref_table_remove();
1657 #endif
1658
1659         return o;
1660 }
1661
1662
1663 /* removecompilerstub **********************************************************
1664
1665    Deletes a compilerstub from memory (simply by freeing it).
1666
1667 *******************************************************************************/
1668
1669 void removecompilerstub(u1 *stub)
1670 {
1671         /* pass size 1 to keep the intern function happy */
1672
1673         CFREE((void *) stub, 1);
1674 }
1675
1676
1677 /* removenativestub ************************************************************
1678
1679    Removes a previously created native-stub from memory.
1680     
1681 *******************************************************************************/
1682
1683 void removenativestub(u1 *stub)
1684 {
1685         /* pass size 1 to keep the intern function happy */
1686
1687         CFREE((void *) stub, 1);
1688 }
1689
1690
1691 /* codegen_reg_of_var **********************************************************
1692
1693    This function determines a register, to which the result of an
1694    operation should go, when it is ultimatively intended to store the
1695    result in pseudoregister v.  If v is assigned to an actual
1696    register, this register will be returned.  Otherwise (when v is
1697    spilled) this function returns tempregnum.  If not already done,
1698    regoff and flags are set in the stack location.
1699        
1700 *******************************************************************************/
1701
1702 s4 codegen_reg_of_var(u2 opcode, varinfo *v, s4 tempregnum)
1703 {
1704
1705 #if 0
1706         /* Do we have to generate a conditional move?  Yes, then always
1707            return the temporary register.  The real register is identified
1708            during the store. */
1709
1710         if (opcode & ICMD_CONDITION_MASK)
1711                 return tempregnum;
1712 #endif
1713
1714         if (!(v->flags & INMEMORY))
1715                 return v->vv.regoff;
1716
1717         return tempregnum;
1718 }
1719
1720
1721 /* codegen_reg_of_dst **********************************************************
1722
1723    This function determines a register, to which the result of an
1724    operation should go, when it is ultimatively intended to store the
1725    result in iptr->dst.var.  If dst.var is assigned to an actual
1726    register, this register will be returned.  Otherwise (when it is
1727    spilled) this function returns tempregnum.  If not already done,
1728    regoff and flags are set in the stack location.
1729        
1730 *******************************************************************************/
1731
1732 s4 codegen_reg_of_dst(jitdata *jd, instruction *iptr, s4 tempregnum)
1733 {
1734         return codegen_reg_of_var(iptr->opc, VAROP(iptr->dst), tempregnum);
1735 }
1736
1737
1738 /* codegen_emit_phi_moves ****************************************************
1739
1740    Emits phi moves at the end of the basicblock.
1741
1742 *******************************************************************************/
1743
1744 #if defined(ENABLE_SSA)
1745 void codegen_emit_phi_moves(jitdata *jd, basicblock *bptr)
1746 {
1747         int lt_d,lt_s,i;
1748         lsradata *ls;
1749         codegendata *cd;
1750         varinfo *s, *d;
1751         instruction tmp_i;
1752
1753         cd = jd->cd;
1754         ls = jd->ls;
1755
1756         MCODECHECK(512);
1757
1758         /* Moves from phi functions with highest indices have to be */
1759         /* inserted first, since this is the order as is used for   */
1760         /* conflict resolution */
1761
1762         for(i = ls->num_phi_moves[bptr->nr] - 1; i >= 0 ; i--) {
1763                 lt_d = ls->phi_moves[bptr->nr][i][0];
1764                 lt_s = ls->phi_moves[bptr->nr][i][1];
1765 #if defined(SSA_DEBUG_VERBOSE)
1766                 if (compileverbose)
1767                         printf("BB %3i Move %3i <- %3i ", bptr->nr, lt_d, lt_s);
1768 #endif
1769                 if (lt_s == UNUSED) {
1770 #if defined(SSA_DEBUG_VERBOSE)
1771                 if (compileverbose)
1772                         printf(" ... not processed \n");
1773 #endif
1774                         continue;
1775                 }
1776                         
1777                 d = VAR(ls->lifetime[lt_d].v_index);
1778                 s = VAR(ls->lifetime[lt_s].v_index);
1779                 
1780
1781                 if (d->type == -1) {
1782 #if defined(SSA_DEBUG_VERBOSE)
1783                         if (compileverbose)
1784                                 printf("...returning - phi lifetimes where joined\n");
1785 #endif
1786                         return;
1787                 }
1788
1789                 if (s->type == -1) {
1790 #if defined(SSA_DEBUG_VERBOSE)
1791                         if (compileverbose)
1792                                 printf("...returning - phi lifetimes where joined\n");
1793 #endif
1794                         return;
1795                 }
1796
1797                 tmp_i.opc = 0;
1798                 tmp_i.s1.varindex = ls->lifetime[lt_s].v_index;
1799                 tmp_i.dst.varindex = ls->lifetime[lt_d].v_index;
1800                 emit_copy(jd, &tmp_i);
1801
1802 #if defined(SSA_DEBUG_VERBOSE)
1803                 if (compileverbose) {
1804                         if (IS_INMEMORY(d->flags) && IS_INMEMORY(s->flags)) {
1805                                 /* mem -> mem */
1806                                 printf("M%3i <- M%3i",d->vv.regoff,s->vv.regoff);
1807                         }
1808                         else if (IS_INMEMORY(s->flags)) {
1809                                 /* mem -> reg */
1810                                 printf("R%3i <- M%3i",d->vv.regoff,s->vv.regoff);
1811                         }
1812                         else if (IS_INMEMORY(d->flags)) {
1813                                 /* reg -> mem */
1814                                 printf("M%3i <- R%3i",d->vv.regoff,s->vv.regoff);
1815                         }
1816                         else {
1817                                 /* reg -> reg */
1818                                 printf("R%3i <- R%3i",d->vv.regoff,s->vv.regoff);
1819                         }
1820                         printf("\n");
1821                 }
1822 #endif /* defined(SSA_DEBUG_VERBOSE) */
1823         }
1824 }
1825 #endif /* defined(ENABLE_SSA) */
1826
1827
1828
1829 /*
1830  * These are local overrides for various environment variables in Emacs.
1831  * Please do not remove this and leave it at the end of the file, where
1832  * Emacs will automagically detect them.
1833  * ---------------------------------------------------------------------
1834  * Local variables:
1835  * mode: c
1836  * indent-tabs-mode: t
1837  * c-basic-offset: 4
1838  * tab-width: 4
1839  * End:
1840  * vim:noexpandtab:sw=4:ts=4:
1841  */