1 /* src/vm/jit/codegen-common.c - architecture independent code generator stuff
3 Copyright (C) 1996-2005, 2006, 2007, 2008
4 CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
6 This file is part of CACAO.
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.
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.
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
23 All functions assume the following code area / data area layout:
27 | code area | code area grows to higher addresses
29 +-----------+ <-- start of procedure
31 | data area | data area grows to lower addresses
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).
54 #include "mm/memory.h"
56 #include "toolbox/avl.h"
57 #include "toolbox/list.h"
58 #include "toolbox/logging.h"
60 #include "native/llni.h"
61 #include "native/localref.h"
62 #include "native/native.h"
64 #include "threads/thread.hpp"
66 #include "vm/builtin.h"
67 #include "vm/exceptions.hpp"
68 #include "vm/method.h"
69 #include "vm/options.h"
70 #include "vm/string.hpp"
72 # include "vm/statistics.h"
75 #include "vm/jit/abi.h"
76 #include "vm/jit/asmpart.h"
77 #include "vm/jit/code.h"
78 #include "vm/jit/codegen-common.h"
80 #if defined(ENABLE_DISASSEMBLER)
81 # include "vm/jit/disass.h"
84 #include "vm/jit/dseg.h"
85 #include "vm/jit/emit-common.h"
86 #include "vm/jit/jit.h"
87 #include "vm/jit/linenumbertable.h"
88 #include "vm/jit/methodheader.h"
89 #include "vm/jit/methodtree.h"
90 #include "vm/jit/patcher-common.h"
91 #include "vm/jit/replace.h"
92 #if defined(ENABLE_SSA)
93 # include "vm/jit/optimizing/lsra.h"
94 # include "vm/jit/optimizing/ssa.h"
96 #include "vm/jit/stacktrace.hpp"
97 #include "vm/jit/trace.hpp"
99 #if defined(ENABLE_INTRP)
100 #include "vm/jit/intrp/intrp.h"
103 #if defined(ENABLE_VMLOG)
104 #include <vmlog_cacao.h>
110 /* codegen_init ****************************************************************
114 *******************************************************************************/
116 void codegen_init(void)
121 /* codegen_setup ***************************************************************
123 Allocates and initialises code area, data area and references.
125 *******************************************************************************/
127 void codegen_setup(jitdata *jd)
132 /* get required compiler data */
137 /* initialize members */
141 cd->mcodebase = DMNEW(u1, MCODEINITSIZE);
142 cd->mcodeend = cd->mcodebase + MCODEINITSIZE;
143 cd->mcodesize = MCODEINITSIZE;
145 /* initialize mcode variables */
147 cd->mcodeptr = cd->mcodebase;
148 cd->lastmcodeptr = cd->mcodebase;
150 #if defined(ENABLE_INTRP)
151 /* native dynamic superinstructions variables */
154 cd->ncodebase = DMNEW(u1, NCODEINITSIZE);
155 cd->ncodesize = NCODEINITSIZE;
157 /* initialize ncode variables */
159 cd->ncodeptr = cd->ncodebase;
161 cd->lastinstwithoutdispatch = ~0; /* no inst without dispatch */
162 cd->superstarts = NULL;
169 cd->jumpreferences = NULL;
171 #if defined(__I386__) || defined(__X86_64__) || defined(__XDSPCORE__) || defined(__M68K__) || defined(ENABLE_INTRP)
172 cd->datareferences = NULL;
175 cd->brancheslabel = list_create_dump(OFFSET(branch_label_ref_t, linkage));
176 cd->linenumbers = list_create_dump(OFFSET(linenumbertable_list_entry_t, linkage));
180 /* codegen_reset ***************************************************************
182 Resets the codegen data structure so we can recompile the method.
184 *******************************************************************************/
186 static void codegen_reset(jitdata *jd)
192 /* get required compiler data */
197 /* reset error flag */
199 cd->flags &= ~CODEGENDATA_FLAG_ERROR;
201 /* reset some members, we reuse the code memory already allocated
202 as this should have almost the correct size */
204 cd->mcodeptr = cd->mcodebase;
205 cd->lastmcodeptr = cd->mcodebase;
210 cd->jumpreferences = NULL;
212 #if defined(__I386__) || defined(__X86_64__) || defined(__XDSPCORE__) || defined(__M68K__) || defined(ENABLE_INTRP)
213 cd->datareferences = NULL;
216 cd->brancheslabel = list_create_dump(OFFSET(branch_label_ref_t, linkage));
217 cd->linenumbers = list_create_dump(OFFSET(linenumbertable_list_entry_t, linkage));
219 /* We need to clear the mpc and the branch references from all
220 basic blocks as they will definitely change. */
222 for (bptr = jd->basicblocks; bptr != NULL; bptr = bptr->next) {
224 bptr->branchrefs = NULL;
227 /* We need to clear all the patcher references from the codeinfo
228 since they all will be regenerated */
230 patcher_list_reset(code);
232 #if defined(ENABLE_REPLACEMENT)
233 code->rplpoints = NULL;
234 code->rplpointcount = 0;
235 code->regalloc = NULL;
236 code->regalloccount = 0;
237 code->globalcount = 0;
242 /* codegen_generate ************************************************************
244 Generates the code for the currently compiled method.
246 *******************************************************************************/
248 bool codegen_generate(jitdata *jd)
252 /* get required compiler data */
256 /* call the machine-dependent code generation function */
258 if (!codegen_emit(jd))
261 /* check for an error */
263 if (CODEGENDATA_HAS_FLAG_ERROR(cd)) {
264 /* check for long-branches flag, if it is set we recompile the
269 log_message_method("Re-generating code: ", jd->m);
272 /* XXX maybe we should tag long-branches-methods for recompilation */
274 if (CODEGENDATA_HAS_FLAG_LONGBRANCHES(cd)) {
275 /* we have to reset the codegendata structure first */
279 /* and restart the compiler run */
281 if (!codegen_emit(jd))
285 vm_abort("codegen_generate: unknown error occurred during codegen_emit: flags=%x\n", cd->flags);
290 log_message_method("Re-generating code done: ", jd->m);
294 /* reallocate the memory and finish the code generation */
298 /* everything's ok */
304 /* codegen_close ***************************************************************
308 *******************************************************************************/
310 void codegen_close(void)
312 /* TODO: release avl tree on i386 and x86_64 */
316 /* codegen_increase ************************************************************
320 *******************************************************************************/
322 void codegen_increase(codegendata *cd)
326 /* save old mcodebase pointer */
328 oldmcodebase = cd->mcodebase;
330 /* reallocate to new, doubled memory */
332 cd->mcodebase = DMREALLOC(cd->mcodebase,
337 cd->mcodeend = cd->mcodebase + cd->mcodesize;
339 /* set new mcodeptr */
341 cd->mcodeptr = cd->mcodebase + (cd->mcodeptr - oldmcodebase);
343 #if defined(__I386__) || defined(__MIPS__) || defined(__X86_64__) || defined(__M68K__) || defined(ENABLE_INTRP) \
344 || defined(__SPARC_64__)
345 /* adjust the pointer to the last patcher position */
347 if (cd->lastmcodeptr != NULL)
348 cd->lastmcodeptr = cd->mcodebase + (cd->lastmcodeptr - oldmcodebase);
353 /* codegen_ncode_increase ******************************************************
357 *******************************************************************************/
359 #if defined(ENABLE_INTRP)
360 u1 *codegen_ncode_increase(codegendata *cd, u1 *ncodeptr)
364 /* save old ncodebase pointer */
366 oldncodebase = cd->ncodebase;
368 /* reallocate to new, doubled memory */
370 cd->ncodebase = DMREALLOC(cd->ncodebase,
376 /* return the new ncodeptr */
378 return (cd->ncodebase + (ncodeptr - oldncodebase));
383 /* codegen_add_branch_ref ******************************************************
385 Prepends an branch to the list.
387 *******************************************************************************/
389 void codegen_add_branch_ref(codegendata *cd, basicblock *target, s4 condition, s4 reg, u4 options)
394 STATISTICS(count_branches_unresolved++);
396 /* calculate the mpc of the branch instruction */
398 branchmpc = cd->mcodeptr - cd->mcodebase;
400 br = DNEW(branchref);
402 br->branchmpc = branchmpc;
403 br->condition = condition;
405 br->options = options;
406 br->next = target->branchrefs;
408 target->branchrefs = br;
412 /* codegen_resolve_branchrefs **************************************************
414 Resolves and patches the branch references of a given basic block.
416 *******************************************************************************/
418 void codegen_resolve_branchrefs(codegendata *cd, basicblock *bptr)
423 /* Save the mcodeptr because in the branch emitting functions
424 we generate code somewhere inside already generated code,
425 but we're still in the actual code generation phase. */
427 mcodeptr = cd->mcodeptr;
429 /* just to make sure */
431 assert(bptr->mpc >= 0);
433 for (br = bptr->branchrefs; br != NULL; br = br->next) {
434 /* temporary set the mcodeptr */
436 cd->mcodeptr = cd->mcodebase + br->branchmpc;
438 /* emit_bccz and emit_branch emit the correct code, even if we
439 pass condition == BRANCH_UNCONDITIONAL or reg == -1. */
441 emit_bccz(cd, bptr, br->condition, br->reg, br->options);
444 /* restore mcodeptr */
446 cd->mcodeptr = mcodeptr;
450 /* codegen_branch_label_add ****************************************************
452 Append an branch to the label-branch list.
454 *******************************************************************************/
456 void codegen_branch_label_add(codegendata *cd, s4 label, s4 condition, s4 reg, u4 options)
459 branch_label_ref_t *br;
462 /* Get the label list. */
464 l = cd->brancheslabel;
466 /* calculate the current mpc */
468 mpc = cd->mcodeptr - cd->mcodebase;
470 br = DNEW(branch_label_ref_t);
474 br->condition = condition;
476 br->options = options;
478 /* Add the branch to the list. */
480 list_add_last(l, br);
484 /* codegen_set_replacement_point_notrap ****************************************
486 Record the position of a non-trappable replacement point.
488 *******************************************************************************/
490 #if defined(ENABLE_REPLACEMENT)
492 void codegen_set_replacement_point_notrap(codegendata *cd, s4 type)
494 void codegen_set_replacement_point_notrap(codegendata *cd)
497 assert(cd->replacementpoint);
498 assert(cd->replacementpoint->type == type);
499 assert(cd->replacementpoint->flags & RPLPOINT_FLAG_NOTRAP);
501 cd->replacementpoint->pc = (u1*) (ptrint) (cd->mcodeptr - cd->mcodebase);
503 cd->replacementpoint++;
505 #endif /* defined(ENABLE_REPLACEMENT) */
508 /* codegen_set_replacement_point ***********************************************
510 Record the position of a trappable replacement point.
512 *******************************************************************************/
514 #if defined(ENABLE_REPLACEMENT)
516 void codegen_set_replacement_point(codegendata *cd, s4 type)
518 void codegen_set_replacement_point(codegendata *cd)
521 assert(cd->replacementpoint);
522 assert(cd->replacementpoint->type == type);
523 assert(!(cd->replacementpoint->flags & RPLPOINT_FLAG_NOTRAP));
525 cd->replacementpoint->pc = (u1*) (ptrint) (cd->mcodeptr - cd->mcodebase);
527 cd->replacementpoint++;
530 /* XXX actually we should use an own REPLACEMENT_NOPS here! */
531 if (opt_TestReplacement)
535 /* XXX assert(cd->lastmcodeptr <= cd->mcodeptr); */
537 cd->lastmcodeptr = cd->mcodeptr + PATCHER_CALL_SIZE;
539 #endif /* defined(ENABLE_REPLACEMENT) */
542 /* codegen_finish **************************************************************
544 Finishes the code generation. A new memory, large enough for both
545 data and code, is allocated and data and code are copied together
546 to their final layout, unresolved jumps are resolved, ...
548 *******************************************************************************/
550 void codegen_finish(jitdata *jd)
555 #if defined(ENABLE_INTRP)
563 /* get required compiler data */
568 /* prevent compiler warning */
570 #if defined(ENABLE_INTRP)
574 /* calculate the code length */
576 mcodelen = (s4) (cd->mcodeptr - cd->mcodebase);
578 #if defined(ENABLE_STATISTICS)
580 count_code_len += mcodelen;
581 count_data_len += cd->dseglen;
585 alignedmcodelen = MEMORY_ALIGN(mcodelen, MAX_ALIGN);
587 #if defined(ENABLE_INTRP)
589 ncodelen = cd->ncodeptr - cd->ncodebase;
591 ncodelen = 0; /* avoid compiler warning */
595 cd->dseglen = MEMORY_ALIGN(cd->dseglen, MAX_ALIGN);
596 alignedlen = alignedmcodelen + cd->dseglen;
598 #if defined(ENABLE_INTRP)
600 alignedlen += ncodelen;
604 /* allocate new memory */
606 code->mcodelength = mcodelen + cd->dseglen;
607 code->mcode = CNEW(u1, alignedlen);
609 /* set the entrypoint of the method */
611 assert(code->entrypoint == NULL);
612 code->entrypoint = epoint = (code->mcode + cd->dseglen);
614 /* fill the data segment (code->entrypoint must already be set!) */
618 /* copy code to the new location */
620 MCOPY((void *) code->entrypoint, cd->mcodebase, u1, mcodelen);
622 #if defined(ENABLE_INTRP)
623 /* relocate native dynamic superinstruction code (if any) */
626 cd->mcodebase = code->entrypoint;
629 u1 *ncodebase = code->mcode + cd->dseglen + alignedmcodelen;
631 MCOPY((void *) ncodebase, cd->ncodebase, u1, ncodelen);
633 /* flush the instruction and data caches */
635 md_cacheflush(ncodebase, ncodelen);
637 /* set some cd variables for dynamic_super_rerwite */
639 cd->ncodebase = ncodebase;
642 cd->ncodebase = NULL;
645 dynamic_super_rewrite(cd);
649 /* Create the exception table. */
651 exceptiontable_create(jd);
653 /* Create the linenumber table. */
655 linenumbertable_create(jd);
657 /* jump table resolving */
659 for (jr = cd->jumpreferences; jr != NULL; jr = jr->next)
660 *((functionptr *) ((ptrint) epoint + jr->tablepos)) =
661 (functionptr) ((ptrint) epoint + (ptrint) jr->target->mpc);
663 /* patcher resolving */
667 #if defined(ENABLE_REPLACEMENT)
668 /* replacement point resolving */
673 rp = code->rplpoints;
674 for (i=0; i<code->rplpointcount; ++i, ++rp) {
675 rp->pc = (u1*) ((ptrint) epoint + (ptrint) rp->pc);
678 #endif /* defined(ENABLE_REPLACEMENT) */
680 /* Insert method into methodtree to find the entrypoint. */
682 methodtree_insert(code->entrypoint, code->entrypoint + mcodelen);
684 #if defined(__I386__) || defined(__X86_64__) || defined(__XDSPCORE__) || defined(__M68K__) || defined(ENABLE_INTRP)
685 /* resolve data segment references */
687 dseg_resolve_datareferences(jd);
690 /* flush the instruction and data caches */
692 md_cacheflush(code->mcode, code->mcodelength);
696 /* codegen_start_native_call ***************************************************
698 Prepares the stuff required for a native (JNI) function call:
700 - adds a stackframe info structure to the chain, for stacktraces
701 - prepares the local references table on the stack
703 The layout of the native stub stackframe should look like this:
705 +---------------------------+ <- java SP (of parent Java function)
707 +---------------------------+ <- data SP
709 | stackframe info structure |
711 +---------------------------+
713 | local references table |
715 +---------------------------+
717 | saved registers (if any) |
719 +---------------------------+
721 | arguments (if any) |
723 +---------------------------+ <- current SP (native stub)
725 *******************************************************************************/
727 java_handle_t *codegen_start_native_call(u1 *sp, u1 *pv)
729 stackframeinfo_t *sfi;
739 STATISTICS(count_calls_java_to_native++);
741 /* Get the methodinfo. */
743 m = code_get_methodinfo_for_pv(pv);
747 framesize = *((int32_t *) (pv + FrameSize));
749 assert(framesize >= sizeof(stackframeinfo_t) + sizeof(localref_table));
751 /* calculate needed values */
753 #if defined(__ALPHA__) || defined(__ARM__)
754 datasp = sp + framesize - SIZEOF_VOID_P;
755 javasp = sp + framesize;
756 arg_regs = (uint64_t *) sp;
757 arg_stack = (uint64_t *) javasp;
758 #elif defined(__MIPS__)
759 /* MIPS always uses 8 bytes to store the RA */
760 datasp = sp + framesize - 8;
761 javasp = sp + framesize;
762 #elif defined(__S390__)
763 datasp = sp + framesize - 8;
764 javasp = sp + framesize;
765 arg_regs = (uint64_t *) (sp + 96);
766 arg_stack = (uint64_t *) javasp;
767 #elif defined(__I386__) || defined(__M68K__) || defined(__X86_64__)
768 datasp = sp + framesize;
769 javasp = sp + framesize + SIZEOF_VOID_P;
770 arg_regs = (uint64_t *) sp;
771 arg_stack = (uint64_t *) javasp;
772 #elif defined(__POWERPC__)
773 datasp = sp + framesize;
774 javasp = sp + framesize;
775 arg_regs = (uint64_t *) (sp + LA_SIZE + 4 * SIZEOF_VOID_P);
776 arg_stack = (uint64_t *) javasp;
777 #elif defined(__POWERPC64__)
778 datasp = sp + framesize;
779 javasp = sp + framesize;
780 arg_regs = (uint64_t *) (sp + PA_SIZE + LA_SIZE + 4 * SIZEOF_VOID_P);
781 arg_stack = (uint64_t *) javasp;
783 /* XXX is was unable to do this port for SPARC64, sorry. (-michi) */
784 /* XXX maybe we need to pass the RA as argument there */
785 vm_abort("codegen_start_native_call: unsupported architecture");
788 /* get data structures from stack */
790 sfi = (stackframeinfo_t *) (datasp - sizeof(stackframeinfo_t));
791 lrt = (localref_table *) (datasp - sizeof(stackframeinfo_t) -
792 sizeof(localref_table));
794 #if defined(ENABLE_JNI)
795 /* add current JNI local references table to this thread */
797 localref_table_add(lrt);
801 # if defined(__ALPHA__) || defined(__I386__) || defined(__M68K__) || defined(__POWERPC__) || defined(__POWERPC64__) || defined(__S390__) || defined(__X86_64__)
802 /* print the call-trace if necesarry */
803 /* BEFORE: filling the local reference table */
805 if (opt_TraceJavaCalls)
806 trace_java_call_enter(m, arg_regs, arg_stack);
810 #if defined(ENABLE_HANDLES)
811 /* place all references into the local reference table */
812 /* BEFORE: creating stackframeinfo */
814 localref_native_enter(m, arg_regs, arg_stack);
817 /* Add a stackframeinfo for this native method. We don't have RA
818 and XPC here. These are determined in
819 stacktrace_stackframeinfo_add. */
821 stacktrace_stackframeinfo_add(sfi, pv, sp, NULL, NULL);
823 /* Return a wrapped classinfo for static methods. */
825 if (m->flags & ACC_STATIC)
826 return (java_handle_t *) LLNI_classinfo_wrap(m->clazz);
832 /* codegen_finish_native_call **************************************************
834 Removes the stuff required for a native (JNI) function call.
835 Additionally it checks for an exceptions and in case, get the
836 exception object and clear the pointer.
838 *******************************************************************************/
840 java_object_t *codegen_finish_native_call(u1 *sp, u1 *pv)
842 stackframeinfo_t *sfi;
852 /* get information from method header */
854 code = code_get_codeinfo_for_pv(pv);
856 framesize = *((int32_t *) (pv + FrameSize));
860 /* get the methodinfo */
865 /* calculate needed values */
867 #if defined(__ALPHA__) || defined(__ARM__)
868 datasp = sp + framesize - SIZEOF_VOID_P;
869 ret_regs = (uint64_t *) sp;
870 #elif defined(__MIPS__)
871 /* MIPS always uses 8 bytes to store the RA */
872 datasp = sp + framesize - 8;
873 #elif defined(__S390__)
874 datasp = sp + framesize - 8;
875 ret_regs = (uint64_t *) (sp + 96);
876 #elif defined(__I386__)
877 datasp = sp + framesize;
878 ret_regs = (uint64_t *) (sp + 2 * SIZEOF_VOID_P);
879 #elif defined(__M68K__)
880 datasp = sp + framesize;
881 ret_regs = (uint64_t *) (sp + 2 * 8);
882 #elif defined(__X86_64__)
883 datasp = sp + framesize;
884 ret_regs = (uint64_t *) sp;
885 #elif defined(__POWERPC__)
886 datasp = sp + framesize;
887 ret_regs = (uint64_t *) (sp + LA_SIZE + 2 * SIZEOF_VOID_P);
888 #elif defined(__POWERPC64__)
889 datasp = sp + framesize;
890 ret_regs = (uint64_t *) (sp + PA_SIZE + LA_SIZE + 2 * SIZEOF_VOID_P);
892 vm_abort("codegen_finish_native_call: unsupported architecture");
895 /* get data structures from stack */
897 sfi = (stackframeinfo_t *) (datasp - sizeof(stackframeinfo_t));
899 /* Remove current stackframeinfo from chain. */
901 stacktrace_stackframeinfo_remove(sfi);
903 #if defined(ENABLE_HANDLES)
904 /* unwrap the return value from the local reference table */
905 /* AFTER: removing the stackframeinfo */
906 /* BEFORE: releasing the local reference table */
908 localref_native_exit(m, ret_regs);
911 /* get and unwrap the exception */
912 /* AFTER: removing the stackframe info */
913 /* BEFORE: releasing the local reference table */
915 e = exceptions_get_and_clear_exception();
918 #if defined(ENABLE_JNI)
919 /* release JNI local references table for this thread */
921 localref_frame_pop_all();
922 localref_table_remove();
926 # if defined(__ALPHA__) || defined(__I386__) || defined(__M68K__) || defined(__POWERPC__) || defined(__POWERPC64__) || defined(__S390__) || defined(__X86_64__)
927 /* print the call-trace if necesarry */
928 /* AFTER: unwrapping the return value */
930 if (opt_TraceJavaCalls)
931 trace_java_call_exit(m, ret_regs);
939 /* codegen_reg_of_var **********************************************************
941 This function determines a register, to which the result of an
942 operation should go, when it is ultimatively intended to store the
943 result in pseudoregister v. If v is assigned to an actual
944 register, this register will be returned. Otherwise (when v is
945 spilled) this function returns tempregnum. If not already done,
946 regoff and flags are set in the stack location.
948 *******************************************************************************/
950 s4 codegen_reg_of_var(u2 opcode, varinfo *v, s4 tempregnum)
952 if (!(v->flags & INMEMORY))
959 /* codegen_reg_of_dst **********************************************************
961 This function determines a register, to which the result of an
962 operation should go, when it is ultimatively intended to store the
963 result in iptr->dst.var. If dst.var is assigned to an actual
964 register, this register will be returned. Otherwise (when it is
965 spilled) this function returns tempregnum. If not already done,
966 regoff and flags are set in the stack location.
968 *******************************************************************************/
970 s4 codegen_reg_of_dst(jitdata *jd, instruction *iptr, s4 tempregnum)
972 return codegen_reg_of_var(iptr->opc, VAROP(iptr->dst), tempregnum);
976 /* codegen_emit_phi_moves ****************************************************
978 Emits phi moves at the end of the basicblock.
980 *******************************************************************************/
982 #if defined(ENABLE_SSA)
983 void codegen_emit_phi_moves(jitdata *jd, basicblock *bptr)
996 /* Moves from phi functions with highest indices have to be */
997 /* inserted first, since this is the order as is used for */
998 /* conflict resolution */
1000 for(i = ls->num_phi_moves[bptr->nr] - 1; i >= 0 ; i--) {
1001 lt_d = ls->phi_moves[bptr->nr][i][0];
1002 lt_s = ls->phi_moves[bptr->nr][i][1];
1003 #if defined(SSA_DEBUG_VERBOSE)
1005 printf("BB %3i Move %3i <- %3i ", bptr->nr, lt_d, lt_s);
1007 if (lt_s == UNUSED) {
1008 #if defined(SSA_DEBUG_VERBOSE)
1010 printf(" ... not processed \n");
1015 d = VAR(ls->lifetime[lt_d].v_index);
1016 s = VAR(ls->lifetime[lt_s].v_index);
1019 if (d->type == -1) {
1020 #if defined(SSA_DEBUG_VERBOSE)
1022 printf("...returning - phi lifetimes where joined\n");
1027 if (s->type == -1) {
1028 #if defined(SSA_DEBUG_VERBOSE)
1030 printf("...returning - phi lifetimes where joined\n");
1036 tmp_i.s1.varindex = ls->lifetime[lt_s].v_index;
1037 tmp_i.dst.varindex = ls->lifetime[lt_d].v_index;
1038 emit_copy(jd, &tmp_i);
1040 #if defined(SSA_DEBUG_VERBOSE)
1041 if (compileverbose) {
1042 if (IS_INMEMORY(d->flags) && IS_INMEMORY(s->flags)) {
1044 printf("M%3i <- M%3i",d->vv.regoff,s->vv.regoff);
1046 else if (IS_INMEMORY(s->flags)) {
1048 printf("R%3i <- M%3i",d->vv.regoff,s->vv.regoff);
1050 else if (IS_INMEMORY(d->flags)) {
1052 printf("M%3i <- R%3i",d->vv.regoff,s->vv.regoff);
1056 printf("R%3i <- R%3i",d->vv.regoff,s->vv.regoff);
1060 #endif /* defined(SSA_DEBUG_VERBOSE) */
1063 #endif /* defined(ENABLE_SSA) */
1066 /* REMOVEME When we have exception handling in C. */
1068 void *md_asm_codegen_get_pv_from_pc(void *ra)
1070 return md_codegen_get_pv_from_pc(ra);
1075 * These are local overrides for various environment variables in Emacs.
1076 * Please do not remove this and leave it at the end of the file, where
1077 * Emacs will automagically detect them.
1078 * ---------------------------------------------------------------------
1081 * indent-tabs-mode: t
1085 * vim:noexpandtab:sw=4:ts=4: