* merged with tip (040f180a056b)
[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, 2008
4    CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
5
6    This file is part of CACAO.
7
8    This program is free software; you can redistribute it and/or
9    modify it under the terms of the GNU General Public License as
10    published by the Free Software Foundation; either version 2, or (at
11    your option) any later version.
12
13    This program is distributed in the hope that it will be useful, but
14    WITHOUT ANY WARRANTY; without even the implied warranty of
15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16    General Public License for more details.
17
18    You should have received a copy of the GNU General Public License
19    along with this program; if not, write to the Free Software
20    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
21    02110-1301, USA.
22
23    All functions assume the following code area / data area layout:
24
25    +-----------+
26    |           |
27    | code area | code area grows to higher addresses
28    |           |
29    +-----------+ <-- start of procedure
30    |           |
31    | data area | data area grows to lower addresses
32    |           |
33    +-----------+
34
35    The functions first write into a temporary code/data area allocated by
36    "codegen_init". "codegen_finish" copies the code and data area into permanent
37    memory. All functions writing values into the data area return the offset
38    relative the begin of the code area (start of procedure).    
39
40 */
41
42
43 #include "config.h"
44
45 #include <assert.h>
46 #include <string.h>
47
48 #include "vm/jit/jitcache.h"
49
50 #include "vm/types.h"
51
52 #include "codegen.h"
53 #include "md.h"
54 #include "md-abi.h"
55
56 #include "mm/memory.h"
57
58 #include "toolbox/avl.h"
59 #include "toolbox/list.h"
60 #include "toolbox/logging.h"
61
62 #include "native/jni.h"
63 #include "native/llni.h"
64 #include "native/localref.h"
65 #include "native/native.h"
66
67 #include "threads/thread.hpp"
68
69 #include "vm/builtin.h"
70 #include "vm/exceptions.hpp"
71 #include "vm/method.h"
72 #include "vm/options.h"
73 #include "vm/string.hpp"
74
75 # include "vm/statistics.h"
76
77
78 #include "vm/jit/abi.h"
79 #include "vm/jit/asmpart.h"
80 #include "vm/jit/code.h"
81 #include "vm/jit/codegen-common.h"
82
83 #if defined(ENABLE_DISASSEMBLER)
84 # include "vm/jit/disass.h"
85 #endif
86
87 #include "vm/jit/dseg.h"
88 #include "vm/jit/emit-common.h"
89 #include "vm/jit/jit.h"
90 #include "vm/jit/linenumbertable.h"
91 #include "vm/jit/methodheader.h"
92 #include "vm/jit/methodtree.h"
93 #include "vm/jit/patcher-common.h"
94 #include "vm/jit/replace.h"
95 #if defined(ENABLE_SSA)
96 # include "vm/jit/optimizing/lsra.h"
97 # include "vm/jit/optimizing/ssa.h"
98 #endif
99 #include "vm/jit/stacktrace.hpp"
100 #include "vm/jit/trace.hpp"
101
102 #if defined(ENABLE_INTRP)
103 #include "vm/jit/intrp/intrp.h"
104 #endif
105
106 #if defined(ENABLE_VMLOG)
107 #include <vmlog_cacao.h>
108 #endif
109
110 #include "show.h"
111
112
113 /* codegen_init ****************************************************************
114
115    TODO
116
117 *******************************************************************************/
118
119 void codegen_init(void)
120 {
121 }
122
123
124 /* codegen_setup ***************************************************************
125
126    Allocates and initialises code area, data area and references.
127
128 *******************************************************************************/
129
130 void codegen_setup(jitdata *jd)
131 {
132         methodinfo  *m;
133         codegendata *cd;
134
135         /* get required compiler data */
136
137         m  = jd->m;
138         cd = jd->cd;
139
140         /* initialize members */
141
142         cd->flags        = 0;
143
144         cd->mcodebase    = DMNEW(u1, MCODEINITSIZE);
145         cd->mcodeend     = cd->mcodebase + MCODEINITSIZE;
146         cd->mcodesize    = MCODEINITSIZE;
147
148         /* initialize mcode variables */
149
150         cd->mcodeptr     = cd->mcodebase;
151         cd->lastmcodeptr = cd->mcodebase;
152
153 #if defined(ENABLE_INTRP)
154         /* native dynamic superinstructions variables */
155
156         if (opt_intrp) {
157                 cd->ncodebase = DMNEW(u1, NCODEINITSIZE);
158                 cd->ncodesize = NCODEINITSIZE;
159
160                 /* initialize ncode variables */
161         
162                 cd->ncodeptr = cd->ncodebase;
163
164                 cd->lastinstwithoutdispatch = ~0; /* no inst without dispatch */
165                 cd->superstarts = NULL;
166         }
167 #endif
168
169         cd->dseg           = NULL;
170         cd->dseglen        = 0;
171
172         cd->jumpreferences = NULL;
173
174 #if defined(__I386__) || defined(__X86_64__) || defined(__XDSPCORE__) || defined(__M68K__) || defined(ENABLE_INTRP)
175         cd->datareferences = NULL;
176 #endif
177
178         cd->brancheslabel  = list_create_dump(OFFSET(branch_label_ref_t, linkage));
179         cd->linenumbers    = list_create_dump(OFFSET(linenumbertable_list_entry_t, linkage));
180 }
181
182
183 /* codegen_reset ***************************************************************
184
185    Resets the codegen data structure so we can recompile the method.
186
187 *******************************************************************************/
188
189 static void codegen_reset(jitdata *jd)
190 {
191         codeinfo    *code;
192         codegendata *cd;
193         basicblock  *bptr;
194
195         /* get required compiler data */
196
197         code = jd->code;
198         cd   = jd->cd;
199
200         /* reset error flag */
201
202         cd->flags          &= ~CODEGENDATA_FLAG_ERROR;
203
204         /* reset some members, we reuse the code memory already allocated
205            as this should have almost the correct size */
206
207         cd->mcodeptr        = cd->mcodebase;
208         cd->lastmcodeptr    = cd->mcodebase;
209
210         cd->dseg            = NULL;
211         cd->dseglen         = 0;
212
213         cd->jumpreferences  = NULL;
214
215 #if defined(__I386__) || defined(__X86_64__) || defined(__XDSPCORE__) || defined(__M68K__) || defined(ENABLE_INTRP)
216         cd->datareferences  = NULL;
217 #endif
218
219         cd->brancheslabel   = list_create_dump(OFFSET(branch_label_ref_t, linkage));
220         cd->linenumbers     = list_create_dump(OFFSET(linenumbertable_list_entry_t, linkage));
221         
222         /* We need to clear the mpc and the branch references from all
223            basic blocks as they will definitely change. */
224
225         for (bptr = jd->basicblocks; bptr != NULL; bptr = bptr->next) {
226                 bptr->mpc        = -1;
227                 bptr->branchrefs = NULL;
228         }
229
230         /* We need to clear all the patcher references from the codeinfo
231            since they all will be regenerated */
232
233         patcher_list_reset(code);
234
235 #if defined(ENABLE_REPLACEMENT)
236         code->rplpoints     = NULL;
237         code->rplpointcount = 0;
238         code->regalloc      = NULL;
239         code->regalloccount = 0;
240         code->globalcount   = 0;
241 #endif
242 }
243
244
245 /* codegen_generate ************************************************************
246
247    Generates the code for the currently compiled method.
248
249 *******************************************************************************/
250
251 bool codegen_generate(jitdata *jd)
252 {
253         codegendata *cd;
254
255         /* get required compiler data */
256
257         cd = jd->cd;
258
259         /* call the machine-dependent code generation function */
260
261         if (!codegen_emit(jd))
262                 return false;
263
264         /* check for an error */
265
266         if (CODEGENDATA_HAS_FLAG_ERROR(cd)) {
267                 /* check for long-branches flag, if it is set we recompile the
268                    method */
269
270 #if !defined(NDEBUG)
271         if (compileverbose)
272             log_message_method("Re-generating code: ", jd->m);
273 #endif
274
275                 /* XXX maybe we should tag long-branches-methods for recompilation */
276
277                 if (CODEGENDATA_HAS_FLAG_LONGBRANCHES(cd)) {
278                         /* we have to reset the codegendata structure first */
279
280                         codegen_reset(jd);
281
282                         /* and restart the compiler run */
283
284                         if (!codegen_emit(jd))
285                                 return false;
286                 }
287                 else {
288                         vm_abort("codegen_generate: unknown error occurred during codegen_emit: flags=%x\n", cd->flags);
289                 }
290
291 #if !defined(NDEBUG)
292         if (compileverbose)
293             log_message_method("Re-generating code done: ", jd->m);
294 #endif
295         }
296
297         /* reallocate the memory and finish the code generation */
298
299         codegen_finish(jd);
300
301         /* everything's ok */
302
303         return true;
304 }
305
306
307 /* codegen_close ***************************************************************
308
309    TODO
310
311 *******************************************************************************/
312
313 void codegen_close(void)
314 {
315         /* TODO: release avl tree on i386 and x86_64 */
316 }
317
318
319 /* codegen_increase ************************************************************
320
321    Doubles code area.
322
323 *******************************************************************************/
324
325 void codegen_increase(codegendata *cd)
326 {
327         u1 *oldmcodebase;
328
329         /* save old mcodebase pointer */
330
331         oldmcodebase = cd->mcodebase;
332
333         /* reallocate to new, doubled memory */
334
335         cd->mcodebase = DMREALLOC(cd->mcodebase,
336                                                           u1,
337                                                           cd->mcodesize,
338                                                           cd->mcodesize * 2);
339         cd->mcodesize *= 2;
340         cd->mcodeend   = cd->mcodebase + cd->mcodesize;
341
342         /* set new mcodeptr */
343
344         cd->mcodeptr = cd->mcodebase + (cd->mcodeptr - oldmcodebase);
345
346 #if defined(__I386__) || defined(__MIPS__) || defined(__X86_64__) || defined(__M68K__) || defined(ENABLE_INTRP) \
347  || defined(__SPARC_64__)
348         /* adjust the pointer to the last patcher position */
349
350         if (cd->lastmcodeptr != NULL)
351                 cd->lastmcodeptr = cd->mcodebase + (cd->lastmcodeptr - oldmcodebase);
352 #endif
353 }
354
355
356 /* codegen_ncode_increase ******************************************************
357
358    Doubles code area.
359
360 *******************************************************************************/
361
362 #if defined(ENABLE_INTRP)
363 u1 *codegen_ncode_increase(codegendata *cd, u1 *ncodeptr)
364 {
365         u1 *oldncodebase;
366
367         /* save old ncodebase pointer */
368
369         oldncodebase = cd->ncodebase;
370
371         /* reallocate to new, doubled memory */
372
373         cd->ncodebase = DMREALLOC(cd->ncodebase,
374                                                           u1,
375                                                           cd->ncodesize,
376                                                           cd->ncodesize * 2);
377         cd->ncodesize *= 2;
378
379         /* return the new ncodeptr */
380
381         return (cd->ncodebase + (ncodeptr - oldncodebase));
382 }
383 #endif
384
385
386 /* codegen_add_branch_ref ******************************************************
387
388    Prepends an branch to the list.
389
390 *******************************************************************************/
391
392 void codegen_add_branch_ref(codegendata *cd, basicblock *target, s4 condition, s4 reg, u4 options)
393 {
394         branchref *br;
395         s4         branchmpc;
396
397         STATISTICS(count_branches_unresolved++);
398
399         /* calculate the mpc of the branch instruction */
400
401         branchmpc = cd->mcodeptr - cd->mcodebase;
402
403         br = DNEW(branchref);
404
405         br->branchmpc = branchmpc;
406         br->condition = condition;
407         br->reg       = reg;
408         br->options   = options;
409         br->next      = target->branchrefs;
410
411         target->branchrefs = br;
412 }
413
414
415 /* codegen_resolve_branchrefs **************************************************
416
417    Resolves and patches the branch references of a given basic block.
418
419 *******************************************************************************/
420
421 void codegen_resolve_branchrefs(codegendata *cd, basicblock *bptr)
422 {
423         branchref *br;
424         u1        *mcodeptr;
425
426         /* Save the mcodeptr because in the branch emitting functions
427            we generate code somewhere inside already generated code,
428            but we're still in the actual code generation phase. */
429
430         mcodeptr = cd->mcodeptr;
431
432         /* just to make sure */
433
434         assert(bptr->mpc >= 0);
435
436         for (br = bptr->branchrefs; br != NULL; br = br->next) {
437                 /* temporary set the mcodeptr */
438
439                 cd->mcodeptr = cd->mcodebase + br->branchmpc;
440
441                 /* emit_bccz and emit_branch emit the correct code, even if we
442                    pass condition == BRANCH_UNCONDITIONAL or reg == -1. */
443
444                 emit_bccz(cd, bptr, br->condition, br->reg, br->options);
445         }
446
447         /* restore mcodeptr */
448
449         cd->mcodeptr = mcodeptr;
450 }
451
452
453 /* codegen_branch_label_add ****************************************************
454
455    Append an branch to the label-branch list.
456
457 *******************************************************************************/
458
459 void codegen_branch_label_add(codegendata *cd, s4 label, s4 condition, s4 reg, u4 options)
460 {
461         list_t             *l;
462         branch_label_ref_t *br;
463         s4                  mpc;
464
465         /* Get the label list. */
466
467         l = cd->brancheslabel;
468         
469         /* calculate the current mpc */
470
471         mpc = cd->mcodeptr - cd->mcodebase;
472
473         br = DNEW(branch_label_ref_t);
474
475         br->mpc       = mpc;
476         br->label     = label;
477         br->condition = condition;
478         br->reg       = reg;
479         br->options   = options;
480
481         /* Add the branch to the list. */
482
483         list_add_last(l, br);
484 }
485
486
487 /* codegen_set_replacement_point_notrap ****************************************
488
489    Record the position of a non-trappable replacement point.
490
491 *******************************************************************************/
492
493 #if defined(ENABLE_REPLACEMENT)
494 #if !defined(NDEBUG)
495 void codegen_set_replacement_point_notrap(codegendata *cd, s4 type)
496 #else
497 void codegen_set_replacement_point_notrap(codegendata *cd)
498 #endif
499 {
500         assert(cd->replacementpoint);
501         assert(cd->replacementpoint->type == type);
502         assert(cd->replacementpoint->flags & RPLPOINT_FLAG_NOTRAP);
503
504         cd->replacementpoint->pc = (u1*) (ptrint) (cd->mcodeptr - cd->mcodebase);
505
506         cd->replacementpoint++;
507 }
508 #endif /* defined(ENABLE_REPLACEMENT) */
509
510
511 /* codegen_set_replacement_point ***********************************************
512
513    Record the position of a trappable replacement point.
514
515 *******************************************************************************/
516
517 #if defined(ENABLE_REPLACEMENT)
518 #if !defined(NDEBUG)
519 void codegen_set_replacement_point(codegendata *cd, s4 type)
520 #else
521 void codegen_set_replacement_point(codegendata *cd)
522 #endif
523 {
524         assert(cd->replacementpoint);
525         assert(cd->replacementpoint->type == type);
526         assert(!(cd->replacementpoint->flags & RPLPOINT_FLAG_NOTRAP));
527
528         cd->replacementpoint->pc = (u1*) (ptrint) (cd->mcodeptr - cd->mcodebase);
529
530         cd->replacementpoint++;
531
532 #if !defined(NDEBUG)
533         /* XXX actually we should use an own REPLACEMENT_NOPS here! */
534         if (opt_TestReplacement)
535                 PATCHER_NOPS;
536 #endif
537
538         /* XXX assert(cd->lastmcodeptr <= cd->mcodeptr); */
539
540         cd->lastmcodeptr = cd->mcodeptr + PATCHER_CALL_SIZE;
541 }
542 #endif /* defined(ENABLE_REPLACEMENT) */
543
544
545 /* codegen_finish **************************************************************
546
547    Finishes the code generation. A new memory, large enough for both
548    data and code, is allocated and data and code are copied together
549    to their final layout, unresolved jumps are resolved, ...
550
551 *******************************************************************************/
552
553 void codegen_finish(jitdata *jd)
554 {
555         codeinfo    *code;
556         codegendata *cd;
557         s4           mcodelen;
558 #if defined(ENABLE_INTRP)
559         s4           ncodelen;
560 #endif
561         s4           alignedmcodelen;
562         jumpref     *jr;
563         u1          *epoint;
564         s4           alignedlen;
565
566         /* get required compiler data */
567
568         code = jd->code;
569         cd   = jd->cd;
570
571         /* prevent compiler warning */
572
573 #if defined(ENABLE_INTRP)
574         ncodelen = 0;
575 #endif
576
577         /* calculate the code length */
578
579         mcodelen = (s4) (cd->mcodeptr - cd->mcodebase);
580
581 #if defined(ENABLE_STATISTICS)
582         if (opt_stat) {
583                 count_code_len += mcodelen;
584                 count_data_len += cd->dseglen;
585         }
586 #endif
587
588         alignedmcodelen = MEMORY_ALIGN(mcodelen, MAX_ALIGN);
589
590 #if defined(ENABLE_INTRP)
591         if (opt_intrp)
592                 ncodelen = cd->ncodeptr - cd->ncodebase;
593         else {
594                 ncodelen = 0; /* avoid compiler warning */
595         }
596 #endif
597
598         cd->dseglen = MEMORY_ALIGN(cd->dseglen, MAX_ALIGN);
599         alignedlen = alignedmcodelen + cd->dseglen;
600
601 #if defined(ENABLE_INTRP)
602         if (opt_intrp) {
603                 alignedlen += ncodelen;
604         }
605 #endif
606
607         /* allocate new memory */
608
609         code->mcodelength = mcodelen + cd->dseglen;
610         code->mcode       = CNEW(u1, alignedlen);
611
612         /* set the entrypoint of the method */
613         
614         assert(code->entrypoint == NULL);
615         code->entrypoint = epoint = (code->mcode + cd->dseglen);
616
617         /* fill the data segment (code->entrypoint must already be set!) */
618
619         dseg_finish(jd);
620
621         /* copy code to the new location */
622
623         MCOPY((void *) code->entrypoint, cd->mcodebase, u1, mcodelen);
624
625 #if defined(ENABLE_INTRP)
626         /* relocate native dynamic superinstruction code (if any) */
627
628         if (opt_intrp) {
629                 cd->mcodebase = code->entrypoint;
630
631                 if (ncodelen > 0) {
632                         u1 *ncodebase = code->mcode + cd->dseglen + alignedmcodelen;
633
634                         MCOPY((void *) ncodebase, cd->ncodebase, u1, ncodelen);
635
636                         /* flush the instruction and data caches */
637
638                         md_cacheflush(ncodebase, ncodelen);
639
640                         /* set some cd variables for dynamic_super_rerwite */
641
642                         cd->ncodebase = ncodebase;
643
644                 } else {
645                         cd->ncodebase = NULL;
646                 }
647
648                 dynamic_super_rewrite(cd);
649         }
650 #endif
651
652         /* Create the exception table. */
653
654         exceptiontable_create(jd);
655
656         /* Create the linenumber table. */
657
658         linenumbertable_create(jd);
659
660         /* jump table resolving */
661
662         for (jr = cd->jumpreferences; jr != NULL; jr = jr->next)
663         {
664                 *((functionptr *) ((ptrint) epoint + jr->tablepos)) =
665                         (functionptr) ((ptrint) epoint + (ptrint) jr->target->mpc);
666
667                 JITCACHE_ADD_CACHED_REF(code, CRT_JUMPREFERENCE, jr->target->mpc, jr->tablepos);
668         }
669
670         /* patcher resolving */
671
672         patcher_resolve(jd);
673
674 #if defined(ENABLE_REPLACEMENT)
675         /* replacement point resolving */
676         {
677                 int i;
678                 rplpoint *rp;
679
680                 rp = code->rplpoints;
681                 for (i=0; i<code->rplpointcount; ++i, ++rp) {
682                         rp->pc = (u1*) ((ptrint) epoint + (ptrint) rp->pc);
683                 }
684         }
685 #endif /* defined(ENABLE_REPLACEMENT) */
686
687         /* Insert method into methodtree to find the entrypoint. */
688
689         methodtree_insert(code->entrypoint, code->entrypoint + mcodelen);
690
691 #if defined(__I386__) || defined(__X86_64__) || defined(__XDSPCORE__) || defined(__M68K__) || defined(ENABLE_INTRP)
692         /* resolve data segment references */
693
694         dseg_resolve_datareferences(jd);
695 #endif
696
697         /* flush the instruction and data caches */
698
699         md_cacheflush(code->mcode, code->mcodelength);
700 }
701
702
703 /* codegen_generate_stub_compiler **********************************************
704
705    Wrapper for codegen_emit_stub_compiler.
706
707    Returns:
708        pointer to the compiler stub code.
709
710 *******************************************************************************/
711
712 u1 *codegen_generate_stub_compiler(methodinfo *m)
713 {
714         jitdata     *jd;
715         codegendata *cd;
716         ptrint      *d;                     /* pointer to data memory             */
717         u1          *c;                     /* pointer to code memory             */
718         int32_t      dumpmarker;
719
720         /* mark dump memory */
721
722         DMARKER;
723
724         /* allocate required data structures */
725
726         jd = DNEW(jitdata);
727
728         jd->m     = m;
729         jd->cd    = DNEW(codegendata);
730         jd->flags = 0;
731
732         /* get required compiler data */
733
734         cd = jd->cd;
735
736 #if !defined(JIT_COMPILER_VIA_SIGNAL)
737         /* allocate code memory */
738
739         c = CNEW(u1, 3 * SIZEOF_VOID_P + COMPILERSTUB_CODESIZE);
740
741         /* set pointers correctly */
742
743         d = (ptrint *) c;
744
745         cd->mcodebase = c;
746
747         c = c + 3 * SIZEOF_VOID_P;
748         cd->mcodeptr = c;
749
750         /* NOTE: The codeinfo pointer is actually a pointer to the
751            methodinfo (this fakes a codeinfo structure). */
752
753         d[0] = (ptrint) asm_call_jit_compiler;
754         d[1] = (ptrint) m;
755         d[2] = (ptrint) &d[1];                                    /* fake code->m */
756
757         /* call the emit function */
758
759         codegen_emit_stub_compiler(jd);
760
761 #if defined(ENABLE_STATISTICS)
762         if (opt_stat)
763                 count_cstub_len += 3 * SIZEOF_VOID_P + COMPILERSTUB_CODESIZE;
764 #endif
765
766         /* flush caches */
767
768         md_cacheflush(cd->mcodebase, 3 * SIZEOF_VOID_P + COMPILERSTUB_CODESIZE);
769 #else
770         /* Allocate code memory. */
771
772         c = CNEW(uint8_t, 2 * SIZEOF_VOID_P + COMPILERSTUB_CODESIZE);
773
774         /* Set pointers correctly. */
775
776         d = (ptrint *) c;
777
778         cd->mcodebase = c;
779
780         c = c + 2 * SIZEOF_VOID_P;
781         cd->mcodeptr = c;
782
783         /* NOTE: The codeinfo pointer is actually a pointer to the
784            methodinfo (this fakes a codeinfo structure). */
785
786         d[0] = (ptrint) m;
787         d[1] = (ptrint) &d[0];                                    /* fake code->m */
788
789         /* Emit the trap instruction. */
790
791         emit_trap_compiler(cd);
792
793 #if defined(ENABLE_STATISTICS)
794         if (opt_stat)
795                 count_cstub_len += 2 * SIZEOF_VOID_P + COMPILERSTUB_CODESIZE;
796 #endif
797
798         /* Flush caches. */
799
800         md_cacheflush(cd->mcodebase, 2 * SIZEOF_VOID_P + COMPILERSTUB_CODESIZE);
801 #endif
802
803         /* release dump memory */
804
805         DRELEASE;
806
807         /* return native stub code */
808
809         return c;
810 }
811
812
813 /* codegen_generate_stub_builtin ***********************************************
814
815    Wrapper for codegen_emit_stub_native.
816
817 *******************************************************************************/
818
819 void codegen_generate_stub_builtin(methodinfo *m, builtintable_entry *bte)
820 {
821         jitdata  *jd;
822         codeinfo *code;
823         int       skipparams;
824         int32_t   dumpmarker;
825
826         /* mark dump memory */
827
828         DMARKER;
829
830         /* Create JIT data structure. */
831
832         jd = jit_jitdata_new(m);
833
834         /* Get required compiler data. */
835
836         code = jd->code;
837
838         /* Stubs are non-leaf methods. */
839
840         code_unflag_leafmethod(code);
841
842         /* setup code generation stuff */
843
844         codegen_setup(jd);
845
846         /* Set the number of native arguments we need to skip. */
847
848         skipparams = 0;
849
850         /* generate the code */
851
852 #if defined(ENABLE_JIT)
853 # if defined(ENABLE_INTRP)
854         if (!opt_intrp) {
855 # endif
856                 assert(bte->fp != NULL);
857                 codegen_emit_stub_native(jd, bte->md, bte->fp, skipparams);
858 # if defined(ENABLE_INTRP)
859         }
860 # endif
861 #endif
862
863         /* reallocate the memory and finish the code generation */
864
865         codegen_finish(jd);
866
867         /* set the stub entry point in the builtin table */
868
869         bte->stub = code->entrypoint;
870
871 #if defined(ENABLE_STATISTICS)
872         if (opt_stat)
873                 size_stub_native += code->mcodelength;
874 #endif
875
876 #if !defined(NDEBUG) && defined(ENABLE_DISASSEMBLER)
877         /* disassemble native stub */
878
879         if (opt_DisassembleStubs) {
880                 codegen_disassemble_stub(m,
881                                                                  (u1 *) (ptrint) code->entrypoint,
882                                                                  (u1 *) (ptrint) code->entrypoint + (code->mcodelength - jd->cd->dseglen));
883
884                 /* show data segment */
885
886                 if (opt_showddatasegment)
887                         dseg_display(jd);
888         }
889 #endif /* !defined(NDEBUG) && defined(ENABLE_DISASSEMBLER) */
890
891         /* release memory */
892
893         DRELEASE;
894 }
895
896
897 /* codegen_generate_stub_native ************************************************
898
899    Wrapper for codegen_emit_stub_native.
900
901    Returns:
902        the codeinfo representing the stub code.
903
904 *******************************************************************************/
905
906 codeinfo *codegen_generate_stub_native(methodinfo *m, functionptr f)
907 {
908         jitdata     *jd;
909         codeinfo    *code;
910         methoddesc  *md;
911         methoddesc  *nmd;       
912         int          skipparams;
913         int32_t      dumpmarker;
914
915         /* mark dump memory */
916
917         DMARKER;
918
919         /* Create JIT data structure. */
920
921         jd = jit_jitdata_new(m);
922
923         /* Get required compiler data. */
924
925         code = jd->code;
926
927         /* Stubs are non-leaf methods. */
928
929         code_unflag_leafmethod(code);
930
931         /* set the flags for the current JIT run */
932
933 #if defined(ENABLE_PROFILING)
934         if (opt_prof)
935                 jd->flags |= JITDATA_FLAG_INSTRUMENT;
936 #endif
937
938         if (opt_verbosecall)
939                 jd->flags |= JITDATA_FLAG_VERBOSECALL;
940
941         /* setup code generation stuff */
942
943 #if defined(ENABLE_JIT)
944 # if defined(ENABLE_INTRP)
945         if (!opt_intrp)
946 # endif
947                 reg_setup(jd);
948 #endif
949
950         codegen_setup(jd);
951
952         /* create new method descriptor with additional native parameters */
953
954         md = m->parseddesc;
955
956         /* Set the number of native arguments we need to skip. */
957
958         if (m->flags & ACC_STATIC)
959                 skipparams = 2;
960         else
961                 skipparams = 1;
962         
963         nmd = (methoddesc *) DMNEW(u1, sizeof(methoddesc) - sizeof(typedesc) +
964                                                            md->paramcount * sizeof(typedesc) +
965                                                            skipparams * sizeof(typedesc));
966
967         nmd->paramcount = md->paramcount + skipparams;
968
969         nmd->params = DMNEW(paramdesc, nmd->paramcount);
970
971         nmd->paramtypes[0].type = TYPE_ADR; /* add environment pointer            */
972
973         if (m->flags & ACC_STATIC)
974                 nmd->paramtypes[1].type = TYPE_ADR; /* add class pointer              */
975
976         MCOPY(nmd->paramtypes + skipparams, md->paramtypes, typedesc,
977                   md->paramcount);
978
979 #if defined(ENABLE_JIT)
980 # if defined(ENABLE_INTRP)
981         if (!opt_intrp)
982 # endif
983                 /* pre-allocate the arguments for the native ABI */
984
985                 md_param_alloc_native(nmd);
986 #endif
987
988         /* generate the code */
989
990 #if defined(ENABLE_JIT)
991 # if defined(ENABLE_INTRP)
992         if (opt_intrp)
993                 intrp_createnativestub(f, jd, nmd);
994         else
995 # endif
996                 codegen_emit_stub_native(jd, nmd, f, skipparams);
997 #else
998         intrp_createnativestub(f, jd, nmd);
999 #endif
1000
1001         /* reallocate the memory and finish the code generation */
1002
1003         codegen_finish(jd);
1004
1005 #if defined(ENABLE_STATISTICS)
1006         /* must be done after codegen_finish() */
1007
1008         if (opt_stat)
1009                 size_stub_native += code->mcodelength;
1010 #endif
1011
1012 #if !defined(NDEBUG) && defined(ENABLE_DISASSEMBLER)
1013         /* disassemble native stub */
1014
1015         if (opt_DisassembleStubs) {
1016 # if defined(ENABLE_DEBUG_FILTER)
1017                 if (m->filtermatches & SHOW_FILTER_FLAG_SHOW_METHOD)
1018 # endif
1019                 {
1020                         codegen_disassemble_stub(m,
1021                                                                          (u1 *) (ptrint) code->entrypoint,
1022                                                                          (u1 *) (ptrint) code->entrypoint + (code->mcodelength - jd->cd->dseglen));
1023
1024                         /* show data segment */
1025
1026                         if (opt_showddatasegment)
1027                                 dseg_display(jd);
1028                 }
1029         }
1030 #endif /* !defined(NDEBUG) && defined(ENABLE_DISASSEMBLER) */
1031
1032         /* release memory */
1033
1034         DRELEASE;
1035
1036         /* return native stub code */
1037
1038         return code;
1039 }
1040
1041
1042 /* codegen_disassemble_nativestub **********************************************
1043
1044    Disassembles the generated builtin or native stub.
1045
1046 *******************************************************************************/
1047
1048 #if defined(ENABLE_DISASSEMBLER)
1049 void codegen_disassemble_stub(methodinfo *m, u1 *start, u1 *end)
1050 {
1051         printf("Stub code: ");
1052         if (m->clazz != NULL)
1053                 utf_fprint_printable_ascii_classname(stdout, m->clazz->name);
1054         else
1055                 printf("NULL");
1056         printf(".");
1057         utf_fprint_printable_ascii(stdout, m->name);
1058         utf_fprint_printable_ascii(stdout, m->descriptor);
1059         printf("\nLength: %d\n\n", (s4) (end - start));
1060
1061         DISASSEMBLE(start, end);
1062 }
1063 #endif
1064
1065
1066 /* codegen_start_native_call ***************************************************
1067
1068    Prepares the stuff required for a native (JNI) function call:
1069
1070    - adds a stackframe info structure to the chain, for stacktraces
1071    - prepares the local references table on the stack
1072
1073    The layout of the native stub stackframe should look like this:
1074
1075    +---------------------------+ <- java SP (of parent Java function)
1076    | return address            |
1077    +---------------------------+ <- data SP
1078    |                           |
1079    | stackframe info structure |
1080    |                           |
1081    +---------------------------+
1082    |                           |
1083    | local references table    |
1084    |                           |
1085    +---------------------------+
1086    |                           |
1087    | saved registers (if any)  |
1088    |                           |
1089    +---------------------------+
1090    |                           |
1091    | arguments (if any)        |
1092    |                           |
1093    +---------------------------+ <- current SP (native stub)
1094
1095 *******************************************************************************/
1096
1097 java_handle_t *codegen_start_native_call(u1 *sp, u1 *pv)
1098 {
1099         stackframeinfo_t *sfi;
1100         localref_table   *lrt;
1101         methodinfo       *m;
1102         int32_t           framesize;
1103
1104         uint8_t  *datasp;
1105         uint8_t  *javasp;
1106         uint64_t *arg_regs;
1107         uint64_t *arg_stack;
1108
1109         STATISTICS(count_calls_java_to_native++);
1110
1111         /* Get the methodinfo. */
1112
1113         m = code_get_methodinfo_for_pv(pv);
1114
1115         assert(m);
1116
1117         framesize = *((int32_t *) (pv + FrameSize));
1118
1119         assert(framesize >= sizeof(stackframeinfo_t) + sizeof(localref_table));
1120
1121         /* calculate needed values */
1122
1123 #if defined(__ALPHA__) || defined(__ARM__)
1124         datasp    = sp + framesize - SIZEOF_VOID_P;
1125         javasp    = sp + framesize;
1126         arg_regs  = (uint64_t *) sp;
1127         arg_stack = (uint64_t *) javasp;
1128 #elif defined(__MIPS__)
1129         /* MIPS always uses 8 bytes to store the RA */
1130         datasp    = sp + framesize - 8;
1131         javasp    = sp + framesize;
1132 #elif defined(__S390__)
1133         datasp    = sp + framesize - 8;
1134         javasp    = sp + framesize;
1135         arg_regs  = (uint64_t *) (sp + 96);
1136         arg_stack = (uint64_t *) javasp;
1137 #elif defined(__I386__) || defined(__M68K__) || defined(__X86_64__)
1138         datasp    = sp + framesize;
1139         javasp    = sp + framesize + SIZEOF_VOID_P;
1140         arg_regs  = (uint64_t *) sp;
1141         arg_stack = (uint64_t *) javasp;
1142 #elif defined(__POWERPC__)
1143         datasp    = sp + framesize;
1144         javasp    = sp + framesize;
1145         arg_regs  = (uint64_t *) (sp + LA_SIZE + 4 * SIZEOF_VOID_P);
1146         arg_stack = (uint64_t *) javasp;
1147 #elif defined(__POWERPC64__)
1148         datasp    = sp + framesize;
1149         javasp    = sp + framesize;
1150         arg_regs  = (uint64_t *) (sp + PA_SIZE + LA_SIZE + 4 * SIZEOF_VOID_P);
1151         arg_stack = (uint64_t *) javasp;
1152 #else
1153         /* XXX is was unable to do this port for SPARC64, sorry. (-michi) */
1154         /* XXX maybe we need to pass the RA as argument there */
1155         vm_abort("codegen_start_native_call: unsupported architecture");
1156 #endif
1157
1158         /* get data structures from stack */
1159
1160         sfi = (stackframeinfo_t *) (datasp - sizeof(stackframeinfo_t));
1161         lrt = (localref_table *)   (datasp - sizeof(stackframeinfo_t) - 
1162                                                                 sizeof(localref_table));
1163
1164 #if defined(ENABLE_JNI)
1165         /* add current JNI local references table to this thread */
1166
1167         localref_table_add(lrt);
1168 #endif
1169
1170 #if !defined(NDEBUG)
1171 # if defined(__ALPHA__) || defined(__I386__) || defined(__M68K__) || defined(__POWERPC__) || defined(__POWERPC64__) || defined(__S390__) || defined(__X86_64__)
1172         /* print the call-trace if necesarry */
1173         /* BEFORE: filling the local reference table */
1174
1175         if (opt_TraceJavaCalls)
1176                 trace_java_call_enter(m, arg_regs, arg_stack);
1177 # endif
1178 #endif
1179
1180 #if defined(ENABLE_HANDLES)
1181         /* place all references into the local reference table */
1182         /* BEFORE: creating stackframeinfo */
1183
1184         localref_native_enter(m, arg_regs, arg_stack);
1185 #endif
1186
1187         /* Add a stackframeinfo for this native method.  We don't have RA
1188            and XPC here.  These are determined in
1189            stacktrace_stackframeinfo_add. */
1190
1191         stacktrace_stackframeinfo_add(sfi, pv, sp, NULL, NULL);
1192
1193         /* Return a wrapped classinfo for static methods. */
1194
1195         if (m->flags & ACC_STATIC)
1196                 return (java_handle_t *) LLNI_classinfo_wrap(m->clazz);
1197         else
1198                 return NULL;
1199 }
1200
1201
1202 /* codegen_finish_native_call **************************************************
1203
1204    Removes the stuff required for a native (JNI) function call.
1205    Additionally it checks for an exceptions and in case, get the
1206    exception object and clear the pointer.
1207
1208 *******************************************************************************/
1209
1210 java_object_t *codegen_finish_native_call(u1 *sp, u1 *pv)
1211 {
1212         stackframeinfo_t *sfi;
1213         java_handle_t    *e;
1214         java_object_t    *o;
1215         codeinfo         *code;
1216         methodinfo       *m;
1217         int32_t           framesize;
1218
1219         uint8_t  *datasp;
1220         uint64_t *ret_regs;
1221
1222         /* get information from method header */
1223
1224         code = code_get_codeinfo_for_pv(pv);
1225
1226         framesize = *((int32_t *) (pv + FrameSize));
1227
1228         assert(code);
1229
1230         /* get the methodinfo */
1231
1232         m = code->m;
1233         assert(m);
1234
1235         /* calculate needed values */
1236
1237 #if defined(__ALPHA__) || defined(__ARM__)
1238         datasp   = sp + framesize - SIZEOF_VOID_P;
1239         ret_regs = (uint64_t *) sp;
1240 #elif defined(__MIPS__)
1241         /* MIPS always uses 8 bytes to store the RA */
1242         datasp   = sp + framesize - 8;
1243 #elif defined(__S390__)
1244         datasp   = sp + framesize - 8;
1245         ret_regs = (uint64_t *) (sp + 96);
1246 #elif defined(__I386__)
1247         datasp   = sp + framesize;
1248         ret_regs = (uint64_t *) (sp + 2 * SIZEOF_VOID_P);
1249 #elif defined(__M68K__)
1250         datasp   = sp + framesize;
1251         ret_regs = (uint64_t *) (sp + 2 * 8);
1252 #elif defined(__X86_64__)
1253         datasp   = sp + framesize;
1254         ret_regs = (uint64_t *) sp;
1255 #elif defined(__POWERPC__)
1256         datasp   = sp + framesize;
1257         ret_regs = (uint64_t *) (sp + LA_SIZE + 2 * SIZEOF_VOID_P);
1258 #elif defined(__POWERPC64__)
1259         datasp   = sp + framesize;
1260         ret_regs = (uint64_t *) (sp + PA_SIZE + LA_SIZE + 2 * SIZEOF_VOID_P);
1261 #else
1262         vm_abort("codegen_finish_native_call: unsupported architecture");
1263 #endif
1264
1265         /* get data structures from stack */
1266
1267         sfi = (stackframeinfo_t *) (datasp - sizeof(stackframeinfo_t));
1268
1269         /* Remove current stackframeinfo from chain. */
1270
1271         stacktrace_stackframeinfo_remove(sfi);
1272
1273 #if defined(ENABLE_HANDLES)
1274         /* unwrap the return value from the local reference table */
1275         /* AFTER: removing the stackframeinfo */
1276         /* BEFORE: releasing the local reference table */
1277
1278         localref_native_exit(m, ret_regs);
1279 #endif
1280
1281         /* get and unwrap the exception */
1282         /* AFTER: removing the stackframe info */
1283         /* BEFORE: releasing the local reference table */
1284
1285         e = exceptions_get_and_clear_exception();
1286         o = LLNI_UNWRAP(e);
1287
1288 #if defined(ENABLE_JNI)
1289         /* release JNI local references table for this thread */
1290
1291         localref_frame_pop_all();
1292         localref_table_remove();
1293 #endif
1294
1295 #if !defined(NDEBUG)
1296 # if defined(__ALPHA__) || defined(__I386__) || defined(__M68K__) || defined(__POWERPC__) || defined(__POWERPC64__) || defined(__S390__) || defined(__X86_64__)
1297         /* print the call-trace if necesarry */
1298         /* AFTER: unwrapping the return value */
1299
1300         if (opt_TraceJavaCalls)
1301                 trace_java_call_exit(m, ret_regs);
1302 # endif
1303 #endif
1304
1305         return o;
1306 }
1307
1308
1309 /* removecompilerstub **********************************************************
1310
1311    Deletes a compilerstub from memory (simply by freeing it).
1312
1313 *******************************************************************************/
1314
1315 void removecompilerstub(u1 *stub)
1316 {
1317         /* pass size 1 to keep the intern function happy */
1318
1319         CFREE((void *) stub, 1);
1320 }
1321
1322
1323 /* removenativestub ************************************************************
1324
1325    Removes a previously created native-stub from memory.
1326     
1327 *******************************************************************************/
1328
1329 void removenativestub(u1 *stub)
1330 {
1331         /* pass size 1 to keep the intern function happy */
1332
1333         CFREE((void *) stub, 1);
1334 }
1335
1336
1337 /* codegen_reg_of_var **********************************************************
1338
1339    This function determines a register, to which the result of an
1340    operation should go, when it is ultimatively intended to store the
1341    result in pseudoregister v.  If v is assigned to an actual
1342    register, this register will be returned.  Otherwise (when v is
1343    spilled) this function returns tempregnum.  If not already done,
1344    regoff and flags are set in the stack location.
1345        
1346 *******************************************************************************/
1347
1348 s4 codegen_reg_of_var(u2 opcode, varinfo *v, s4 tempregnum)
1349 {
1350         if (!(v->flags & INMEMORY))
1351                 return v->vv.regoff;
1352
1353         return tempregnum;
1354 }
1355
1356
1357 /* codegen_reg_of_dst **********************************************************
1358
1359    This function determines a register, to which the result of an
1360    operation should go, when it is ultimatively intended to store the
1361    result in iptr->dst.var.  If dst.var is assigned to an actual
1362    register, this register will be returned.  Otherwise (when it is
1363    spilled) this function returns tempregnum.  If not already done,
1364    regoff and flags are set in the stack location.
1365        
1366 *******************************************************************************/
1367
1368 s4 codegen_reg_of_dst(jitdata *jd, instruction *iptr, s4 tempregnum)
1369 {
1370         return codegen_reg_of_var(iptr->opc, VAROP(iptr->dst), tempregnum);
1371 }
1372
1373
1374 /* codegen_emit_phi_moves ****************************************************
1375
1376    Emits phi moves at the end of the basicblock.
1377
1378 *******************************************************************************/
1379
1380 #if defined(ENABLE_SSA)
1381 void codegen_emit_phi_moves(jitdata *jd, basicblock *bptr)
1382 {
1383         int lt_d,lt_s,i;
1384         lsradata *ls;
1385         codegendata *cd;
1386         varinfo *s, *d;
1387         instruction tmp_i;
1388
1389         cd = jd->cd;
1390         ls = jd->ls;
1391
1392         MCODECHECK(512);
1393
1394         /* Moves from phi functions with highest indices have to be */
1395         /* inserted first, since this is the order as is used for   */
1396         /* conflict resolution */
1397
1398         for(i = ls->num_phi_moves[bptr->nr] - 1; i >= 0 ; i--) {
1399                 lt_d = ls->phi_moves[bptr->nr][i][0];
1400                 lt_s = ls->phi_moves[bptr->nr][i][1];
1401 #if defined(SSA_DEBUG_VERBOSE)
1402                 if (compileverbose)
1403                         printf("BB %3i Move %3i <- %3i ", bptr->nr, lt_d, lt_s);
1404 #endif
1405                 if (lt_s == UNUSED) {
1406 #if defined(SSA_DEBUG_VERBOSE)
1407                 if (compileverbose)
1408                         printf(" ... not processed \n");
1409 #endif
1410                         continue;
1411                 }
1412                         
1413                 d = VAR(ls->lifetime[lt_d].v_index);
1414                 s = VAR(ls->lifetime[lt_s].v_index);
1415                 
1416
1417                 if (d->type == -1) {
1418 #if defined(SSA_DEBUG_VERBOSE)
1419                         if (compileverbose)
1420                                 printf("...returning - phi lifetimes where joined\n");
1421 #endif
1422                         continue;
1423                 }
1424
1425                 if (s->type == -1) {
1426 #if defined(SSA_DEBUG_VERBOSE)
1427                         if (compileverbose)
1428                                 printf("...returning - phi lifetimes where joined\n");
1429 #endif
1430                         continue;
1431                 }
1432
1433                 tmp_i.opc = 0;
1434                 tmp_i.s1.varindex = ls->lifetime[lt_s].v_index;
1435                 tmp_i.dst.varindex = ls->lifetime[lt_d].v_index;
1436                 emit_copy(jd, &tmp_i);
1437
1438 #if defined(SSA_DEBUG_VERBOSE)
1439                 if (compileverbose) {
1440                         if (IS_INMEMORY(d->flags) && IS_INMEMORY(s->flags)) {
1441                                 /* mem -> mem */
1442                                 printf("M%3i <- M%3i",d->vv.regoff,s->vv.regoff);
1443                         }
1444                         else if (IS_INMEMORY(s->flags)) {
1445                                 /* mem -> reg */
1446                                 printf("R%3i <- M%3i",d->vv.regoff,s->vv.regoff);
1447                         }
1448                         else if (IS_INMEMORY(d->flags)) {
1449                                 /* reg -> mem */
1450                                 printf("M%3i <- R%3i",d->vv.regoff,s->vv.regoff);
1451                         }
1452                         else {
1453                                 /* reg -> reg */
1454                                 printf("R%3i <- R%3i",d->vv.regoff,s->vv.regoff);
1455                         }
1456                         printf("\n");
1457                 }
1458 #endif /* defined(SSA_DEBUG_VERBOSE) */
1459         }
1460 }
1461 #endif /* defined(ENABLE_SSA) */
1462
1463
1464 /* REMOVEME When we have exception handling in C. */
1465
1466 void *md_asm_codegen_get_pv_from_pc(void *ra)
1467 {
1468         return md_codegen_get_pv_from_pc(ra);
1469 }
1470
1471
1472 /*
1473  * These are local overrides for various environment variables in Emacs.
1474  * Please do not remove this and leave it at the end of the file, where
1475  * Emacs will automagically detect them.
1476  * ---------------------------------------------------------------------
1477  * Local variables:
1478  * mode: c
1479  * indent-tabs-mode: t
1480  * c-basic-offset: 4
1481  * tab-width: 4
1482  * End:
1483  * vim:noexpandtab:sw=4:ts=4:
1484  */