1 /* src/vm/jit/codegen-common.cpp - 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.hpp"
58 #include "toolbox/logging.h"
60 #include "native/llni.h"
61 #include "native/localref.hpp"
62 #include "native/native.hpp"
64 #include "threads/thread.hpp"
66 #include "vm/jit/builtin.hpp"
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.hpp"
78 #include "vm/jit/codegen-common.hpp"
80 #if defined(ENABLE_DISASSEMBLER)
81 # include "vm/jit/disass.h"
84 #include "vm/jit/dseg.h"
85 #include "vm/jit/emit-common.hpp"
86 #include "vm/jit/jit.hpp"
87 #include "vm/jit/linenumbertable.hpp"
88 #include "vm/jit/methodheader.h"
89 #include "vm/jit/methodtree.h"
90 #include "vm/jit/patcher-common.hpp"
91 #include "vm/jit/replace.hpp"
92 #if defined(ENABLE_SSA)
93 # include "vm/jit/optimizing/lsra.h"
94 # include "vm/jit/optimizing/ssa.h"
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 = (u1*) DumpMemory::allocate(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 = (u1*) DumpMemory::allocate(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 = new DumpList<branch_label_ref_t*>();
176 cd->linenumbers = new DumpList<Linenumber>();
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 = new DumpList<branch_label_ref_t*>();
217 cd->linenumbers = new DumpList<Linenumber>();
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 = (u1*) DumpMemory::reallocate(cd->mcodebase,
336 cd->mcodeend = cd->mcodebase + cd->mcodesize;
338 /* set new mcodeptr */
340 cd->mcodeptr = cd->mcodebase + (cd->mcodeptr - oldmcodebase);
342 #if defined(__I386__) || defined(__MIPS__) || defined(__X86_64__) || defined(__M68K__) || defined(ENABLE_INTRP) \
343 || defined(__SPARC_64__)
344 /* adjust the pointer to the last patcher position */
346 if (cd->lastmcodeptr != NULL)
347 cd->lastmcodeptr = cd->mcodebase + (cd->lastmcodeptr - oldmcodebase);
352 /* codegen_ncode_increase ******************************************************
356 *******************************************************************************/
358 #if defined(ENABLE_INTRP)
359 u1 *codegen_ncode_increase(codegendata *cd, u1 *ncodeptr)
363 /* save old ncodebase pointer */
365 oldncodebase = cd->ncodebase;
367 /* reallocate to new, doubled memory */
369 cd->ncodebase = DMREALLOC(cd->ncodebase,
375 /* return the new ncodeptr */
377 return (cd->ncodebase + (ncodeptr - oldncodebase));
382 /* codegen_add_branch_ref ******************************************************
384 Prepends an branch to the list.
386 *******************************************************************************/
388 void codegen_add_branch_ref(codegendata *cd, basicblock *target, s4 condition, s4 reg, u4 options)
393 STATISTICS(count_branches_unresolved++);
395 /* calculate the mpc of the branch instruction */
397 branchmpc = cd->mcodeptr - cd->mcodebase;
399 br = (branchref*) DumpMemory::allocate(sizeof(branchref));
401 br->branchmpc = branchmpc;
402 br->condition = condition;
404 br->options = options;
405 br->next = target->branchrefs;
407 target->branchrefs = br;
411 /* codegen_resolve_branchrefs **************************************************
413 Resolves and patches the branch references of a given basic block.
415 *******************************************************************************/
417 void codegen_resolve_branchrefs(codegendata *cd, basicblock *bptr)
422 /* Save the mcodeptr because in the branch emitting functions
423 we generate code somewhere inside already generated code,
424 but we're still in the actual code generation phase. */
426 mcodeptr = cd->mcodeptr;
428 /* just to make sure */
430 assert(bptr->mpc >= 0);
432 for (br = bptr->branchrefs; br != NULL; br = br->next) {
433 /* temporary set the mcodeptr */
435 cd->mcodeptr = cd->mcodebase + br->branchmpc;
437 /* emit_bccz and emit_branch emit the correct code, even if we
438 pass condition == BRANCH_UNCONDITIONAL or reg == -1. */
440 emit_bccz(cd, bptr, br->condition, br->reg, br->options);
443 /* restore mcodeptr */
445 cd->mcodeptr = mcodeptr;
449 /* codegen_branch_label_add ****************************************************
451 Append an branch to the label-branch list.
453 *******************************************************************************/
455 void codegen_branch_label_add(codegendata *cd, s4 label, s4 condition, s4 reg, u4 options)
457 // Calculate the current mpc.
458 int32_t mpc = cd->mcodeptr - cd->mcodebase;
460 branch_label_ref_t* br = (branch_label_ref_t*) DumpMemory::allocate(sizeof(branch_label_ref_t));
464 br->condition = condition;
466 br->options = options;
468 // Add the branch to the list.
469 cd->brancheslabel->push_back(br);
473 /* codegen_set_replacement_point_notrap ****************************************
475 Record the position of a non-trappable replacement point.
477 *******************************************************************************/
479 #if defined(ENABLE_REPLACEMENT)
481 void codegen_set_replacement_point_notrap(codegendata *cd, s4 type)
483 void codegen_set_replacement_point_notrap(codegendata *cd)
486 assert(cd->replacementpoint);
487 assert(cd->replacementpoint->type == type);
488 assert(cd->replacementpoint->flags & RPLPOINT_FLAG_NOTRAP);
490 cd->replacementpoint->pc = (u1*) (ptrint) (cd->mcodeptr - cd->mcodebase);
492 cd->replacementpoint++;
494 #endif /* defined(ENABLE_REPLACEMENT) */
497 /* codegen_set_replacement_point ***********************************************
499 Record the position of a trappable replacement point.
501 *******************************************************************************/
503 #if defined(ENABLE_REPLACEMENT)
505 void codegen_set_replacement_point(codegendata *cd, s4 type)
507 void codegen_set_replacement_point(codegendata *cd)
510 assert(cd->replacementpoint);
511 assert(cd->replacementpoint->type == type);
512 assert(!(cd->replacementpoint->flags & RPLPOINT_FLAG_NOTRAP));
514 cd->replacementpoint->pc = (u1*) (ptrint) (cd->mcodeptr - cd->mcodebase);
516 cd->replacementpoint++;
519 /* XXX actually we should use an own REPLACEMENT_NOPS here! */
520 if (opt_TestReplacement)
524 /* XXX assert(cd->lastmcodeptr <= cd->mcodeptr); */
526 cd->lastmcodeptr = cd->mcodeptr + PATCHER_CALL_SIZE;
528 #endif /* defined(ENABLE_REPLACEMENT) */
531 /* codegen_finish **************************************************************
533 Finishes the code generation. A new memory, large enough for both
534 data and code, is allocated and data and code are copied together
535 to their final layout, unresolved jumps are resolved, ...
537 *******************************************************************************/
539 void codegen_finish(jitdata *jd)
544 #if defined(ENABLE_INTRP)
552 /* get required compiler data */
557 /* prevent compiler warning */
559 #if defined(ENABLE_INTRP)
563 /* calculate the code length */
565 mcodelen = (s4) (cd->mcodeptr - cd->mcodebase);
567 #if defined(ENABLE_STATISTICS)
569 count_code_len += mcodelen;
570 count_data_len += cd->dseglen;
574 alignedmcodelen = MEMORY_ALIGN(mcodelen, MAX_ALIGN);
576 #if defined(ENABLE_INTRP)
578 ncodelen = cd->ncodeptr - cd->ncodebase;
580 ncodelen = 0; /* avoid compiler warning */
584 cd->dseglen = MEMORY_ALIGN(cd->dseglen, MAX_ALIGN);
585 alignedlen = alignedmcodelen + cd->dseglen;
587 #if defined(ENABLE_INTRP)
589 alignedlen += ncodelen;
593 /* allocate new memory */
595 code->mcodelength = mcodelen + cd->dseglen;
596 code->mcode = CNEW(u1, alignedlen);
598 /* set the entrypoint of the method */
600 assert(code->entrypoint == NULL);
601 code->entrypoint = epoint = (code->mcode + cd->dseglen);
603 /* fill the data segment (code->entrypoint must already be set!) */
607 /* copy code to the new location */
609 MCOPY((void *) code->entrypoint, cd->mcodebase, u1, mcodelen);
611 #if defined(ENABLE_INTRP)
612 /* relocate native dynamic superinstruction code (if any) */
615 cd->mcodebase = code->entrypoint;
618 u1 *ncodebase = code->mcode + cd->dseglen + alignedmcodelen;
620 MCOPY((void *) ncodebase, cd->ncodebase, u1, ncodelen);
622 /* flush the instruction and data caches */
624 md_cacheflush(ncodebase, ncodelen);
626 /* set some cd variables for dynamic_super_rerwite */
628 cd->ncodebase = ncodebase;
631 cd->ncodebase = NULL;
634 dynamic_super_rewrite(cd);
638 /* Create the exception table. */
640 exceptiontable_create(jd);
642 /* Create the linenumber table. */
644 code->linenumbertable = new LinenumberTable(jd);
646 /* jump table resolving */
648 for (jr = cd->jumpreferences; jr != NULL; jr = jr->next)
649 *((functionptr *) ((ptrint) epoint + jr->tablepos)) =
650 (functionptr) ((ptrint) epoint + (ptrint) jr->target->mpc);
652 /* patcher resolving */
656 #if defined(ENABLE_REPLACEMENT)
657 /* replacement point resolving */
662 rp = code->rplpoints;
663 for (i=0; i<code->rplpointcount; ++i, ++rp) {
664 rp->pc = (u1*) ((ptrint) epoint + (ptrint) rp->pc);
667 #endif /* defined(ENABLE_REPLACEMENT) */
669 /* Insert method into methodtree to find the entrypoint. */
671 methodtree_insert(code->entrypoint, code->entrypoint + mcodelen);
673 #if defined(__I386__) || defined(__X86_64__) || defined(__XDSPCORE__) || defined(__M68K__) || defined(ENABLE_INTRP)
674 /* resolve data segment references */
676 dseg_resolve_datareferences(jd);
679 /* flush the instruction and data caches */
681 md_cacheflush(code->mcode, code->mcodelength);
685 /* codegen_start_native_call ***************************************************
687 Prepares the stuff required for a native (JNI) function call:
689 - adds a stackframe info structure to the chain, for stacktraces
690 - prepares the local references table on the stack
692 The layout of the native stub stackframe should look like this:
694 +---------------------------+ <- java SP (of parent Java function)
696 +---------------------------+ <- data SP
698 | stackframe info structure |
700 +---------------------------+
702 | local references table |
704 +---------------------------+
706 | saved registers (if any) |
708 +---------------------------+
710 | arguments (if any) |
712 +---------------------------+ <- current SP (native stub)
714 *******************************************************************************/
716 java_handle_t *codegen_start_native_call(u1 *sp, u1 *pv)
718 stackframeinfo_t *sfi;
728 STATISTICS(count_calls_java_to_native++);
730 /* Get the methodinfo. */
732 m = code_get_methodinfo_for_pv(pv);
736 framesize = *((int32_t *) (pv + FrameSize));
738 assert(framesize >= (int32_t) (sizeof(stackframeinfo_t) + sizeof(localref_table)));
740 /* calculate needed values */
742 #if defined(__ALPHA__) || defined(__ARM__)
743 datasp = sp + framesize - SIZEOF_VOID_P;
744 javasp = sp + framesize;
745 arg_regs = (uint64_t *) sp;
746 arg_stack = (uint64_t *) javasp;
747 #elif defined(__MIPS__)
748 /* MIPS always uses 8 bytes to store the RA */
749 datasp = sp + framesize - 8;
750 javasp = sp + framesize;
751 #elif defined(__S390__)
752 datasp = sp + framesize - 8;
753 javasp = sp + framesize;
754 arg_regs = (uint64_t *) (sp + 96);
755 arg_stack = (uint64_t *) javasp;
756 #elif defined(__I386__) || defined(__M68K__) || defined(__X86_64__)
757 datasp = sp + framesize;
758 javasp = sp + framesize + SIZEOF_VOID_P;
759 arg_regs = (uint64_t *) sp;
760 arg_stack = (uint64_t *) javasp;
761 #elif defined(__POWERPC__)
762 datasp = sp + framesize;
763 javasp = sp + framesize;
764 arg_regs = (uint64_t *) (sp + LA_SIZE + 4 * SIZEOF_VOID_P);
765 arg_stack = (uint64_t *) javasp;
766 #elif defined(__POWERPC64__)
767 datasp = sp + framesize;
768 javasp = sp + framesize;
769 arg_regs = (uint64_t *) (sp + PA_SIZE + LA_SIZE + 4 * SIZEOF_VOID_P);
770 arg_stack = (uint64_t *) javasp;
772 /* XXX is was unable to do this port for SPARC64, sorry. (-michi) */
773 /* XXX maybe we need to pass the RA as argument there */
774 vm_abort("codegen_start_native_call: unsupported architecture");
777 /* get data structures from stack */
779 sfi = (stackframeinfo_t *) (datasp - sizeof(stackframeinfo_t));
780 lrt = (localref_table *) (datasp - sizeof(stackframeinfo_t) -
781 sizeof(localref_table));
783 #if defined(ENABLE_JNI)
784 /* add current JNI local references table to this thread */
786 localref_table_add(lrt);
790 # if defined(__ALPHA__) || defined(__I386__) || defined(__M68K__) || defined(__POWERPC__) || defined(__POWERPC64__) || defined(__S390__) || defined(__X86_64__)
791 /* print the call-trace if necesarry */
792 /* BEFORE: filling the local reference table */
794 if (opt_TraceJavaCalls)
795 trace_java_call_enter(m, arg_regs, arg_stack);
799 #if defined(ENABLE_HANDLES)
800 /* place all references into the local reference table */
801 /* BEFORE: creating stackframeinfo */
803 localref_native_enter(m, arg_regs, arg_stack);
806 /* Add a stackframeinfo for this native method. We don't have RA
807 and XPC here. These are determined in
808 stacktrace_stackframeinfo_add. */
810 stacktrace_stackframeinfo_add(sfi, pv, sp, NULL, NULL);
812 /* Return a wrapped classinfo for static methods. */
814 if (m->flags & ACC_STATIC)
815 return (java_handle_t *) LLNI_classinfo_wrap(m->clazz);
821 /* codegen_finish_native_call **************************************************
823 Removes the stuff required for a native (JNI) function call.
824 Additionally it checks for an exceptions and in case, get the
825 exception object and clear the pointer.
827 *******************************************************************************/
829 java_object_t *codegen_finish_native_call(u1 *sp, u1 *pv)
831 stackframeinfo_t *sfi;
841 /* get information from method header */
843 code = code_get_codeinfo_for_pv(pv);
845 framesize = *((int32_t *) (pv + FrameSize));
849 /* get the methodinfo */
854 /* calculate needed values */
856 #if defined(__ALPHA__) || defined(__ARM__)
857 datasp = sp + framesize - SIZEOF_VOID_P;
858 ret_regs = (uint64_t *) sp;
859 #elif defined(__MIPS__)
860 /* MIPS always uses 8 bytes to store the RA */
861 datasp = sp + framesize - 8;
862 #elif defined(__S390__)
863 datasp = sp + framesize - 8;
864 ret_regs = (uint64_t *) (sp + 96);
865 #elif defined(__I386__)
866 datasp = sp + framesize;
867 ret_regs = (uint64_t *) (sp + 2 * SIZEOF_VOID_P);
868 #elif defined(__M68K__)
869 datasp = sp + framesize;
870 ret_regs = (uint64_t *) (sp + 2 * 8);
871 #elif defined(__X86_64__)
872 datasp = sp + framesize;
873 ret_regs = (uint64_t *) sp;
874 #elif defined(__POWERPC__)
875 datasp = sp + framesize;
876 ret_regs = (uint64_t *) (sp + LA_SIZE + 2 * SIZEOF_VOID_P);
877 #elif defined(__POWERPC64__)
878 datasp = sp + framesize;
879 ret_regs = (uint64_t *) (sp + PA_SIZE + LA_SIZE + 2 * SIZEOF_VOID_P);
881 vm_abort("codegen_finish_native_call: unsupported architecture");
884 /* get data structures from stack */
886 sfi = (stackframeinfo_t *) (datasp - sizeof(stackframeinfo_t));
888 /* Remove current stackframeinfo from chain. */
890 stacktrace_stackframeinfo_remove(sfi);
892 #if defined(ENABLE_HANDLES)
893 /* unwrap the return value from the local reference table */
894 /* AFTER: removing the stackframeinfo */
895 /* BEFORE: releasing the local reference table */
897 localref_native_exit(m, ret_regs);
900 /* get and unwrap the exception */
901 /* AFTER: removing the stackframe info */
902 /* BEFORE: releasing the local reference table */
904 e = exceptions_get_and_clear_exception();
907 #if defined(ENABLE_JNI)
908 /* release JNI local references table for this thread */
910 localref_frame_pop_all();
911 localref_table_remove();
915 # if defined(__ALPHA__) || defined(__I386__) || defined(__M68K__) || defined(__POWERPC__) || defined(__POWERPC64__) || defined(__S390__) || defined(__X86_64__)
916 /* print the call-trace if necesarry */
917 /* AFTER: unwrapping the return value */
919 if (opt_TraceJavaCalls)
920 trace_java_call_exit(m, ret_regs);
928 /* codegen_reg_of_var **********************************************************
930 This function determines a register, to which the result of an
931 operation should go, when it is ultimatively intended to store the
932 result in pseudoregister v. If v is assigned to an actual
933 register, this register will be returned. Otherwise (when v is
934 spilled) this function returns tempregnum. If not already done,
935 regoff and flags are set in the stack location.
937 *******************************************************************************/
939 s4 codegen_reg_of_var(u2 opcode, varinfo *v, s4 tempregnum)
941 if (!(v->flags & INMEMORY))
948 /* codegen_reg_of_dst **********************************************************
950 This function determines a register, to which the result of an
951 operation should go, when it is ultimatively intended to store the
952 result in iptr->dst.var. If dst.var is assigned to an actual
953 register, this register will be returned. Otherwise (when it is
954 spilled) this function returns tempregnum. If not already done,
955 regoff and flags are set in the stack location.
957 *******************************************************************************/
959 s4 codegen_reg_of_dst(jitdata *jd, instruction *iptr, s4 tempregnum)
961 return codegen_reg_of_var(iptr->opc, VAROP(iptr->dst), tempregnum);
965 /* codegen_emit_phi_moves ****************************************************
967 Emits phi moves at the end of the basicblock.
969 *******************************************************************************/
971 #if defined(ENABLE_SSA)
972 void codegen_emit_phi_moves(jitdata *jd, basicblock *bptr)
985 /* Moves from phi functions with highest indices have to be */
986 /* inserted first, since this is the order as is used for */
987 /* conflict resolution */
989 for(i = ls->num_phi_moves[bptr->nr] - 1; i >= 0 ; i--) {
990 lt_d = ls->phi_moves[bptr->nr][i][0];
991 lt_s = ls->phi_moves[bptr->nr][i][1];
992 #if defined(SSA_DEBUG_VERBOSE)
994 printf("BB %3i Move %3i <- %3i ", bptr->nr, lt_d, lt_s);
996 if (lt_s == UNUSED) {
997 #if defined(SSA_DEBUG_VERBOSE)
999 printf(" ... not processed \n");
1004 d = VAR(ls->lifetime[lt_d].v_index);
1005 s = VAR(ls->lifetime[lt_s].v_index);
1008 if (d->type == -1) {
1009 #if defined(SSA_DEBUG_VERBOSE)
1011 printf("...returning - phi lifetimes where joined\n");
1016 if (s->type == -1) {
1017 #if defined(SSA_DEBUG_VERBOSE)
1019 printf("...returning - phi lifetimes where joined\n");
1025 tmp_i.s1.varindex = ls->lifetime[lt_s].v_index;
1026 tmp_i.dst.varindex = ls->lifetime[lt_d].v_index;
1027 emit_copy(jd, &tmp_i);
1029 #if defined(SSA_DEBUG_VERBOSE)
1030 if (compileverbose) {
1031 if (IS_INMEMORY(d->flags) && IS_INMEMORY(s->flags)) {
1033 printf("M%3i <- M%3i",d->vv.regoff,s->vv.regoff);
1035 else if (IS_INMEMORY(s->flags)) {
1037 printf("R%3i <- M%3i",d->vv.regoff,s->vv.regoff);
1039 else if (IS_INMEMORY(d->flags)) {
1041 printf("M%3i <- R%3i",d->vv.regoff,s->vv.regoff);
1045 printf("R%3i <- R%3i",d->vv.regoff,s->vv.regoff);
1049 #endif /* defined(SSA_DEBUG_VERBOSE) */
1052 #endif /* defined(ENABLE_SSA) */
1055 /* REMOVEME When we have exception handling in C. */
1057 void *md_asm_codegen_get_pv_from_pc(void *ra)
1059 return md_codegen_get_pv_from_pc(ra);
1064 * These are local overrides for various environment variables in Emacs.
1065 * Please do not remove this and leave it at the end of the file, where
1066 * Emacs will automagically detect them.
1067 * ---------------------------------------------------------------------
1070 * indent-tabs-mode: t
1074 * vim:noexpandtab:sw=4:ts=4: