PERFORCE change 158286 for review
Oleksandr Tymoshenko
gonzo at FreeBSD.org
Wed Feb 25 12:46:20 PST 2009
http://perforce.freebsd.org/chv.cgi?CH=158286
Change 158286 by gonzo at gonzo_figaro on 2009/02/25 20:46:02
- Add AVR32 bits to GCC
Affected files ...
.. //depot/projects/avr32/src/contrib/gcc/config.gcc#2 edit
.. //depot/projects/avr32/src/contrib/gcc/config/avr32/avr32-elf.h#1 add
.. //depot/projects/avr32/src/contrib/gcc/config/avr32/avr32-modes.def#1 add
.. //depot/projects/avr32/src/contrib/gcc/config/avr32/avr32-protos.h#1 add
.. //depot/projects/avr32/src/contrib/gcc/config/avr32/avr32.c#1 add
.. //depot/projects/avr32/src/contrib/gcc/config/avr32/avr32.h#1 add
.. //depot/projects/avr32/src/contrib/gcc/config/avr32/avr32.md#1 add
.. //depot/projects/avr32/src/contrib/gcc/config/avr32/avr32.opt#1 add
.. //depot/projects/avr32/src/contrib/gcc/config/avr32/crti.asm#1 add
.. //depot/projects/avr32/src/contrib/gcc/config/avr32/crtn.asm#1 add
.. //depot/projects/avr32/src/contrib/gcc/config/avr32/fpcp.md#1 add
.. //depot/projects/avr32/src/contrib/gcc/config/avr32/freebsd.h#1 add
.. //depot/projects/avr32/src/contrib/gcc/config/avr32/lib1funcs.S#1 add
.. //depot/projects/avr32/src/contrib/gcc/config/avr32/lib2funcs.S#1 add
.. //depot/projects/avr32/src/contrib/gcc/config/avr32/linux-elf.h#1 add
.. //depot/projects/avr32/src/contrib/gcc/config/avr32/predicates.md#1 add
.. //depot/projects/avr32/src/contrib/gcc/config/avr32/simd.md#1 add
.. //depot/projects/avr32/src/contrib/gcc/config/avr32/sync.md#1 add
.. //depot/projects/avr32/src/contrib/gcc/config/avr32/t-avr32#1 add
.. //depot/projects/avr32/src/contrib/gcc/config/avr32/t-elf#1 add
.. //depot/projects/avr32/src/contrib/gcc/config/avr32/uclinux-elf.h#1 add
.. //depot/projects/avr32/src/contrib/gcc/expmed.c#2 edit
.. //depot/projects/avr32/src/contrib/gcc/expr.c#2 edit
.. //depot/projects/avr32/src/contrib/gcc/flow.c#2 edit
.. //depot/projects/avr32/src/contrib/gcc/function.c#2 edit
.. //depot/projects/avr32/src/contrib/gcc/genemit.c#2 edit
.. //depot/projects/avr32/src/contrib/gcc/genflags.c#2 edit
.. //depot/projects/avr32/src/contrib/gcc/genoutput.c#2 edit
.. //depot/projects/avr32/src/contrib/gcc/ifcvt.c#2 edit
.. //depot/projects/avr32/src/contrib/gcc/longlong.h#2 edit
.. //depot/projects/avr32/src/contrib/gcc/optabs.h#2 edit
.. //depot/projects/avr32/src/contrib/gcc/regrename.c#2 edit
.. //depot/projects/avr32/src/contrib/gcc/reload.c#2 edit
.. //depot/projects/avr32/src/contrib/gcc/sched-deps.c#2 edit
Differences ...
==== //depot/projects/avr32/src/contrib/gcc/config.gcc#2 (text+ko) ====
@@ -782,6 +782,24 @@
tm_file="avr/avr.h dbxelf.h"
use_fixproto=yes
;;
+avr32*-*-linux*)
+ tm_file="dbxelf.h elfos.h linux.h avr32/linux-elf.h avr32/avr32.h "
+ tmake_file="t-linux avr32/t-avr32 avr32/t-elf"
+ extra_parts="crtbegin.o crtbeginS.o crtend.o crtendS.o"
+ extra_modes=avr32/avr32-modes.def
+ gnu_ld=yes
+ ;;
+avr32*-*-uclinux*)
+ tm_file="dbxelf.h elfos.h linux.h avr32/linux-elf.h avr32/uclinux-elf.h avr32/avr32.h"
+ tmake_file="t-linux avr32/t-avr32 avr32/t-elf"
+ extra_modes=avr32/avr32-modes.def
+ gnu_ld=yes
+ ;;
+avr32-*-*)
+ tm_file="dbxelf.h elfos.h avr32/avr32.h avr32/avr32-elf.h"
+ tmake_file="avr32/t-avr32 avr32/t-elf"
+ extra_modes=avr32/avr32-modes.def
+ ;;
bfin*-elf*)
tm_file="${tm_file} dbxelf.h elfos.h bfin/elf.h"
tmake_file=bfin/t-bfin-elf
@@ -1682,6 +1700,9 @@
pdp11-*-*)
use_fixproto=yes
;;
+avr-*-*)
+ use_fixproto=yes
+ ;;
# port not yet contributed
#powerpc-*-openbsd*)
# tmake_file="${tmake_file} rs6000/t-fprules rs6000/t-fprules-fpbit "
@@ -2718,6 +2739,32 @@
fi
;;
+ avr32*-*-*)
+ supported_defaults="part arch"
+
+ case "$with_part" in
+ "" \
+ | "ap7000" | "ap7010" | "ap7020" | "uc3a0256" | "uc3a0512" | "uc3a1128" | "uc3a1256" | "uc3a1512" )
+ # OK
+ ;;
+ *)
+ echo "Unknown part used in --with-part=$with_part" 1>&2
+ exit 1
+ ;;
+ esac
+
+ case "$with_arch" in
+ "" \
+ | "ap" | "uc")
+ # OK
+ ;;
+ *)
+ echo "Unknown arch used in --with-arch=$with_arch" 1>&2
+ exit 1
+ ;;
+ esac
+ ;;
+
fr*-*-*linux*)
supported_defaults=cpu
case "$with_cpu" in
==== //depot/projects/avr32/src/contrib/gcc/expmed.c#2 (text+ko) ====
@@ -37,6 +37,7 @@
#include "real.h"
#include "recog.h"
#include "langhooks.h"
+#include "target.h"
static void store_fixed_bit_field (rtx, unsigned HOST_WIDE_INT,
unsigned HOST_WIDE_INT,
@@ -455,9 +456,19 @@
? ((GET_MODE_SIZE (fieldmode) >= UNITS_PER_WORD
|| GET_MODE_SIZE (GET_MODE (op0)) == GET_MODE_SIZE (fieldmode))
&& byte_offset % GET_MODE_SIZE (fieldmode) == 0)
- : (! SLOW_UNALIGNED_ACCESS (fieldmode, MEM_ALIGN (op0))
- || (offset * BITS_PER_UNIT % bitsize == 0
- && MEM_ALIGN (op0) % GET_MODE_BITSIZE (fieldmode) == 0))))
+ : (
+
+ /* NB! Added for AVR32, and I think this should be true for
+ all targets not using narrow volatile bitfields. If the
+ bitfield is volatile then we need to perform an access
+ consistent with the container type. */
+ !(MEM_VOLATILE_P (op0)
+ && GET_MODE_BITSIZE (GET_MODE (op0)) != bitsize
+ && bitsize < BITS_PER_WORD
+ && !targetm.narrow_volatile_bitfield ())
+ && (! SLOW_UNALIGNED_ACCESS (fieldmode, MEM_ALIGN (op0))
+ || (offset * BITS_PER_UNIT % bitsize == 0
+ && MEM_ALIGN (op0) % GET_MODE_BITSIZE (fieldmode) == 0)))))
{
if (MEM_P (op0))
op0 = adjust_address (op0, fieldmode, offset);
@@ -1257,6 +1268,13 @@
&& GET_MODE_SIZE (mode1) != 0
&& byte_offset % GET_MODE_SIZE (mode1) == 0)
|| (MEM_P (op0)
+ /* NB! Added for AVR32, and I think this should be true for
+ all targets not using narrow volatile bitfields. If the
+ bitfield is volatile then we need to perform an access
+ consistent with the container type. */
+ && !(MEM_VOLATILE_P (op0)
+ && GET_MODE_BITSIZE (GET_MODE (op0)) != bitsize
+ && !targetm.narrow_volatile_bitfield ())
&& (! SLOW_UNALIGNED_ACCESS (mode, MEM_ALIGN (op0))
|| (offset * BITS_PER_UNIT % bitsize == 0
&& MEM_ALIGN (op0) % bitsize == 0)))))
==== //depot/projects/avr32/src/contrib/gcc/expr.c#2 (text+ko) ====
@@ -3520,18 +3520,19 @@
}
else
{
+ emit_move_insn (stack_pointer_rtx,
+ expand_binop (Pmode,
#ifdef STACK_GROWS_DOWNWARD
- /* ??? This seems wrong if STACK_PUSH_CODE == POST_DEC. */
- dest_addr = gen_rtx_PLUS (Pmode, stack_pointer_rtx,
- GEN_INT (-(HOST_WIDE_INT) rounded_size));
+ sub_optab,
#else
- /* ??? This seems wrong if STACK_PUSH_CODE == POST_INC. */
- dest_addr = gen_rtx_PLUS (Pmode, stack_pointer_rtx,
- GEN_INT (rounded_size));
+ add_optab,
#endif
- dest_addr = gen_rtx_PRE_MODIFY (Pmode, stack_pointer_rtx, dest_addr);
+ stack_pointer_rtx,
+ GEN_INT (rounded_size),
+ NULL_RTX, 0, OPTAB_LIB_WIDEN));
+ dest_addr = stack_pointer_rtx;
}
-
+
dest = gen_rtx_MEM (mode, dest_addr);
if (type != 0)
@@ -5510,7 +5511,21 @@
is a bit field, we cannot use addressing to access it.
Use bit-field techniques or SUBREG to store in it. */
- if (mode == VOIDmode
+ if (
+ /* NB! Added for AVR32, and I think this should be true for
+ all targets not using narrow volatile bitfields. If the
+ bitfield is volatile then we need to perform an access
+ consistent with the container type. */
+ (MEM_P (target)
+ && MEM_VOLATILE_P (target)
+ && ((GET_MODE (target) != BLKmode
+ && GET_MODE_BITSIZE (GET_MODE (target)) > bitsize )
+ /* If BLKmode, check if this is a record. Do not know
+ if this is really necesarry though...*/
+ || (GET_MODE (target) == BLKmode
+ && TREE_CODE (type) == RECORD_TYPE))
+ && !targetm.narrow_volatile_bitfield ())
+ || mode == VOIDmode
|| (mode != BLKmode && ! direct_store[(int) mode]
&& GET_MODE_CLASS (mode) != MODE_COMPLEX_INT
&& GET_MODE_CLASS (mode) != MODE_COMPLEX_FLOAT)
@@ -7512,7 +7527,21 @@
by doing the extract into an object as wide as the field
(which we know to be the width of a basic mode), then
storing into memory, and changing the mode to BLKmode. */
- if (mode1 == VOIDmode
+ if (
+ /* NB! Added for AVR32, and I think this should be true for
+ all targets not using narrow volatile bitfields. If the
+ bitfield is volatile then we need to perform an access
+ consistent with the container type. */
+ (MEM_P (op0)
+ && MEM_VOLATILE_P (op0)
+ && ((GET_MODE (op0) != BLKmode
+ && GET_MODE_BITSIZE (GET_MODE (op0)) > bitsize )
+ /* If BLKmode, check if this is a record. Do not know
+ if this is really necesarry though...*/
+ || (GET_MODE (op0) == BLKmode
+ && TREE_CODE (type) == RECORD_TYPE))
+ && !targetm.narrow_volatile_bitfield ())
+ || mode1 == VOIDmode
|| REG_P (op0) || GET_CODE (op0) == SUBREG
|| (mode1 != BLKmode && ! direct_load[(int) mode1]
&& GET_MODE_CLASS (mode) != MODE_COMPLEX_INT
==== //depot/projects/avr32/src/contrib/gcc/flow.c#2 (text+ko) ====
@@ -3328,12 +3328,12 @@
if (GET_CODE (x) == NOT)
return XEXP (x, 0);
if (COMPARISON_P (x)
- && REG_P (XEXP (x, 0)))
+ /* && REG_P (XEXP (x, 0))*/)
{
- gcc_assert (XEXP (x, 1) == const0_rtx);
+ /*gcc_assert (XEXP (x, 1) == const0_rtx);*/
return gen_rtx_fmt_ee (reversed_comparison_code (x, NULL),
- VOIDmode, XEXP (x, 0), const0_rtx);
+ VOIDmode, XEXP (x, 0), XEXP (x, 0) /*const0_rtx*/);
}
return gen_rtx_NOT (0, x);
}
==== //depot/projects/avr32/src/contrib/gcc/function.c#2 (text+ko) ====
@@ -2679,8 +2679,12 @@
SET_DECL_RTL (parm, parmreg);
/* Copy the value into the register. */
- if (data->nominal_mode != data->passed_mode
- || promoted_nominal_mode != data->promoted_mode)
+ if ( (data->nominal_mode != data->passed_mode
+ /* Added for AVR32: If passed_mode is equal
+ to promoted nominal mode why should be convert?
+ The conversion should make no difference. */
+ && data->passed_mode != promoted_nominal_mode)
+ || promoted_nominal_mode != data->promoted_mode)
{
int save_tree_used;
==== //depot/projects/avr32/src/contrib/gcc/genemit.c#2 (text+ko) ====
@@ -122,6 +122,24 @@
}
static void
+gen_vararg_prologue(int operands)
+{
+ int i;
+
+ if (operands > 1)
+ {
+ for (i = 1; i < operands; i++)
+ printf(" rtx operand%d ATTRIBUTE_UNUSED;\n", i);
+
+ printf(" va_list args;\n\n");
+ printf(" va_start(args, operand0);\n");
+ for (i = 1; i < operands; i++)
+ printf(" operand%d = va_arg(args, rtx);\n", i);
+ printf(" va_end(args);\n\n");
+ }
+}
+
+static void
print_code (RTX_CODE code)
{
const char *p1;
@@ -406,18 +424,16 @@
fatal ("match_dup operand number has no match_operand");
/* Output the function name and argument declarations. */
- printf ("rtx\ngen_%s (", XSTR (insn, 0));
+ printf ("rtx\ngen_%s ", XSTR (insn, 0));
+
if (operands)
- for (i = 0; i < operands; i++)
- if (i)
- printf (",\n\trtx operand%d ATTRIBUTE_UNUSED", i);
- else
- printf ("rtx operand%d ATTRIBUTE_UNUSED", i);
+ printf("(rtx operand0 ATTRIBUTE_UNUSED, ...)\n");
else
- printf ("void");
- printf (")\n");
+ printf("(void)\n");
printf ("{\n");
+ gen_vararg_prologue(operands);
+
/* Output code to construct and return the rtl for the instruction body. */
if (XVECLEN (insn, 1) == 1)
@@ -457,16 +473,12 @@
operands = max_operand_vec (expand, 1);
/* Output the function name and argument declarations. */
- printf ("rtx\ngen_%s (", XSTR (expand, 0));
+ printf ("rtx\ngen_%s ", XSTR (expand, 0));
if (operands)
- for (i = 0; i < operands; i++)
- if (i)
- printf (",\n\trtx operand%d", i);
- else
- printf ("rtx operand%d", i);
+ printf("(rtx operand0 ATTRIBUTE_UNUSED, ...)\n");
else
- printf ("void");
- printf (")\n");
+ printf("(void)\n");
+
printf ("{\n");
/* If we don't have any C code to write, only one insn is being written,
@@ -476,6 +488,8 @@
&& operands > max_dup_opno
&& XVECLEN (expand, 1) == 1)
{
+ gen_vararg_prologue(operands);
+
printf (" return ");
gen_exp (XVECEXP (expand, 1, 0), DEFINE_EXPAND, NULL);
printf (";\n}\n\n");
@@ -489,6 +503,7 @@
for (; i <= max_scratch_opno; i++)
printf (" rtx operand%d ATTRIBUTE_UNUSED;\n", i);
printf (" rtx _val = 0;\n");
+ gen_vararg_prologue(operands);
printf (" start_sequence ();\n");
/* The fourth operand of DEFINE_EXPAND is some code to be executed
==== //depot/projects/avr32/src/contrib/gcc/genflags.c#2 (text+ko) ====
@@ -128,7 +128,6 @@
gen_proto (rtx insn)
{
int num = num_operands (insn);
- int i;
const char *name = XSTR (insn, 0);
int truth = maybe_eval_c_test (XSTR (insn, 2));
@@ -159,12 +158,7 @@
if (num == 0)
fputs ("void", stdout);
else
- {
- for (i = 1; i < num; i++)
- fputs ("rtx, ", stdout);
-
- fputs ("rtx", stdout);
- }
+ fputs("rtx, ...", stdout);
puts (");");
@@ -174,12 +168,7 @@
{
printf ("static inline rtx\ngen_%s", name);
if (num > 0)
- {
- putchar ('(');
- for (i = 0; i < num-1; i++)
- printf ("rtx ARG_UNUSED (%c), ", 'a' + i);
- printf ("rtx ARG_UNUSED (%c))\n", 'a' + i);
- }
+ puts("(rtx ARG_UNUSED(a), ...)");
else
puts ("(void)");
puts ("{\n return 0;\n}");
==== //depot/projects/avr32/src/contrib/gcc/genoutput.c#2 (text+ko) ====
@@ -387,7 +387,7 @@
}
if (d->name && d->name[0] != '*')
- printf (" (insn_gen_fn) gen_%s,\n", d->name);
+ printf (" gen_%s,\n", d->name);
else
printf (" 0,\n");
==== //depot/projects/avr32/src/contrib/gcc/ifcvt.c#2 (text+ko) ====
@@ -78,7 +78,7 @@
static int num_updated_if_blocks;
/* # of changes made which require life information to be updated. */
-static int num_true_changes;
+int num_true_changes;
/* Whether conditional execution changes were made. */
static int cond_exec_changed_p;
@@ -288,12 +288,15 @@
if (must_be_last)
return FALSE;
- if (modified_in_p (test, insn))
- {
- if (!mod_ok)
- return FALSE;
- must_be_last = TRUE;
- }
+#ifdef IFCVT_ALLOW_MODIFY_TEST_IN_INSN
+ if ( !IFCVT_ALLOW_MODIFY_TEST_IN_INSN )
+#endif
+ if (modified_in_p (test, insn))
+ {
+ if (!mod_ok)
+ return FALSE;
+ must_be_last = TRUE;
+ }
/* Now build the conditional form of the instruction. */
pattern = PATTERN (insn);
@@ -567,16 +570,19 @@
/* Do any machine dependent final modifications. */
IFCVT_MODIFY_FINAL (ce_info);
#endif
-
- /* Conversion succeeded. */
- if (dump_file)
- fprintf (dump_file, "%d insn%s converted to conditional execution.\n",
- n_insns, (n_insns == 1) ? " was" : "s were");
-
+
/* Merge the blocks! */
- merge_if_block (ce_info);
- cond_exec_changed_p = TRUE;
- return TRUE;
+ if ( reload_completed ){
+ /* Conversion succeeded. */
+ if (dump_file)
+ fprintf (dump_file, "%d insn%s converted to conditional execution.\n",
+ n_insns, (n_insns == 1) ? " was" : "s were");
+
+ merge_if_block (ce_info);
+ cond_exec_changed_p = TRUE;
+ return TRUE;
+ }
+ return FALSE;
fail:
#ifdef IFCVT_MODIFY_CANCEL
@@ -1051,7 +1057,11 @@
!= UNKNOWN))
{
rtx cond = if_info->cond;
- enum rtx_code code = reversed_comparison_code (cond, if_info->jump);
+ /* This generates wrong code for AVR32. The cond code need not be reversed
+ since the addmodecc patterns add if the condition is NOT met. */
+ /* enum rtx_code code = reversed_comparison_code (cond, if_info->jump);*/
+ enum rtx_code code = GET_CODE(cond);
+
/* First try to use addcc pattern. */
if (general_operand (XEXP (cond, 0), VOIDmode)
@@ -2652,7 +2662,12 @@
&& cond_move_process_if_block (ce_info))
return TRUE;
- if (HAVE_conditional_execution && reload_completed)
+ if (HAVE_conditional_execution &&
+#ifdef IFCVT_COND_EXEC_BEFORE_RELOAD
+ (reload_completed || IFCVT_COND_EXEC_BEFORE_RELOAD))
+#else
+ reload_completed)
+#endif
{
/* If we have && and || tests, try to first handle combining the && and
|| tests into the conditional code, and if that fails, go back and
@@ -4037,6 +4052,15 @@
cleanup_cfg (CLEANUP_EXPENSIVE
| CLEANUP_UPDATE_LIFE
| (flag_crossjumping ? CLEANUP_CROSSJUMP : 0));
+
+ /* Hack for the AVR32 experimental ifcvt processing before reload.
+ The AVR32 specific ifcvt code needs to know when ifcvt after reload
+ has begun. */
+#ifdef IFCVT_COND_EXEC_BEFORE_RELOAD
+ if ( IFCVT_COND_EXEC_BEFORE_RELOAD )
+ cfun->machine->ifcvt_after_reload = 1;
+#endif
+
if (flag_if_conversion2)
if_convert (1);
return 0;
==== //depot/projects/avr32/src/contrib/gcc/longlong.h#2 (text+ko) ====
@@ -227,6 +227,41 @@
#define UDIV_TIME 100
#endif /* __arm__ */
+#if defined (__avr32__) && W_TYPE_SIZE == 32
+#define add_ssaaaa(sh, sl, ah, al, bh, bl) \
+ __asm__ ("add\t%1, %4, %5\n\tadc\t%0, %2, %3" \
+ : "=r" ((USItype) (sh)), \
+ "=&r" ((USItype) (sl)) \
+ : "r" ((USItype) (ah)), \
+ "r" ((USItype) (bh)), \
+ "r" ((USItype) (al)), \
+ "r" ((USItype) (bl)) __CLOBBER_CC)
+#define sub_ddmmss(sh, sl, ah, al, bh, bl) \
+ __asm__ ("sub\t%1, %4, %5\n\tsbc\t%0, %2, %3" \
+ : "=r" ((USItype) (sh)), \
+ "=&r" ((USItype) (sl)) \
+ : "r" ((USItype) (ah)), \
+ "r" ((USItype) (bh)), \
+ "r" ((USItype) (al)), \
+ "r" ((USItype) (bl)) __CLOBBER_CC)
+
+#if !defined (__AVR32_UC__) || __AVR32_UC__ != 3
+#define __umulsidi3(a,b) ((UDItype)(a) * (UDItype)(b))
+
+#define umul_ppmm(w1, w0, u, v) \
+{ \
+ DWunion __w; \
+ __w.ll = __umulsidi3 (u, v); \
+ w1 = __w.s.high; \
+ w0 = __w.s.low; \
+}
+#endif
+
+#define count_leading_zeros(COUNT,X) ((COUNT) = __builtin_clz (X))
+#define count_trailing_zeros(COUNT,X) ((COUNT) = __builtin_ctz (X))
+#define COUNT_LEADING_ZEROS_0 32
+#endif
+
#if defined (__hppa) && W_TYPE_SIZE == 32
#define add_ssaaaa(sh, sl, ah, al, bh, bl) \
__asm__ ("add %4,%5,%1\n\taddc %2,%3,%0" \
==== //depot/projects/avr32/src/contrib/gcc/optabs.h#2 (text+ko) ====
@@ -432,7 +432,7 @@
extern GTY(()) optab code_to_optab[NUM_RTX_CODE + 1];
-typedef rtx (*rtxfun) (rtx);
+typedef rtx (*rtxfun) (rtx, ...);
/* Indexed by the rtx-code for a conditional (e.g. EQ, LT,...)
gives the gen_function to make a branch to test that condition. */
==== //depot/projects/avr32/src/contrib/gcc/regrename.c#2 (text+ko) ====
@@ -1593,6 +1593,9 @@
bool changed = false;
rtx insn;
+ rtx prev_pred_test;
+ int prev_pred_insn_skipped = 0;
+
for (insn = BB_HEAD (bb); ; insn = NEXT_INSN (insn))
{
int n_ops, i, alt, predicated;
@@ -1631,7 +1634,60 @@
|| (predicated && recog_data.operand_type[i] == OP_OUT))
recog_data.operand_type[i] = OP_INOUT;
}
+
+
+ /* Added for targets (AVR32) which supports test operands to be modified
+ in cond_exec instruction. For these targets we cannot make a change to
+ the test operands if one of the test operands is an output operand This beacuse
+ changing the test operands might cause the need for inserting a new test
+ insns in the middle of a sequence of cond_exec insns and if the test operands
+ are modified these tests will fail.
+ */
+
+ if ( IFCVT_ALLOW_MODIFY_TEST_IN_INSN
+ && predicated )
+ {
+ int insn_skipped = 0;
+ rtx test = COND_EXEC_TEST (PATTERN (insn));
+ /* Check if the previous insn was a skipped predicated insn with the same
+ test as this predicated insns. If so we cannot do any modification to
+ this insn either since we cannot emit the test insn because the operands
+ are clobbered. */
+ if ( prev_pred_insn_skipped
+ && (rtx_equal_p (test, prev_pred_test)
+ || rtx_equal_p (test, reversed_condition (prev_pred_test))) )
+ {
+ insn_skipped = 1;
+ }
+ else
+ {
+ /* Check if the output operand is used in the test expression. */
+ for (i = 0; i < n_ops; ++i)
+ if ( recog_data.operand_type[i] == OP_INOUT
+ && reg_mentioned_p (recog_data.operand[i], test) )
+ {
+ insn_skipped = 1;
+ break;
+ }
+
+ }
+
+ prev_pred_test = test;
+ prev_pred_insn_skipped = insn_skipped;
+ if ( insn_skipped )
+ {
+ if (insn == BB_END (bb))
+ break;
+ else
+ continue;
+ }
+ }
+ else
+ {
+ prev_pred_insn_skipped = 0;
+ }
+
/* For each earlyclobber operand, zap the value data. */
for (i = 0; i < n_ops; i++)
if (recog_op_alt[i][alt].earlyclobber)
==== //depot/projects/avr32/src/contrib/gcc/reload.c#2 (text+ko) ====
@@ -4575,7 +4575,7 @@
x = mem;
i = find_reloads_address (GET_MODE (x), &x, XEXP (x, 0), &XEXP (x, 0),
opnum, type, ind_levels, insn);
- if (x != mem)
+ if (!rtx_equal_p (x, mem))
push_reg_equiv_alt_mem (regno, x);
if (address_reloaded)
*address_reloaded = i;
==== //depot/projects/avr32/src/contrib/gcc/sched-deps.c#2 (text+ko) ====
@@ -650,7 +650,14 @@
prev_nonnote = prev_nonnote_insn (insn);
if (BLOCK_FOR_INSN (insn) == BLOCK_FOR_INSN (prev_nonnote)
- && ! sched_insns_conditions_mutex_p (insn, prev_nonnote))
+ /* Modification for AVR32 by RP: Why is this here, this will
+ cause instruction to be without any dependencies which might
+ cause it to be moved anywhere. For the AVR32 we try to keep
+ a group of conditionals together even if they are mutual exclusive.
+ */
+ && (! sched_insns_conditions_mutex_p (insn, prev_nonnote)
+ || GET_CODE (PATTERN (insn)) == COND_EXEC )
+ )
add_dependence (insn, prev_nonnote, REG_DEP_ANTI);
}
@@ -1124,8 +1131,29 @@
if (code == COND_EXEC)
{
+#ifdef IFCVT_ALLOW_MODIFY_TEST_IN_INSN
+ if (IFCVT_ALLOW_MODIFY_TEST_IN_INSN)
+ {
+ /* Check if we have a group og conditional instructions with the same test.
+ If so we must make sure that they are not scheduled apart in order to
+ avoid unnecesarry tests and if one of the registers in the test is modified
+ in the instruction this is needed to ensure correct code. */
+ if ( prev_nonnote_insn (insn)
+ && INSN_P (prev_nonnote_insn (insn))
+ && GET_CODE (PATTERN (prev_nonnote_insn (insn))) == COND_EXEC
+ && rtx_equal_p (XEXP(COND_EXEC_TEST (PATTERN (prev_nonnote_insn (insn))), 0), XEXP (COND_EXEC_TEST (x), 0))
+ && rtx_equal_p (XEXP(COND_EXEC_TEST (PATTERN (prev_nonnote_insn (insn))), 1), XEXP (COND_EXEC_TEST (x), 1))
+ && ( GET_CODE (COND_EXEC_TEST (PATTERN (prev_nonnote_insn (insn)))) == GET_CODE (COND_EXEC_TEST (x))
+ || GET_CODE (COND_EXEC_TEST (PATTERN (prev_nonnote_insn (insn)))) == reversed_comparison_code (COND_EXEC_TEST (x), insn)))
+ {
+ SCHED_GROUP_P (insn) = 1;
+ //CANT_MOVE (prev_nonnote_insn (insn)) = 1;
+ }
+ }
+#endif
sched_analyze_2 (deps, COND_EXEC_TEST (x), insn);
+
/* ??? Should be recording conditions so we reduce the number of
false dependencies. */
x = COND_EXEC_CODE (x);
More information about the p4-projects
mailing list