aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorrobc <robc@138bc75d-0d04-0410-961f-82ee72b054a4>2006-09-25 17:35:47 +0000
committerrobc <robc@138bc75d-0d04-0410-961f-82ee72b054a4>2006-09-25 17:35:47 +0000
commit5da80c532647e4e140505c0e845fea2923070bfb (patch)
tree45cbec6fecbf6dc0d07d65ecd11c6acb171c311e
parentc9cbd980d80f2d0a48de88b3992e0ba458382763 (diff)
Merge from ST 20060925
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/branches/st/cli@117200 138bc75d-0d04-0410-961f-82ee72b054a4
-rwxr-xr-xcil32-crosstool.sh245
-rw-r--r--gcc/config/cil32/gcc4net.cs14
-rw-r--r--gcc/config/cil32/gen-cil.c435
-rw-r--r--gcc/config/cil32/tree-simp-cil.c342
-rw-r--r--gcc/config/cil32/tree-simp-cil.h4
5 files changed, 659 insertions, 381 deletions
diff --git a/cil32-crosstool.sh b/cil32-crosstool.sh
index 53cf09e75e2..40f587e062c 100755
--- a/cil32-crosstool.sh
+++ b/cil32-crosstool.sh
@@ -1,6 +1,7 @@
#!/bin/sh
+INSTALL_BINUTILS=yes
INSTALL_GCC=yes
TARGET=cil32
@@ -12,81 +13,65 @@ PREFIX=${PREFIX-`pwd`/newbuild}
SYSROOT=${PREFIX}/${TARGET}
LANGUAGES=c
-_help()
-{
- echo "Options:"
- echo " -nogcc : build only binutils (no compiler)"
- echo " -cpp : build also C++ compiler"
- echo " -help : this message"
-}
-
-while [ $# -gt 0 ] ; do
-
-if [ "x$1" == x-help ] ; then
- _help ;
- exit 0
-elif [ "x$1" == x-cpp ] ; then
- LANGUAGES=c,c++
-elif [ "x$1" == x-nogcc ] ; then
- INSTALL_GCC=no
-else
- echo "Unrecognized option: " $1
- _help ;
- exit 1
-fi
-
-shift 1
-done
-
echo "DIRECTORIES:"
echo " BUILD_DIR: " ${BUILD_DIR}
echo " SOURCE_DIR: " ${SOURCE_DIR}
echo " SYSROOT: " ${SYSROOT}
echo " PREFIX: " ${PREFIX}
-
-PATH="${PREFIX}/bin:${PATH}"
-export PATH
+_help()
+{
+ echo "Options:"
+ echo " -binutils : install of binutils (default)"
+ echo " -nobinutils : skip install of binutils"
+ echo " -gcc : gcc build and installation (default)"
+ echo " -nogcc : skip gcc build and installation"
+ echo " -cpp : build also C++ compiler"
+ echo " -help : this message"
+}
# Create directories
-
-mkdir -p ${PREFIX}
-mkdir -p ${PREFIX}/bin
-mkdir -p ${PREFIX}/include
-mkdir -p ${PREFIX}/lib
-# SYSROOT must be = ${PREFIX}/${TARGET}
-mkdir -p ${SYSROOT}
-mkdir -p ${SYSROOT}/bin
-( cd ${SYSROOT} ; ln -fs ../include . )
-( cd ${SYSROOT} ; ln -fs ../lib . )
+_prepare_dirs()
+{
+ mkdir -p ${PREFIX}
+ mkdir -p ${PREFIX}/bin
+ mkdir -p ${PREFIX}/include
+ mkdir -p ${PREFIX}/lib
+ # SYSROOT must be = ${PREFIX}/${TARGET}
+ mkdir -p ${SYSROOT}
+ mkdir -p ${SYSROOT}/bin
+ ( cd ${SYSROOT} ; ln -fs ../include . )
+ ( cd ${SYSROOT} ; ln -fs ../lib . )
+}
# Install Binutils
+_binutils()
+{
+ CIL_AS=${CIL_AS-`which ilasm`}
+ CIL_LD=${CIL_LD-`which ilalink`}
-CIL_AS=${CIL_AS-`which ilasm`}
-CIL_LD=${CIL_LD-`which ilalink`}
-
-echo "Tools:"
-echo " CIL ASSEMBLER: " ${CIL_AS}
-echo " CIL LINKER: " ${CIL_LD}
+ echo "Tools:"
+ echo " CIL ASSEMBLER: " ${CIL_AS}
+ echo " CIL LINKER: " ${CIL_LD}
-echo
-echo "Installing Bin Utils"
+ echo
+ echo "Installing Bin Utils"
-cat > ${SYSROOT}/bin/tool_not_exist <<_EOF_
+ cat > ${SYSROOT}/bin/tool_not_exist <<_EOF_
#!/bin/sh
echo "Tool " \`basename \$0\` " not provided"
exit 1
_EOF_
-chmod 755 ${SYSROOT}/bin/tool_not_exist
+ chmod 755 ${SYSROOT}/bin/tool_not_exist
-cat > ${SYSROOT}/bin/as <<_EOF_
+ cat > ${SYSROOT}/bin/as <<_EOF_
#!/bin/sh
${CIL_AS} "\$@"
_EOF_
-chmod 755 ${SYSROOT}/bin/as
+ chmod 755 ${SYSROOT}/bin/as
-cat > ${SYSROOT}/bin/ld <<_EOF_
+ cat > ${SYSROOT}/bin/ld <<_EOF_
#!/bin/sh
PARAM=
@@ -107,81 +92,119 @@ done
${CIL_LD} \$PARAM
_EOF_
-chmod 755 ${SYSROOT}/bin/ld
-
-cp ${SYSROOT}/bin/tool_not_exist ${SYSROOT}/bin/addr2line
-cp ${SYSROOT}/bin/tool_not_exist ${SYSROOT}/bin/ar
-cp ${SYSROOT}/bin/tool_not_exist ${SYSROOT}/bin/nm
-cp ${SYSROOT}/bin/tool_not_exist ${SYSROOT}/bin/objcopy
-cp ${SYSROOT}/bin/tool_not_exist ${SYSROOT}/bin/objdump
-cp ${SYSROOT}/bin/tool_not_exist ${SYSROOT}/bin/ranlib
-cp ${SYSROOT}/bin/tool_not_exist ${SYSROOT}/bin/readelf
-cp ${SYSROOT}/bin/tool_not_exist ${SYSROOT}/bin/size
-cp ${SYSROOT}/bin/tool_not_exist ${SYSROOT}/bin/strings
-cp ${SYSROOT}/bin/tool_not_exist ${SYSROOT}/bin/strip
-
-
-cp ${SYSROOT}/bin/addr2line ${PREFIX}/bin/${TARGET}-addr2line
-cp ${SYSROOT}/bin/ar ${PREFIX}/bin/${TARGET}-ar
-cp ${SYSROOT}/bin/as ${PREFIX}/bin/${TARGET}-as
-cp ${SYSROOT}/bin/ld ${PREFIX}/bin/${TARGET}-ld
-cp ${SYSROOT}/bin/nm ${PREFIX}/bin/${TARGET}-nm
-cp ${SYSROOT}/bin/objcopy ${PREFIX}/bin/${TARGET}-objcopy
-cp ${SYSROOT}/bin/objdump ${PREFIX}/bin/${TARGET}-objdump
-cp ${SYSROOT}/bin/ranlib ${PREFIX}/bin/${TARGET}-ranlib
-cp ${SYSROOT}/bin/readelf ${PREFIX}/bin/${TARGET}-readelf
-cp ${SYSROOT}/bin/size ${PREFIX}/bin/${TARGET}-size
-cp ${SYSROOT}/bin/strings ${PREFIX}/bin/${TARGET}-strings
-cp ${SYSROOT}/bin/strip ${PREFIX}/bin/${TARGET}-strip
-
-echo
-echo "Installing vm wrappers"
-
-cat > ${PREFIX}/bin/${TARGET}-ilrun <<_EOF_
+ chmod 755 ${SYSROOT}/bin/ld
+
+ cp ${SYSROOT}/bin/tool_not_exist ${SYSROOT}/bin/addr2line
+ cp ${SYSROOT}/bin/tool_not_exist ${SYSROOT}/bin/ar
+ cp ${SYSROOT}/bin/tool_not_exist ${SYSROOT}/bin/nm
+ cp ${SYSROOT}/bin/tool_not_exist ${SYSROOT}/bin/objcopy
+ cp ${SYSROOT}/bin/tool_not_exist ${SYSROOT}/bin/objdump
+ cp ${SYSROOT}/bin/tool_not_exist ${SYSROOT}/bin/ranlib
+ cp ${SYSROOT}/bin/tool_not_exist ${SYSROOT}/bin/readelf
+ cp ${SYSROOT}/bin/tool_not_exist ${SYSROOT}/bin/size
+ cp ${SYSROOT}/bin/tool_not_exist ${SYSROOT}/bin/strings
+ cp ${SYSROOT}/bin/tool_not_exist ${SYSROOT}/bin/strip
+
+
+ cp ${SYSROOT}/bin/addr2line ${PREFIX}/bin/${TARGET}-addr2line
+ cp ${SYSROOT}/bin/ar ${PREFIX}/bin/${TARGET}-ar
+ cp ${SYSROOT}/bin/as ${PREFIX}/bin/${TARGET}-as
+ cp ${SYSROOT}/bin/ld ${PREFIX}/bin/${TARGET}-ld
+ cp ${SYSROOT}/bin/nm ${PREFIX}/bin/${TARGET}-nm
+ cp ${SYSROOT}/bin/objcopy ${PREFIX}/bin/${TARGET}-objcopy
+ cp ${SYSROOT}/bin/objdump ${PREFIX}/bin/${TARGET}-objdump
+ cp ${SYSROOT}/bin/ranlib ${PREFIX}/bin/${TARGET}-ranlib
+ cp ${SYSROOT}/bin/readelf ${PREFIX}/bin/${TARGET}-readelf
+ cp ${SYSROOT}/bin/size ${PREFIX}/bin/${TARGET}-size
+ cp ${SYSROOT}/bin/strings ${PREFIX}/bin/${TARGET}-strings
+ cp ${SYSROOT}/bin/strip ${PREFIX}/bin/${TARGET}-strip
+
+ echo
+ echo "Installing vm wrappers"
+
+ cat > ${PREFIX}/bin/${TARGET}-ilrun <<_EOF_
#!/bin/sh
-ilrun -L ${PREFIX}/lib "\$@"
+basedir=\`dirname \$0\`
+basedir=\`cd \$basedir/.. ; pwd\`
+
+ilrun -L \$basedir/lib "\$@"
_EOF_
-chmod 755 ${PREFIX}/bin/${TARGET}-ilrun
+ chmod 755 ${PREFIX}/bin/${TARGET}-ilrun
-cat > ${PREFIX}/bin/${TARGET}-mono <<_EOF_
+ cat > ${PREFIX}/bin/${TARGET}-mono <<_EOF_
#!/bin/sh
-export MONO_PATH=${PREFIX}/lib
+basedir=\`dirname \$0\`
+basedir=\`cd \$basedir/.. ; pwd\`
-mono "\$@"
+MONO_PATH=\$basedir/lib mono "\$@"
_EOF_
-chmod 755 ${PREFIX}/bin/${TARGET}-mono
+ chmod 755 ${PREFIX}/bin/${TARGET}-mono
+}
-# ... To Be Completed with needed binutil tools
-
-# ... To Be Completed with libraries
+# Configure, build and install gcc
-if test "x${INSTALL_GCC}" == "xno"
-then
+_gcc()
+{
+ echo
+ echo "Configuring GCC"
+
+ mkdir -p ${BUILD_DIR}/build-gcc
+ cd ${BUILD_DIR}/build-gcc
+
+ ${SOURCE_DIR}/configure --target=${TARGET} \
+ --enable-languages=${LANGUAGES} \
+ --disable-bootstrap \
+ --prefix=${PREFIX} \
+ --with-local-prefix=${SYSROOT}
+
+ echo
+ echo "Building GCC"
+ make all
+
+ echo
+ echo "Installing GCC"
+ make install
+}
+
+while [ $# -gt 0 ] ; do
+
+if [ "x$1" == x-help ] ; then
+ _help ;
exit 0
+elif [ "x$1" == x-cpp ] ; then
+ LANGUAGES=c,c++
+elif [ "x$1" == x-nobinutils ] ; then
+ INSTALL_BINUTILS=no
+elif [ "x$1" == x-nogcc ] ; then
+ INSTALL_GCC=no
+elif [ "x$1" == x-binutils ] ; then
+ INSTALL_BINUTILS=yes
+elif [ "x$1" == x-gcc ] ; then
+ INSTALL_GCC=yes
+else
+ echo "Unrecognized option: " $1
+ _help ;
+ exit 1
fi
-# Configure gcc
+shift 1
+done
-echo
-echo "Configuring GCC"
+PATH="${PREFIX}/bin:${PATH}"
+export PATH
-mkdir -p ${BUILD_DIR}/build-gcc
-cd ${BUILD_DIR}/build-gcc
+_prepare_dirs
-${SOURCE_DIR}/configure --target=${TARGET} \
- --enable-languages=${LANGUAGES} \
- --disable-bootstrap \
- --prefix=${PREFIX} \
- --with-local-prefix=${SYSROOT}
+if test "x${INSTALL_BINUTILS}" == "xyes"
+then
+ _binutils
+fi
-# Build and install gcc
-echo
-echo "Building GCC"
-make all
-echo
-echo "Installing GCC"
-make install
+if test "x${INSTALL_GCC}" == "xyes"
+then
+ _gcc
+fi
diff --git a/gcc/config/cil32/gcc4net.cs b/gcc/config/cil32/gcc4net.cs
index fff17f545a9..3321a55b4ff 100644
--- a/gcc/config/cil32/gcc4net.cs
+++ b/gcc/config/cil32/gcc4net.cs
@@ -52,12 +52,10 @@ namespace gcc4net {
}
public unsafe static void Startup() {
- Module mainModule;
Assembly assembly;
Type type;
// Find the module that contains the "main" function.
- mainModule = null;
assembly = Assembly.GetEntryAssembly();
type = assembly.GetType("<Module>");
// Invoke the application's ".init" function, if present.
@@ -90,17 +88,5 @@ namespace gcc4net {
public static long __absti2(long a) { return (a>=0) ? a : -a; }
public static float __abssf2(float a) { return (a>=0) ? a : -a; }
public static double __absdf2(double a) { return (a>=0) ? a : -a; }
-
- unsafe public static void memset(void* dest , byte val, int len) {
- byte* ptr = (byte*)dest;
- while (len-- > 0)
- *ptr++ = val;
- }
- unsafe public static void memcpy (void* dest, void* src, int len) {
- byte* d = (byte*)dest;
- byte* s = (byte*)src;
- while (len-- > 0)
- *d++ = *s++;
- }
}
}
diff --git a/gcc/config/cil32/gen-cil.c b/gcc/config/cil32/gen-cil.c
index 0f74ce6ac88..afe4d918756 100644
--- a/gcc/config/cil32/gen-cil.c
+++ b/gcc/config/cil32/gen-cil.c
@@ -75,7 +75,7 @@ static void dump_label_name (FILE *, tree);
static void dump_fun_type (FILE *, tree, tree, const char *, bool);
static void dump_valuetype_name (FILE *, tree);
static void compute_addr_expr (FILE *, tree);
-static void print_type_suffix (FILE *, tree, tree, bool);
+static void print_type_suffix (FILE *, tree, bool);
static void gen_cil_modify_expr (FILE *, tree);
static char * append_string (char *, const char *,
unsigned int *, unsigned int *);
@@ -93,6 +93,7 @@ static void stack_set (unsigned int) ATTRIBUTE_UNUSED;
static void stack_reset (void);
static void stack_push (unsigned int);
static void stack_pop (unsigned int);
+static void gen_integral_conv (FILE *, tree, tree);
static void gen_start_function (FILE *);
static unsigned int gen_cil (void);
static void gen_cil_1 (FILE *);
@@ -136,6 +137,8 @@ mark_var_defs_uses (tree node)
case CALL_EXPR:
{
tree args = TREE_OPERAND (node, 1);
+ tree fun_expr;
+ tree dfun = NULL_TREE;
mark_var_defs_uses (TREE_OPERAND (node, 0));
@@ -144,6 +147,33 @@ mark_var_defs_uses (tree node)
mark_var_defs_uses (TREE_VALUE (args));
args = TREE_CHAIN (args);
}
+
+ fun_expr = TREE_OPERAND (node, 0);
+ if (TREE_CODE (fun_expr) == ADDR_EXPR
+ && TREE_CODE (TREE_OPERAND (fun_expr, 0)) == FUNCTION_DECL)
+ dfun = TREE_OPERAND (fun_expr, 0);
+
+ /* Calls to some built-in functions require ad-hoc simplifications */
+ if (dfun && DECL_BUILT_IN (dfun))
+ {
+ switch (DECL_FUNCTION_CODE (dfun))
+ {
+ case BUILT_IN_VA_COPY:
+ {
+ tree va_dest = TREE_VALUE (TREE_OPERAND (node, 1));
+
+ gcc_assert (TREE_CODE (va_dest) == ADDR_EXPR);
+ gcc_assert (TREE_CODE (TREE_OPERAND (va_dest, 0)) == VAR_DECL
+ && !DECL_FILE_SCOPE_P (TREE_OPERAND (va_dest, 0)));
+
+ TREE_SIDE_EFFECTS (TREE_OPERAND (va_dest, 0)) = true;
+ }
+ break;
+
+ default:
+ ;
+ }
+ }
}
break;
@@ -200,6 +230,10 @@ mark_var_defs_uses (tree node)
mark_var_defs_uses (lhs);
mark_var_defs_uses (rhs);
+
+ if (AGGREGATE_TYPE_P (TREE_TYPE (lhs)) && TREE_CODE (rhs) == VAR_DECL)
+ TREE_SIDE_EFFECTS (rhs) = true;
+
gcc_assert (TREE_CODE (rhs) != CONSTRUCTOR
&& TREE_CODE (rhs) != STRING_CST);
}
@@ -212,16 +246,33 @@ mark_var_defs_uses (tree node)
case NOP_EXPR:
case FLOAT_EXPR:
case FIX_TRUNC_EXPR:
- case INDIRECT_REF:
- case BIT_FIELD_REF:
- case ADDR_EXPR:
- case COMPONENT_REF:
case ABS_EXPR:
case RETURN_EXPR:
case WITH_SIZE_EXPR:
mark_var_defs_uses (TREE_OPERAND (node, 0));
break;
+ case ADDR_EXPR:
+ case COMPONENT_REF:
+ {
+ tree op = TREE_OPERAND (node, 0);
+
+ mark_var_defs_uses (op);
+ if (AGGREGATE_TYPE_P (TREE_TYPE (op)) && TREE_CODE (op) == VAR_DECL)
+ TREE_SIDE_EFFECTS (op) = true;
+ }
+ break;
+
+ case INDIRECT_REF:
+ {
+ tree op = TREE_OPERAND (node, 0);
+
+ mark_var_defs_uses (op);
+ if (AGGREGATE_TYPE_P (TREE_TYPE (node)) && TREE_CODE (op) == VAR_DECL)
+ TREE_SIDE_EFFECTS (op) = true;
+ }
+ break;
+
case INTEGER_CST:
case REAL_CST:
case STRING_CST:
@@ -342,8 +393,7 @@ remove_stloc_ldloc (block_stmt_iterator bsi, tree *node_ptr, bool *mod)
case INIT_EXPR:
case MODIFY_EXPR:
- if (! AGGREGATE_TYPE_P (TREE_TYPE (TREE_OPERAND (node, 0))))
- remove_stloc_ldloc (bsi, &TREE_OPERAND (node, 1), mod);
+ remove_stloc_ldloc (bsi, &TREE_OPERAND (node, 1), mod);
gcc_assert (TREE_CODE (TREE_OPERAND (node, 1)) != CONSTRUCTOR
&& TREE_CODE (TREE_OPERAND (node, 1)) != STRING_CST);
break;
@@ -355,28 +405,23 @@ remove_stloc_ldloc (block_stmt_iterator bsi, tree *node_ptr, bool *mod)
case NOP_EXPR:
case FLOAT_EXPR:
case FIX_TRUNC_EXPR:
- case BIT_FIELD_REF:
+ case ADDR_EXPR:
+ case COMPONENT_REF:
+ case INDIRECT_REF:
case ABS_EXPR:
case RETURN_EXPR:
case WITH_SIZE_EXPR:
remove_stloc_ldloc (bsi, &TREE_OPERAND (node, 0), mod);
break;
- case ADDR_EXPR:
- case COMPONENT_REF:
- if (! AGGREGATE_TYPE_P (TREE_TYPE (TREE_OPERAND (node, 0))))
- remove_stloc_ldloc (bsi, &TREE_OPERAND (node, 0), mod);
- break;
-
- case INDIRECT_REF:
- if (! AGGREGATE_TYPE_P (TREE_TYPE (node)))
- remove_stloc_ldloc (bsi, &TREE_OPERAND (node, 0), mod);
- break;
-
case VAR_DECL:
+ /* In GIMPLE, TREE_SIDE_EFFECTS is true for a VAR_DECL only if the
+ variable is volatile.
+ However, mark_var_defs_uses (...) function sets TREE_SIDE_EFFECTS
+ for some non-volatile variables that shouldn't be removed. */
if (! TREE_ADDRESSABLE (node)
&& ! TREE_STATIC (node)
- && ! TREE_THIS_VOLATILE (node)
+ && ! TREE_SIDE_EFFECTS (node)
&& ! DECL_FILE_SCOPE_P (node))
{
tree prev_stmt;
@@ -812,10 +857,11 @@ dump_type (FILE *file, tree node, bool ref)
{
/* node = TYPE_MAIN_VARIANT (node); */
- if (TYPE_MAIN_VARIANT (node) == va_list_type_node) {
+ if (TYPE_MAIN_VARIANT (node) == va_list_type_node)
+ {
fputs ("valuetype [mscorlib]System.ArgIterator", file);
return;
- }
+ }
switch (TREE_CODE (node))
{
@@ -861,7 +907,7 @@ dump_type (FILE *file, tree node, bool ref)
case REAL_TYPE:
{
- int type_size = GET_MODE_BITSIZE (TYPE_MODE (node));
+ int type_size = TYPE_PRECISION (node);
switch (type_size)
{
@@ -898,7 +944,7 @@ dump_type (FILE *file, tree node, bool ref)
case VECTOR_TYPE:
{
- int type_size = GET_MODE_BITSIZE (TYPE_MODE (node));
+ int type_size = TREE_INT_CST_LOW (TYPE_SIZE (node));
tree innertype = TREE_TYPE (node);
enum machine_mode innermode = TYPE_MODE (innertype);
@@ -1099,6 +1145,7 @@ dump_type_for_builtin (FILE *file, tree node, bool all_types)
{
case ENUMERAL_TYPE:
case INTEGER_TYPE:
+ case BOOLEAN_TYPE:
{
int type_size = GET_MODE_BITSIZE (TYPE_MODE (node));
@@ -1120,7 +1167,7 @@ dump_type_for_builtin (FILE *file, tree node, bool all_types)
case REAL_TYPE:
{
- int type_size = GET_MODE_BITSIZE (TYPE_MODE (node));
+ int type_size = TYPE_PRECISION (node);
switch (type_size)
{
@@ -1147,6 +1194,7 @@ dump_type_eval_mode (FILE *stream, tree node, bool all_types)
{
case ENUMERAL_TYPE:
case INTEGER_TYPE:
+ case BOOLEAN_TYPE:
{
int type_size = GET_MODE_BITSIZE (TYPE_MODE (node));
@@ -1254,23 +1302,6 @@ compute_addr_expr (FILE *file, tree t)
}
break;
- case BIT_FIELD_REF:
- {
- tree obj = TREE_OPERAND (t, 0);
- unsigned int off = TREE_INT_CST_LOW (TREE_OPERAND (t, 2));
-
- gcc_assert (off % 8 == 0);
- compute_addr_expr (file, obj);
- if (off / 8 > 0)
- {
- fprintf (file, "\n\tldc.i4\t%d", off / 8);
- fputs ("\n\tadd", file);
- stack_push (1);
- stack_pop (1);
- }
- }
- break;
-
default:
fprintf (stderr, "%s: %s\n",
__func__, tree_code_name[TREE_CODE (t)]);
@@ -1282,22 +1313,15 @@ compute_addr_expr (FILE *file, tree t)
}
static void
-print_type_suffix (FILE *file, tree type_node, tree conv_in_type, bool unsign)
+print_type_suffix (FILE *file, tree type_node, bool unsign)
{
- int type_size = GET_MODE_BITSIZE (TYPE_MODE (type_node));
-
switch (TREE_CODE (type_node))
{
case ENUMERAL_TYPE:
case INTEGER_TYPE:
{
- bool uns = false;
-
- if (TYPE_UNSIGNED (type_node)
- || (conv_in_type != NULL_TREE
- && TYPE_UNSIGNED (conv_in_type)
- && type_size > GET_MODE_BITSIZE (TYPE_MODE (conv_in_type))))
- uns = unsign;
+ int type_size = TYPE_PRECISION (type_node);
+ bool uns = unsign && TYPE_UNSIGNED (type_node);
switch (type_size)
{
@@ -1313,16 +1337,24 @@ print_type_suffix (FILE *file, tree type_node, tree conv_in_type, bool unsign)
}
break;
+ case BOOLEAN_TYPE:
+ fputs ((unsign && TYPE_UNSIGNED (type_node))?"u1":"i1", file);
+ break;
+
case REAL_TYPE:
- switch (type_size)
- {
- case 32: fputs ("r4", file); break;
- case 64: fputs ("r8", file); break;
- default:
- fprintf (stderr, "Unsupported floating point size %d\n", type_size);
- gcc_assert (0);
- break;
- }
+ {
+ int type_size = TYPE_PRECISION (type_node);
+
+ switch (type_size)
+ {
+ case 32: fputs ("r4", file); break;
+ case 64: fputs ("r8", file); break;
+ default:
+ fprintf (stderr, "Unsupported floating point size %d\n", type_size);
+ gcc_assert (0);
+ break;
+ }
+ }
break;
case POINTER_TYPE:
@@ -1331,17 +1363,14 @@ print_type_suffix (FILE *file, tree type_node, tree conv_in_type, bool unsign)
case VECTOR_TYPE:
{
- bool uns = false;
+ int type_size = TREE_INT_CST_LOW (TYPE_SIZE (type_node));
+ bool uns = TYPE_UNSIGNED (type_node) && unsign;
tree innertype = TREE_TYPE (type_node);
enum machine_mode innermode = TYPE_MODE (innertype);
/* Only expect integer vectors */
gcc_assert (GET_MODE_CLASS (innermode) == MODE_INT);
- /* and then emit as corresponding same-size interger mode */
- if (TYPE_UNSIGNED (type_node) && unsign)
- uns = true;
-
switch (type_size)
{
case 8: fputs ((uns)?"u1":"i1", file); break;
@@ -1364,6 +1393,79 @@ print_type_suffix (FILE *file, tree type_node, tree conv_in_type, bool unsign)
}
}
+/* Emit a conversion from integral or pointer type IN_TYPE
+ to integral type OUT_TYPE to file FILE.
+ If the precision of OUT_TYPE is bigger than that of IN_TYPE,
+ then IN_TYPE and OUT_TYPE have to have the same signedness. */
+
+static void
+gen_integral_conv (FILE *file, tree out_type, tree in_type)
+{
+ unsigned int out_bits, cont_size, in_bits;
+
+ gcc_assert (INTEGRAL_TYPE_P (out_type));
+ gcc_assert (INTEGRAL_TYPE_P (in_type) || TREE_CODE (in_type) == POINTER_TYPE);
+ gcc_assert (TYPE_PRECISION (out_type) <= 64);
+ gcc_assert (TYPE_PRECISION (out_type) <= TYPE_PRECISION (in_type)
+ || TYPE_UNSIGNED (out_type) == TYPE_UNSIGNED (in_type));
+
+ /* Get the precision of the output and input types and the size
+ of the output type container */
+ in_bits = TYPE_PRECISION (in_type);
+ out_bits = TYPE_PRECISION (out_type);
+ cont_size = GET_MODE_BITSIZE (TYPE_MODE (out_type));
+ gcc_assert (cont_size >= out_bits);
+
+ /* Dump a conv with for the container size, if not superfluous */
+ if ((cont_size == out_bits && (out_bits != in_bits || out_bits < 32))
+ || ((out_bits > 32) ^ (in_bits > 32)))
+ {
+ fputs ("\n\tconv.", file);
+ print_type_suffix (file, get_integer_type (cont_size,
+ TYPE_UNSIGNED (out_type)),
+ true);
+ }
+
+ /* If the container is bigger than the output type precision,
+ force the output to be of the desired precision. */
+ if (cont_size > out_bits)
+ {
+ if (TYPE_UNSIGNED (out_type))
+ {
+ unsigned HOST_WIDEST_INT mask;
+ double_int mask_di;
+
+ /* Compute the mask to be applied to the existing value */
+ gcc_assert (HOST_BITS_PER_WIDEST_INT >= 64);
+ mask = (1LL << out_bits) - 1LL;
+ mask_di.low = mask;
+ mask_di.high = (HOST_WIDE_INT)(mask >> HOST_BITS_PER_WIDE_INT);
+
+ /* Apply the mask */
+ if (out_bits <= 32)
+ fputs ("\n\tldc.i4\t", file);
+ else
+ fputs ("\n\tldc.i8\t", file);
+ dump_double_int (file, mask_di, false);
+ fputs ("\n\tand", file);
+ }
+ else
+ {
+ unsigned int cont_size = (out_bits > 32) ? 64 : 32;
+ unsigned int shift = cont_size - out_bits;
+
+ /* Do a pair of shift to perform the sign extension */
+ fprintf (file, "\n\tldc.i4\t%d", shift);
+ fputs ("\n\tshl\t", file);
+ fprintf (file, "\n\tldc.i4\t%d", shift);
+ fputs ("\n\tshr\t", file);
+ }
+
+ stack_push (1);
+ stack_pop (1);
+ }
+}
+
/* Dump the node NODE in CIL on the file FILE. */
static void
gen_cil_node (FILE *file, tree node)
@@ -1386,26 +1488,18 @@ gen_cil_node (FILE *file, tree node)
{
case INTEGER_CST:
{
- int type_size = GET_MODE_BITSIZE (TYPE_MODE (TREE_TYPE (node)));
+ int type_size = TYPE_PRECISION (TREE_TYPE (node));
- switch (type_size)
- {
- case 8:
- case 16:
- case 32:
- fprintf (file, "\n\tldc.i4\t%ld", TREE_INT_CST_LOW (node));
- break;
-
- case 64:
- fprintf (file, "\n\tldc.i8\t%ld", TREE_INT_CST_LOW (node));
- break;
+ gcc_assert (type_size <= 64);
+ if (type_size <= 32)
+ fputs ("\n\tldc.i4\t", file);
+ else
+ fputs ("\n\tldc.i8\t", file);
+ dump_double_int (file, TREE_INT_CST (node), false);
- default:
- internal_error ("\nldc: unsupported int size %d\n", type_size);
- break;
- }
if (TREE_CODE (TREE_TYPE (node)) == POINTER_TYPE)
fputs ("\n\tconv.i", file);
+
stack_push (1);
}
break;
@@ -1425,7 +1519,7 @@ gen_cil_node (FILE *file, tree node)
mode = TYPE_MODE (type_tree);
real_to_target (buf, &d, mode);
real_to_decimal (string, &d, sizeof (string), 5, 1);
- type_size = GET_MODE_BITSIZE (TYPE_MODE (type_tree));
+ type_size = TYPE_PRECISION (type_tree);
switch (type_size)
{
@@ -1449,14 +1543,17 @@ gen_cil_node (FILE *file, tree node)
case VECTOR_CST:
{
tree elt;
- unsigned int val = 0;
+ unsigned HOST_WIDEST_INT val = 0;
+ double_int val_di;
tree vector_type = TREE_TYPE (node);
- int vector_bitsize = GET_MODE_BITSIZE (TYPE_MODE (vector_type));
+ int vector_bitsize = TREE_INT_CST_LOW (TYPE_SIZE (vector_type));
tree unit_type = TREE_TYPE (vector_type);
- int unit_bitsize = GET_MODE_BITSIZE (TYPE_MODE (unit_type));
+ int unit_bitsize = TYPE_PRECISION (unit_type);
+
+ gcc_assert (HOST_BITS_PER_WIDEST_INT >= 64);
- /* At this time, support only 32 bit vectors */
- if (vector_bitsize != 32)
+ /* At this time, support up to 64-bit vectors */
+ if (vector_bitsize > 64)
internal_error ("\nVECTOR_CST size %d\n", vector_bitsize);
for (elt = TREE_VECTOR_CST_ELTS (node); elt; elt = TREE_CHAIN (elt))
@@ -1465,6 +1562,7 @@ gen_cil_node (FILE *file, tree node)
switch (TREE_CODE (elt_val))
{
case INTEGER_CST:
+ gcc_assert (TREE_INT_CST_HIGH (elt_val) == 0);
val = (val << unit_bitsize) | TREE_INT_CST_LOW (elt_val);
break;
@@ -1474,7 +1572,15 @@ gen_cil_node (FILE *file, tree node)
}
}
- fprintf (file, "\n\tldc.i4\t%#0x", val);
+ val_di.low = val;
+ val_di.high = (HOST_WIDE_INT)(val >> HOST_BITS_PER_WIDE_INT);
+
+ if (vector_bitsize <= 32)
+ fputs ("\n\tldc.i4\t", file);
+ else
+ fputs ("\n\tldc.i8\t", file);
+ dump_double_int (file, val_di, false);
+
stack_push (1);
break;
}
@@ -2012,7 +2118,6 @@ gen_cil_node (FILE *file, tree node)
case MINUS_EXPR:
case RDIV_EXPR:
case LSHIFT_EXPR:
- case BIT_XOR_EXPR:
op0 = TREE_OPERAND (node, 0);
op1 = TREE_OPERAND (node, 1);
@@ -2026,25 +2131,21 @@ gen_cil_node (FILE *file, tree node)
case MINUS_EXPR: fputs ("\n\tsub", file); break;
case RDIV_EXPR: fputs ("\n\tdiv", file); break;
case LSHIFT_EXPR: fputs ("\n\tshl", file); break;
- case BIT_XOR_EXPR: fputs ("\n\txor", file); break;
default:
gcc_unreachable ();
}
- /* Values smaller than 32-bits are represented as 32-bit
- on the evaluation stack, therefore an explicit conversion
- is required. */
- if (TREE_INT_CST_LOW (TYPE_SIZE (TREE_TYPE (node))) < 32)
- {
- fputs ("\n\tconv.", file);
- print_type_suffix (file, TREE_TYPE (node), NULL_TREE, true);
- }
-
stack_pop (1);
+
+ /* Values with precision smaller than the one used
+ on the evaluation stack require an explicit conversion. */
+ if (INTEGRAL_TYPE_P (TREE_TYPE (node)))
+ gen_integral_conv (file, TREE_TYPE (node), TREE_TYPE (node));
break;
case BIT_IOR_EXPR:
case BIT_AND_EXPR:
+ case BIT_XOR_EXPR:
op0 = TREE_OPERAND (node, 0);
op1 = TREE_OPERAND (node, 1);
@@ -2055,12 +2156,14 @@ gen_cil_node (FILE *file, tree node)
{
case BIT_IOR_EXPR: fputs ("\n\tor", file); break;
case BIT_AND_EXPR: fputs ("\n\tand", file); break;
+ case BIT_XOR_EXPR: fputs ("\n\txor", file); break;
default:
gcc_unreachable ();
}
- /* No need for conversions even in case of values smaller
- than 32-bits, since for these operations the output is
+ /* No need for conversions even in case of values with precision
+ smaller than the one used on the evaluation stack,
+ since for these operations the output is
always less or equal than both operands. */
stack_pop (1);
@@ -2095,7 +2198,7 @@ gen_cil_node (FILE *file, tree node)
gcc_unreachable ();
}
- if (TREE_INT_CST_LOW (TYPE_SIZE (TREE_TYPE (node))) == 64)
+ if (TYPE_PRECISION (TREE_TYPE (node)) > 32)
fputs ("\n\tconv.i8", file);
stack_pop (1);
@@ -2127,7 +2230,7 @@ gen_cil_node (FILE *file, tree node)
fputs ("\n\tldc.i4.1"
"\n\txor", file);
- if (TREE_INT_CST_LOW (TYPE_SIZE (TREE_TYPE (node))) == 64)
+ if (TYPE_PRECISION (TREE_TYPE (node)) > 32)
fputs ("\n\tconv.i8", file);
stack_pop (1);
@@ -2156,8 +2259,9 @@ gen_cil_node (FILE *file, tree node)
if (TYPE_UNSIGNED (TREE_TYPE (node)))
fputs (".un", file);
- /* No need for conversions even in case of values smaller
- than 32-bits, since for these operations the output is
+ /* No need for conversions even in case of values with precision
+ smaller than the one used on the evaluation stack,
+ since for these operations the output is
always less or equal than both operands. */
stack_pop (1);
@@ -2190,8 +2294,9 @@ gen_cil_node (FILE *file, tree node)
fputs (")", file);
}
- /* No need for conversions even in case of values smaller
- than 32-bits, since for this operation the output is
+ /* No need for conversions even in case of values with precision
+ smaller than the one used on the evaluation stack,
+ since for these operations the output is
always less or equal than both operands. */
stack_pop (1);
@@ -2210,49 +2315,63 @@ gen_cil_node (FILE *file, tree node)
gcc_unreachable ();
}
- /* Values smaller than 32-bits are represented as 32-bit
- on the evaluation stack, therefore an explicit conversion
- is required.
+ /* Values with precision smaller than the one used
+ on the evaluation stack require an explicit conversion.
Unfortunately this is true for the negation as well just
for the case in which the operand is the smallest negative value.
Example: 8-bit negation of -128 gives 0 and not 128. */
- if (TREE_INT_CST_LOW (TYPE_SIZE (TREE_TYPE (node))) < 32)
- {
- fputs ("\n\tconv.", file);
- print_type_suffix (file, TREE_TYPE (node), NULL_TREE, true);
- }
-
+ if (INTEGRAL_TYPE_P (TREE_TYPE (node)))
+ gen_integral_conv (file, TREE_TYPE (node), TREE_TYPE (node));
break;
case INDIRECT_REF:
- case BIT_FIELD_REF:
compute_addr_expr (file, node);
- fputs ("\n\tldind.", file);
- print_type_suffix (file, TREE_TYPE (node), NULL_TREE, true);
+ if (AGGREGATE_TYPE_P (TREE_TYPE (node)))
+ {
+ fputs ("\n\tldobj\t", file);
+ dump_type (file, TREE_TYPE (node), true);
+ }
+ else
+ {
+ fputs ("\n\tldind.", file);
+ print_type_suffix (file, TREE_TYPE (node), true);
+ }
break;
case CONVERT_EXPR:
+ case FLOAT_EXPR:
/* ER: if flag_trapv is set, we could generate the .ovf version? */
/* TODO: */
- gen_cil_node (file, TREE_OPERAND (node, 0));
- fputs ("\n\tconv.", file);
- print_type_suffix (file, TREE_TYPE (node), TREE_TYPE (TREE_OPERAND (node, 0)), true);
- break;
-
+ case FIX_TRUNC_EXPR:
case NOP_EXPR:
{
- enum tree_code out_type_code = TREE_CODE (TREE_TYPE (node));
+ tree op = TREE_OPERAND (node, 0);
+ tree in_type = TREE_TYPE (op);
+ tree out_type = TREE_TYPE (node);
- gen_cil_node (file, TREE_OPERAND (node, 0));
+ gen_cil_node (file, op);
- if (out_type_code == INTEGER_TYPE
- || out_type_code == ENUMERAL_TYPE
- || out_type_code == REAL_TYPE
- || out_type_code == POINTER_TYPE)
+ if (TREE_CODE (node) == NOP_EXPR && INTEGRAL_TYPE_P (out_type))
+ {
+ gcc_assert (INTEGRAL_TYPE_P (in_type)
+ || TREE_CODE (in_type) == POINTER_TYPE);
+
+ if (TYPE_PRECISION (out_type) > TYPE_PRECISION (in_type))
+ {
+ tree tmp_type = TYPE_UNSIGNED (in_type)
+ ? unsigned_type_for (out_type)
+ : signed_type_for (out_type);
+
+ gen_integral_conv (file, tmp_type, in_type);
+ gen_integral_conv (file, out_type, tmp_type);
+ }
+ else
+ gen_integral_conv (file, out_type, in_type);
+ }
+ else
{
fputs ("\n\tconv.", file);
- print_type_suffix (file, TREE_TYPE (node),
- TREE_TYPE (TREE_OPERAND (node, 0)), true);
+ print_type_suffix (file, out_type, true);
}
}
break;
@@ -2434,13 +2553,6 @@ gen_cil_node (FILE *file, tree node)
}
break;
- case FLOAT_EXPR:
- case FIX_TRUNC_EXPR:
- gen_cil_node (file, TREE_OPERAND (node, 0));
- fputs ("\n\tconv.", file);
- print_type_suffix (file, TREE_TYPE (node), NULL_TREE, true);
- break;
-
case TRUTH_NOT_EXPR:
gen_cil_node (file, TREE_OPERAND (node, 0));
fputs ("\n\tldc.i4.0"
@@ -2456,6 +2568,8 @@ gen_cil_node (FILE *file, tree node)
op1 = TREE_OPERAND (node, 1);
gen_cil_node (file, op0);
+ gcc_assert (TREE_CODE (TREE_TYPE (op0)) == INTEGER_TYPE
+ || TREE_CODE (TREE_TYPE (op0)) == BOOLEAN_TYPE);
if (TREE_CODE (TREE_TYPE (op0)) == INTEGER_TYPE)
{
fputs ("\n\tldc.i4.0"
@@ -2467,6 +2581,8 @@ gen_cil_node (FILE *file, tree node)
}
gen_cil_node (file, op1);
+ gcc_assert (TREE_CODE (TREE_TYPE (op1)) == INTEGER_TYPE
+ || TREE_CODE (TREE_TYPE (op1)) == BOOLEAN_TYPE);
if (TREE_CODE (TREE_TYPE (op1)) == INTEGER_TYPE)
{
fputs ("\n\tldc.i4.0"
@@ -2518,20 +2634,6 @@ gen_cil_modify_expr (FILE *file, tree node)
tree lhs = TREE_OPERAND (node, 0);
tree rhs = TREE_OPERAND (node, 1);
- if (AGGREGATE_TYPE_P (TREE_TYPE (rhs))
- && (TREE_CODE (lhs) == INDIRECT_REF || TREE_CODE (rhs) == INDIRECT_REF))
- {
- gcc_assert (AGGREGATE_TYPE_P (TREE_TYPE (lhs)));
- compute_addr_expr (file, lhs);
- compute_addr_expr (file, rhs);
- fprintf (file, "\n\tldc.i4\t%lu",
- TREE_INT_CST_LOW (TYPE_SIZE_UNIT (TREE_TYPE (rhs))));
- fputs ("\n\tcall\tvoid [gcc4net]gcc4net.Crt::memcpy(void*, void*, int32)",file);
- stack_push (1);
- stack_pop (3);
- return;
- }
-
switch (TREE_CODE (lhs))
{
case SSA_NAME:
@@ -2541,8 +2643,19 @@ gen_cil_modify_expr (FILE *file, tree node)
case INDIRECT_REF:
compute_addr_expr (file, lhs);
gen_cil_node (file, rhs);
- fputs ("\n\tstind.", file);
- print_type_suffix (file, TREE_TYPE (lhs), NULL_TREE, false);
+
+ if (AGGREGATE_TYPE_P (TREE_TYPE (lhs)))
+ {
+ gcc_assert (AGGREGATE_TYPE_P (TREE_TYPE (rhs)));
+ fputs ("\n\tstobj\t", file);
+ dump_type (file, TREE_TYPE (lhs), true);
+ }
+ else
+ {
+ fputs ("\n\tstind.", file);
+ print_type_suffix (file, TREE_TYPE (lhs), false);
+ }
+
stack_pop (2);
break;
@@ -2642,7 +2755,7 @@ append_coded_type (char *str, tree type,
{
case INTEGER_TYPE:
{
- int type_size = GET_MODE_BITSIZE (TYPE_MODE (type));
+ int type_size = TYPE_PRECISION (type);
char tmp_str[8] = "UI";
char *tmp_str_ptr = tmp_str;
@@ -2655,9 +2768,13 @@ append_coded_type (char *str, tree type,
}
break;
+ case BOOLEAN_TYPE:
+ str = append_string (str, "B", len, max_len);
+ break;
+
case REAL_TYPE:
{
- int type_size = GET_MODE_BITSIZE (TYPE_MODE (type));
+ int type_size = TYPE_PRECISION (type);
char tmp_str[4] = "F";
snprintf (tmp_str + 1, 3, "%d", type_size);
@@ -2887,7 +3004,7 @@ print_valuetype_decl (FILE *file, tree t)
if (is_enum)
{
- int type_size = GET_MODE_BITSIZE (TYPE_MODE (t));
+ int type_size = TYPE_PRECISION (t);
char tmp_str[8] = "int";
char *base_type_str = tmp_str;
tree tmp;
diff --git a/gcc/config/cil32/tree-simp-cil.c b/gcc/config/cil32/tree-simp-cil.c
index 8e43c2fbee9..d8f8aa26994 100644
--- a/gcc/config/cil32/tree-simp-cil.c
+++ b/gcc/config/cil32/tree-simp-cil.c
@@ -90,6 +90,12 @@ Roberto Costa <roberto.costa@st.com> */
assignment also requires a load from memory; from the memory
access point of view, the operation cannot be made atomic.
+ *) Expansion of BIT_FIELD_REF nodes.
+ CIL has no direct support for bit-field access; hence,
+ equivalent code that extracts the bit pattern and applies the
+ appropriate bit mask is generated.
+ Memory access is performed by using INDIRECT_REF nodes.
+
*) Expansion of TARGET_MEM_REF nodes.
Emission of such nodes is not difficult in gen_cil pass;
however, a previous expansion may trigger further optimizations
@@ -126,6 +132,15 @@ Roberto Costa <roberto.costa@st.com> */
The reason is that CIL shift operations require a shift operand
of type int32.
+ *) Forcing arguments of CALL_EXPRs to be local variables, only for
+ specific built-in functions.
+ A few built-in functions require special simplifications
+ in order to make their emission easier; in particular:
+ *) the 1st argument of BUILT_IN_VA_COPY has to be a local variable
+ (the emitted CIL uses a 'stloc' to store its value).
+ To force arguments of calls to be local variables, new local
+ variables are generated.
+
*) Rename of inlined variables to unique names.
Emitted variables by gen_cil pass keep the original name.
In case of variables declared within inlined functions,
@@ -144,52 +159,67 @@ Roberto Costa <roberto.costa@st.com> */
*/
/* Local functions, macros and variables. */
-static tree get_unsigned_integer_type (int);
static bool is_copy_required (tree);
static bool mostly_zeros_p (tree);
static bool all_zeros_p (tree);
static void simp_switch (block_stmt_iterator *, tree *);
static void simp_trivial_switch (block_stmt_iterator *, tree *);
+static void simp_builtin_call (block_stmt_iterator, tree);
static void simp_abs (block_stmt_iterator *, tree *);
static void simp_min_max (block_stmt_iterator *, tree *);
static void simp_rotate (block_stmt_iterator *, tree *);
static void simp_shift (block_stmt_iterator *, tree);
static void simp_target_mem_ref (block_stmt_iterator *, tree *);
static void simp_array_ref (block_stmt_iterator *, tree *);
+static void simp_bitfield (block_stmt_iterator *, tree *, tree, unsigned int,
+ unsigned int, unsigned int, HOST_WIDEST_INT, bool);
static void simp_rhs_bitfield_component_ref (block_stmt_iterator *, tree *);
static void simp_lhs_bitfield_component_ref (block_stmt_iterator *, tree *);
+static void simp_bitfield_ref (block_stmt_iterator *, tree *);
static void pre_simp_init (block_stmt_iterator *, tree);
static void simp_cil_node (block_stmt_iterator *, tree *);
-static void split_use (block_stmt_iterator, tree *);
-static void rename_var (tree, const char*);
+static void split_use (block_stmt_iterator, tree *, bool);
+static void rename_var (tree, const char*, unsigned long);
static void simp_vars (void);
static unsigned int simp_cil (void);
static bool simp_cil_gate (void);
static tree res_var;
-static tree uint32_type;
-/* Return the unsigned integer type with size BITS bits */
+/* Return the integer type with size BITS bits.
+ The type is unsigned or signed depending on UNS. */
-static tree
-get_unsigned_integer_type (int bits)
+tree
+get_integer_type (int bits, bool uns)
{
- if (GET_MODE_BITSIZE (TYPE_MODE (unsigned_type_node)) == bits)
- return unsigned_type_node;
- else if (GET_MODE_BITSIZE (TYPE_MODE (long_unsigned_type_node)) == bits)
- return long_unsigned_type_node;
- else if (GET_MODE_BITSIZE (TYPE_MODE (short_unsigned_type_node)) == bits)
- return short_unsigned_type_node;
- else if (GET_MODE_BITSIZE (TYPE_MODE (long_long_unsigned_type_node))
- == bits)
- return long_long_unsigned_type_node;
- else if (GET_MODE_BITSIZE (TYPE_MODE (unsigned_char_type_node)) == bits)
- return unsigned_char_type_node;
- else
- {
- gcc_assert (0);
- return NULL_TREE;
- }
+ if (uns)
+ {
+ switch (bits)
+ {
+ case 8: return unsigned_intQI_type_node;
+ case 16: return unsigned_intHI_type_node;
+ case 32: return unsigned_intSI_type_node;
+ case 64: return unsigned_intDI_type_node;
+ case 128: return unsigned_intTI_type_node;
+ default:
+ gcc_assert (0);
+ return NULL_TREE;
+ }
+ }
+ else
+ {
+ switch (bits)
+ {
+ case 8: return intQI_type_node;
+ case 16: return intHI_type_node;
+ case 32: return intSI_type_node;
+ case 64: return intDI_type_node;
+ case 128: return intTI_type_node;
+ default:
+ gcc_assert (0);
+ return NULL_TREE;
+ }
+ }
}
/* In the case of multiple uses of tree NODE, return whether
@@ -247,6 +277,8 @@ simp_cil_node (block_stmt_iterator *bsi, tree *node_ptr)
case CALL_EXPR:
{
tree args = TREE_OPERAND (node, 1);
+ tree fun_expr;
+ tree dfun = NULL_TREE;
simp_cil_node (bsi, &TREE_OPERAND (node, 0));
@@ -255,6 +287,15 @@ simp_cil_node (block_stmt_iterator *bsi, tree *node_ptr)
simp_cil_node (bsi, &TREE_VALUE (args));
args = TREE_CHAIN (args);
}
+
+ fun_expr = TREE_OPERAND (node, 0);
+ if (TREE_CODE (fun_expr) == ADDR_EXPR
+ && TREE_CODE (TREE_OPERAND (fun_expr, 0)) == FUNCTION_DECL)
+ dfun = TREE_OPERAND (fun_expr, 0);
+
+ /* Calls to some built-in functions require ad-hoc simplifications */
+ if (dfun && DECL_BUILT_IN (dfun))
+ simp_builtin_call (*bsi, node);
}
break;
@@ -306,7 +347,7 @@ simp_cil_node (block_stmt_iterator *bsi, tree *node_ptr)
if (AGGREGATE_TYPE_P (TREE_TYPE (TREE_OPERAND (node, 1)))
&& TREE_CODE (TREE_OPERAND (node, 0)) == INDIRECT_REF
&& TREE_CODE (TREE_OPERAND (node, 1)) == CALL_EXPR)
- split_use (*bsi, &TREE_OPERAND (node, 1));
+ split_use (*bsi, &TREE_OPERAND (node, 1), false);
break;
case NEGATE_EXPR:
@@ -316,7 +357,6 @@ simp_cil_node (block_stmt_iterator *bsi, tree *node_ptr)
case NOP_EXPR:
case FLOAT_EXPR:
case FIX_TRUNC_EXPR:
- case BIT_FIELD_REF:
simp_cil_node (bsi, &TREE_OPERAND (node, 0));
break;
@@ -324,14 +364,14 @@ simp_cil_node (block_stmt_iterator *bsi, tree *node_ptr)
simp_cil_node (bsi, &TREE_OPERAND (node, 0));
if (AGGREGATE_TYPE_P (TREE_TYPE (TREE_OPERAND (node, 0)))
&& TREE_CODE (TREE_OPERAND (node, 0)) == CALL_EXPR)
- split_use (*bsi, &TREE_OPERAND (node, 0));
+ split_use (*bsi, &TREE_OPERAND (node, 0), false);
break;
case INDIRECT_REF:
simp_cil_node (bsi, &TREE_OPERAND (node, 0));
if (AGGREGATE_TYPE_P (TREE_TYPE (node))
&& TREE_CODE (TREE_OPERAND (node, 0)) == CALL_EXPR)
- split_use (*bsi, &TREE_OPERAND (node, 0));
+ split_use (*bsi, &TREE_OPERAND (node, 0), false);
break;
case COMPONENT_REF:
@@ -339,7 +379,7 @@ simp_cil_node (block_stmt_iterator *bsi, tree *node_ptr)
simp_cil_node (bsi, &TREE_OPERAND (node, 0));
if (AGGREGATE_TYPE_P (TREE_TYPE (TREE_OPERAND (node, 0)))
&& TREE_CODE (TREE_OPERAND (node, 0)) == CALL_EXPR)
- split_use (*bsi, &TREE_OPERAND (node, 0));
+ split_use (*bsi, &TREE_OPERAND (node, 0), false);
if (DECL_BIT_FIELD (TREE_OPERAND (node, 1)))
{
tree stmt = bsi_stmt (*bsi);
@@ -352,6 +392,16 @@ simp_cil_node (block_stmt_iterator *bsi, tree *node_ptr)
}
break;
+ case BIT_FIELD_REF:
+ simp_cil_node (bsi, &TREE_OPERAND (node, 0));
+ if (AGGREGATE_TYPE_P (TREE_TYPE (TREE_OPERAND (node, 0)))
+ && TREE_CODE (TREE_OPERAND (node, 0)) == CALL_EXPR)
+ split_use (*bsi, &TREE_OPERAND (node, 0), false);
+ gcc_assert (TREE_CODE (bsi_stmt (*bsi)) != MODIFY_EXPR
+ || TREE_OPERAND (bsi_stmt (*bsi), 0) != node);
+ simp_bitfield_ref (bsi, node_ptr);
+ break;
+
case TARGET_MEM_REF:
simp_cil_node (bsi, &TMR_SYMBOL (node));
simp_cil_node (bsi, &TMR_BASE (node));
@@ -361,7 +411,7 @@ simp_cil_node (block_stmt_iterator *bsi, tree *node_ptr)
gcc_assert (TREE_CODE (node) == INDIRECT_REF);
if (AGGREGATE_TYPE_P (TREE_TYPE (node))
&& TREE_CODE (TREE_OPERAND (node, 0)) == CALL_EXPR)
- split_use (*bsi, &TREE_OPERAND (node, 0));
+ split_use (*bsi, &TREE_OPERAND (node, 0), false);
break;
case ARRAY_REF:
@@ -372,7 +422,7 @@ simp_cil_node (block_stmt_iterator *bsi, tree *node_ptr)
gcc_assert (TREE_CODE (node) == INDIRECT_REF);
if (AGGREGATE_TYPE_P (TREE_TYPE (node))
&& TREE_CODE (TREE_OPERAND (node, 0)) == CALL_EXPR)
- split_use (*bsi, &TREE_OPERAND (node, 0));
+ split_use (*bsi, &TREE_OPERAND (node, 0), false);
break;
case RETURN_EXPR:
@@ -862,6 +912,40 @@ simp_trivial_switch (block_stmt_iterator *bsi, tree *node_ptr)
}
}
+/* Force specific arguments of the CALL_EXPR to a built-in function
+ pointed by NODE to be local variables.
+ Which arguments are forced depend on the built-in function.
+ BSI is the iterator of the statement that contains NODE
+ (in order to allow insertion of new statements). */
+
+static void
+simp_builtin_call (block_stmt_iterator bsi, tree node)
+{
+ tree fun_expr = TREE_OPERAND (node, 0);
+
+ gcc_assert (TREE_CODE (node) == CALL_EXPR);
+ gcc_assert (TREE_CODE (fun_expr) == ADDR_EXPR);
+ gcc_assert (TREE_CODE (TREE_OPERAND (fun_expr, 0)) == FUNCTION_DECL);
+ gcc_assert (DECL_BUILT_IN (TREE_OPERAND (fun_expr, 0)));
+
+ switch (DECL_FUNCTION_CODE (TREE_OPERAND (fun_expr, 0)))
+ {
+ case BUILT_IN_VA_COPY:
+ {
+ tree va_dest = TREE_VALUE (TREE_OPERAND (node, 1));
+
+ gcc_assert (TREE_CODE (va_dest) == ADDR_EXPR);
+ if (TREE_CODE (TREE_OPERAND (va_dest, 0)) != VAR_DECL
+ || DECL_FILE_SCOPE_P (TREE_OPERAND (va_dest, 0)))
+ split_use (bsi, &TREE_OPERAND (va_dest, 0), true);
+ }
+ break;
+
+ default:
+ ;
+ }
+}
+
/* Remove the ABS_EXPR pointed by NODE_PTR by inserting
explicit control flow.
BSI points to the iterator of the statement that contains *NODE_PTR
@@ -1077,7 +1161,7 @@ simp_rotate (block_stmt_iterator *bsi, tree *node_ptr)
op0 = fold_convert (op0_uns_type, op0);
/* Convert the second operand to 32-bit */
- op1 = fold_convert (uint32_type, TREE_OPERAND (node, 1));
+ op1 = fold_convert (unsigned_intSI_type_node, TREE_OPERAND (node, 1));
/* Make sure that the two operands have no side effects */
if (is_copy_required (op0))
@@ -1109,8 +1193,8 @@ simp_rotate (block_stmt_iterator *bsi, tree *node_ptr)
/* Build second shift */
t2 = fold_build2 (left ? RSHIFT_EXPR : LSHIFT_EXPR, op0_uns_type,
op0,
- build2 (MINUS_EXPR, uint32_type,
- fold_convert (uint32_type,
+ build2 (MINUS_EXPR, unsigned_intSI_type_node,
+ fold_convert (unsigned_intSI_type_node,
TYPE_SIZE (TREE_TYPE (op0))),
op1));
@@ -1143,7 +1227,7 @@ simp_shift (block_stmt_iterator *bsi, tree node)
|| TREE_CODE (node) == RSHIFT_EXPR);
/* Generate the type conversion */
- t = fold_convert (uint32_type, TREE_OPERAND (node, 1));
+ t = fold_convert (unsigned_intSI_type_node, TREE_OPERAND (node, 1));
/* Gimplify the equivalent expression and update the current node */
TREE_OPERAND (node, 1) = force_gimple_operand_bsi (bsi, t, FALSE, NULL);
@@ -1312,46 +1396,40 @@ simp_array_ref (block_stmt_iterator *bsi, tree *node_ptr)
*node_ptr = build1 (INDIRECT_REF, TREE_TYPE (node), t1);
}
-/* Expand the COMPONENT_REF (pointed by NODE_PTR) accessing
- a BIT_FIELD_DECL and being on a right-hand side by transforming it
+/* Expand a bit-field reference by transforming it
into an INDIRECT_REF and applying the necessary bit mask operations.
BSI points to the iterator of the statement that contains *NODE_PTR
(in order to allow insertion of new statements).
BSI is passed by reference because instructions are inserted.
NODE is passed by reference because simplification requires
- replacing the node. */
+ replacing the node.
+ OBJ is the object containing the bit-field.
+ CONT_SIZE is the number of bits of the bit-field container.
+ BFLD_SIZE is the number of bits being referenced.
+ BFLD_OFF is the position of the first referenced bit.
+ OFF is an additional offset in bytes of the bit-field from the
+ beginning of the OBJ.
+ UNS tells whether the bit-field is unsigned or not. */
static void
-simp_rhs_bitfield_component_ref (block_stmt_iterator *bsi, tree *node_ptr)
+simp_bitfield (block_stmt_iterator *bsi, tree *node_ptr,
+ tree obj, unsigned int cont_size, unsigned int bfld_size,
+ unsigned int bfld_off, HOST_WIDEST_INT off, bool uns)
{
tree node = *node_ptr;
location_t locus = EXPR_LOCATION (bsi_stmt (*bsi));
- tree obj = TREE_OPERAND (node, 0);
- tree fld = TREE_OPERAND (node, 1);
- tree fld_type, fld_off ;
- unsigned int cont_size, bfld_size, bfld_off;
tree new_type, obj_ptr_type;
tree tmp_var, tmp_stmt;
tree t;
- HOST_WIDEST_INT off;
-
- gcc_assert (TREE_CODE (node) == COMPONENT_REF);
- gcc_assert (DECL_BIT_FIELD (fld));
- /* Extract bit field layout */
- fld_type = DECL_BIT_FIELD_TYPE (fld);
- fld_off = DECL_FIELD_OFFSET (fld);
- cont_size = TREE_INT_CST_LOW (TYPE_SIZE (fld_type));
- bfld_size = TYPE_PRECISION (TREE_TYPE (fld));
- bfld_off = TREE_INT_CST_LOW (DECL_FIELD_BIT_OFFSET (fld)) & (cont_size - 1);
- gcc_assert (cont_size >= TREE_INT_CST_LOW (TYPE_SIZE (TREE_TYPE (node))));
+ gcc_assert (cont_size >= bfld_size + bfld_off);
/* Build the type corresponding of a pointer to the object */
obj_ptr_type = build0 (POINTER_TYPE, TREE_TYPE (obj));
layout_type (obj_ptr_type);
/* Build the new type for the equivalent access */
- new_type = get_unsigned_integer_type (cont_size);
+ new_type = get_integer_type (cont_size, uns);
/* Build the (gimplified) equivalent expression */
@@ -1364,13 +1442,6 @@ simp_rhs_bitfield_component_ref (block_stmt_iterator *bsi, tree *node_ptr)
t = tmp_var;
bsi_insert_before (bsi, tmp_stmt, BSI_SAME_STMT);
- off = TREE_INT_CST_LOW (fld_off)
- + ((TREE_INT_CST_LOW (DECL_FIELD_BIT_OFFSET (fld))
- & ~(cont_size - 1))
- / 8);
-
- gcc_assert (TREE_INT_CST_HIGH (fld_off) == 0);
-
if (off > 0)
{
tmp_var = create_tmp_var (obj_ptr_type, "cilsimp");
@@ -1399,7 +1470,7 @@ simp_rhs_bitfield_component_ref (block_stmt_iterator *bsi, tree *node_ptr)
tmp_var,
build2 (LSHIFT_EXPR, new_type,
t,
- build_int_cstu (uint32_type,
+ build_int_cstu (unsigned_intSI_type_node,
cont_size
- bfld_size - bfld_off)));
SET_EXPR_LOCATION (tmp_stmt, locus);
@@ -1414,7 +1485,7 @@ simp_rhs_bitfield_component_ref (block_stmt_iterator *bsi, tree *node_ptr)
tmp_var,
build2 (RSHIFT_EXPR, new_type,
t,
- build_int_cstu (uint32_type,
+ build_int_cstu (unsigned_intSI_type_node,
cont_size - bfld_size)));
SET_EXPR_LOCATION (tmp_stmt, locus);
t = tmp_var;
@@ -1428,6 +1499,46 @@ simp_rhs_bitfield_component_ref (block_stmt_iterator *bsi, tree *node_ptr)
}
/* Expand the COMPONENT_REF (pointed by NODE_PTR) accessing
+ a BIT_FIELD_DECL and being on a right-hand side by transforming it
+ into an INDIRECT_REF and applying the necessary bit mask operations.
+ BSI points to the iterator of the statement that contains *NODE_PTR
+ (in order to allow insertion of new statements).
+ BSI is passed by reference because instructions are inserted.
+ NODE is passed by reference because simplification requires
+ replacing the node. */
+
+static void
+simp_rhs_bitfield_component_ref (block_stmt_iterator *bsi, tree *node_ptr)
+{
+ tree node = *node_ptr;
+ tree obj = TREE_OPERAND (node, 0);
+ tree fld = TREE_OPERAND (node, 1);
+ tree fld_type, fld_off;
+ unsigned int cont_size, bfld_size, bfld_off;
+ HOST_WIDEST_INT off;
+
+ gcc_assert (TREE_CODE (node) == COMPONENT_REF);
+ gcc_assert (DECL_BIT_FIELD (fld));
+
+ /* Extract bit field layout */
+ fld_type = DECL_BIT_FIELD_TYPE (fld);
+ fld_off = DECL_FIELD_OFFSET (fld);
+ cont_size = TREE_INT_CST_LOW (TYPE_SIZE (fld_type));
+ bfld_size = TYPE_PRECISION (TREE_TYPE (fld));
+ bfld_off = TREE_INT_CST_LOW (DECL_FIELD_BIT_OFFSET (fld)) & (cont_size - 1);
+ gcc_assert (cont_size >= TREE_INT_CST_LOW (TYPE_SIZE (TREE_TYPE (node))));
+ gcc_assert (TREE_INT_CST_HIGH (fld_off) == 0);
+ off = TREE_INT_CST_LOW (fld_off)
+ + ((TREE_INT_CST_LOW (DECL_FIELD_BIT_OFFSET (fld))
+ & ~(cont_size - 1))
+ / 8);
+
+ /* Simplify the bit-field */
+ simp_bitfield (bsi, node_ptr, obj, cont_size, bfld_size, bfld_off, off,
+ DECL_UNSIGNED (fld));
+}
+
+/* Expand the COMPONENT_REF (pointed by NODE_PTR) accessing
a BIT_FIELD_DECL and being on a left-hand side by transforming it
into an INDIRECT_REF and applying the necessary bit mask operations.
BSI points to the iterator of the statement that contains *NODE_PTR
@@ -1466,7 +1577,7 @@ simp_lhs_bitfield_component_ref (block_stmt_iterator *bsi, tree *node_ptr)
gcc_assert (cont_size >= TREE_INT_CST_LOW (TYPE_SIZE (TREE_TYPE (node))));
/* Build the new type for the equivalent access */
- new_type = get_unsigned_integer_type (cont_size);
+ new_type = get_integer_type (cont_size, true);
/* Build the type corresponding of a pointer to the object */
obj_ptr_type = build0 (POINTER_TYPE, TREE_TYPE (obj));
@@ -1490,7 +1601,7 @@ simp_lhs_bitfield_component_ref (block_stmt_iterator *bsi, tree *node_ptr)
tmp_var,
build2 (LSHIFT_EXPR, new_type,
rhs,
- build_int_cstu (uint32_type,
+ build_int_cstu (unsigned_intSI_type_node,
cont_size - bfld_size)));
SET_EXPR_LOCATION (tmp_stmt, locus);
rhs = tmp_var;
@@ -1506,7 +1617,7 @@ simp_lhs_bitfield_component_ref (block_stmt_iterator *bsi, tree *node_ptr)
tmp_var,
build2 (RSHIFT_EXPR, new_type,
rhs,
- build_int_cstu (uint32_type,
+ build_int_cstu (unsigned_intSI_type_node,
cont_size
- bfld_size - bfld_off)));
SET_EXPR_LOCATION (tmp_stmt, locus);
@@ -1556,9 +1667,9 @@ simp_lhs_bitfield_component_ref (block_stmt_iterator *bsi, tree *node_ptr)
/* Compute the mask to be applied to the existing value */
gcc_assert (HOST_BITS_PER_WIDEST_INT >= 64);
- mask |= (1 << (cont_size - bfld_size - bfld_off)) - 1;
+ mask |= (1LL << (cont_size - bfld_size - bfld_off)) - 1LL;
mask <<= bfld_off + bfld_size;
- mask |= (1 << bfld_off) - 1;
+ mask |= (1LL << bfld_off) - 1;
/* Apply the mask to the existing value */
tmp_var = create_tmp_var (new_type, "cilsimp");
@@ -1566,7 +1677,9 @@ simp_lhs_bitfield_component_ref (block_stmt_iterator *bsi, tree *node_ptr)
tmp_var,
build2 (BIT_AND_EXPR, new_type,
t,
- build_int_cstu (new_type, mask)));
+ build_int_cst_wide (new_type,
+ mask,
+ mask >> HOST_BITS_PER_WIDE_INT)));
SET_EXPR_LOCATION (tmp_stmt, locus);
t = tmp_var;
bsi_insert_before (bsi, tmp_stmt, BSI_SAME_STMT);
@@ -1587,6 +1700,51 @@ simp_lhs_bitfield_component_ref (block_stmt_iterator *bsi, tree *node_ptr)
TREE_OPERAND (stmt, 1) = rhs;
}
+/* Expand the BIT_FIELD_REF (pointed by NODE_PTR) by transforming it
+ into an INDIRECT_REF and applying the necessary bit mask operations.
+ BSI points to the iterator of the statement that contains *NODE_PTR
+ (in order to allow insertion of new statements).
+ BSI is passed by reference because instructions are inserted.
+ NODE is passed by reference because simplification requires
+ replacing the node. */
+
+static void
+simp_bitfield_ref (block_stmt_iterator *bsi, tree *node_ptr)
+{
+ tree node = *node_ptr;
+ tree obj = TREE_OPERAND (node, 0);
+ unsigned int ref_bfld_off, cont_size, bfld_size, bfld_off;
+ HOST_WIDE_INT off;
+
+ gcc_assert (TREE_CODE (node) == BIT_FIELD_REF);
+
+ /* Extract bit field layout */
+ bfld_size = TREE_INT_CST_LOW (TREE_OPERAND (node, 1));
+ ref_bfld_off = TREE_INT_CST_LOW (TREE_OPERAND (node, 2));
+ gcc_assert (bfld_size <= 64);
+
+ /* At least, cont_size is the next power of two of the bit-field size */
+ cont_size = bfld_size - 1;
+ cont_size |= (cont_size >> 1);
+ cont_size |= (cont_size >> 2);
+ cont_size |= (cont_size >> 4);
+ ++cont_size;
+ gcc_assert (cont_size == 8 || cont_size == 16
+ || cont_size == 32 || cont_size == 64);
+
+ /* Widen the container until an aligned access is enough */
+ while ((ref_bfld_off & ~(cont_size - 1))
+ != ((ref_bfld_off + bfld_size - 1) & ~(cont_size - 1)))
+ cont_size <<= 1;
+
+ bfld_off = ref_bfld_off & (cont_size - 1);
+ off = (ref_bfld_off - bfld_off) >> 3;
+
+ /* Simplify the bit-field */
+ simp_bitfield (bsi, node_ptr, obj, cont_size, bfld_size, bfld_off, off,
+ BIT_FIELD_REF_UNSIGNED (node));
+}
+
/* Expand the INIT_EXPR (or MODIFY_EXPR) in NODE having
a CONSTRUCTOR or STRING_CST on the right side into a sequence
of simpler (here, it means "not involving CONSTRUCTOR or
@@ -1655,21 +1813,23 @@ pre_simp_init (block_stmt_iterator *bsi, tree node)
*bsi = tmp_bsi;
}
-/* Make sure that the tree pointed by NODE_PTR is a VAR_DECL.
+/* Make sure that the tree pointed by NODE_PTR is a VAR_DECL;
+ if LOCAL is true, then the VAR_DECL must be a local variable.
In case, split the statement containing NODE_PTR into two
by creating a new local variable.
BSI points to the iterator of the statement that contains NODE_PTR
(in order to allow insertion of new statements). */
static void
-split_use (block_stmt_iterator bsi, tree *node_ptr)
+split_use (block_stmt_iterator bsi, tree *node_ptr, bool local)
{
tree node = *node_ptr;
location_t locus = EXPR_LOCATION (bsi_stmt (bsi));
tree type = TREE_TYPE (node);
tree var, stmt;
- if (TREE_CODE (node) == VAR_DECL)
+ if (TREE_CODE (node) == VAR_DECL
+ && (!local || !DECL_FILE_SCOPE_P (node)))
return;
/* Split the current statement by creating a new local variable */
@@ -1963,24 +2123,11 @@ expand_init_to_stmt_list (tree decl, tree init, tree *stmt_list, bool cleared)
elements. */
FOR_EACH_CONSTRUCTOR_ELT (CONSTRUCTOR_ELTS (init), i, index, value)
{
- enum machine_mode mode;
- HOST_WIDE_INT bitsize;
- int unsignedp;
tree t;
if (initializer_zerop (value))
continue;
- unsignedp = TYPE_UNSIGNED (elttype);
- mode = TYPE_MODE (elttype);
-
- if (mode == BLKmode)
- bitsize = (host_integerp (TYPE_SIZE (elttype), 1)
- ? tree_low_cst (TYPE_SIZE (elttype), 1)
- : -1);
- else
- bitsize = GET_MODE_BITSIZE (mode);
-
gcc_assert (index == NULL_TREE
|| TREE_CODE (index) != RANGE_EXPR);
@@ -2020,7 +2167,7 @@ expand_init_to_stmt_list (tree decl, tree init, tree *stmt_list, bool cleared)
/* Rename a single variable using the specified suffix */
static void
-rename_var (tree var, const char* suffix)
+rename_var (tree var, const char* suffix, unsigned long index)
{
const char *orig_name = IDENTIFIER_POINTER (DECL_NAME (var));
char *newsym = alloca (strlen (orig_name) + strlen (suffix) + 10 + 1);
@@ -2029,7 +2176,7 @@ rename_var (tree var, const char* suffix)
"%s%s%lu",
orig_name,
suffix,
- (unsigned long)var));
+ index));
}
/* Simplify variables: rename inlined variables
@@ -2041,20 +2188,28 @@ simp_vars (void)
{
block_stmt_iterator bsi = bsi_start (ENTRY_BLOCK_PTR);
tree *p = &cfun->unexpanded_var_list;
+ unsigned long num_loc = 0;
- for (; *p; )
+ for (; *p; p = &TREE_CHAIN (*p))
{
tree var = TREE_VALUE (*p);
tree init = DECL_INITIAL (var);
if (TREE_STATIC (var) && DECL_CONTEXT (var) != 0)
{
- rename_var (var, "?fs");
+ rename_var (var, "?fs", (unsigned long)var);
DECL_CONTEXT (var) = 0;
}
- if (DECL_FROM_INLINE (var) && DECL_NAME (var) != NULL)
- rename_var (var, "?in");
+ if (DECL_NAME (var) != NULL && ! TREE_STATIC (var))
+ {
+ if (DECL_FROM_INLINE (var))
+ rename_var (var, "?in", num_loc);
+ else
+ rename_var (var, "?", num_loc);
+
+ ++num_loc;
+ }
if (!TREE_STATIC (var) && init && init != error_mark_node)
{
@@ -2063,8 +2218,6 @@ simp_vars (void)
build2 (INIT_EXPR, TREE_TYPE (var), var, init),
BSI_NEW_STMT);
}
-
- p = &TREE_CHAIN (*p);
}
}
@@ -2077,7 +2230,6 @@ simp_cil (void)
block_stmt_iterator bsi;
res_var = NULL_TREE;
- uint32_type = get_unsigned_integer_type (32);
simp_vars ();
@@ -2103,7 +2255,7 @@ simp_cil (void)
pre_simp_init (&bsi, stmt);
else if (TREE_CODE (lhs) == COMPONENT_REF
&& DECL_BIT_FIELD (TREE_OPERAND (lhs, 1)))
- split_use (bsi, &TREE_OPERAND (stmt, 1));
+ split_use (bsi, &TREE_OPERAND (stmt, 1), false);
}
}
}
diff --git a/gcc/config/cil32/tree-simp-cil.h b/gcc/config/cil32/tree-simp-cil.h
index 51f0970a707..6f4ea4fc502 100644
--- a/gcc/config/cil32/tree-simp-cil.h
+++ b/gcc/config/cil32/tree-simp-cil.h
@@ -33,7 +33,7 @@ Roberto Costa <roberto.costa@st.com> */
#include "tree.h"
-void
-expand_init_to_stmt_list (tree, tree, tree *, bool);
+extern void expand_init_to_stmt_list (tree, tree, tree *, bool);
+extern tree get_integer_type (int, bool);
#endif /* TREE_SIMP_CIL_H */