aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrea Ornstein <andrea.ornstein@st.com>2009-02-18 13:14:25 +0000
committerAndrea Ornstein <andrea.ornstein@st.com>2009-02-18 13:14:25 +0000
commit55696a394999c0e6d9df66e1de694e493bc18355 (patch)
treec4610e8115f95381f647248a31acc8480a1ff92c
parent9c2921a9653dbb5afe44e60c5997c7434a380ef2 (diff)
New Snapshot from STMicroelectronics 2009-02-18 (rev 1349)st/cli
Changes from Gabriele Svelto and Andrea C. Ornstein - Added support for pointers in min/max builtins - Implemented address generation of imaginary numbers parts. - Reworked the code used for splitting switches. When splitting a switch with more than 8192 cases the default case label was set incorrectly causing an ICE during CFG creation, fixed. - Define shift instructions in the .md file, fixes a problem when the loop optimizer tries to calculate an instruction cost. - Fixed a bug which caused the cil_name attribute to be ignored during CIL emission. - Remove more redundant conversions. - Fixed a bug which caused an ICE when a NEGATE_EXPR had a pointer argument. - Optimized bit-field initializers when endianness is selected. git-svn-id: https://gcc.gnu.org/svn/gcc/branches/st/cli@144262 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--gcc/config/cil32/cil-refs.c166
-rw-r--r--gcc/config/cil32/cil-refs.h1
-rw-r--r--gcc/config/cil32/cil-stmt-inline.h28
-rw-r--r--gcc/config/cil32/cil-stmt.c35
-rw-r--r--gcc/config/cil32/cil-stmt.h4
-rw-r--r--gcc/config/cil32/cil32.md24
-rw-r--r--gcc/config/cil32/emit-cil.c12
-rw-r--r--gcc/config/cil32/gimple-to-cil.c56
-rw-r--r--gcc/config/cil32/remove-convs.c7
-rw-r--r--gcc/config/cil32/t-cil3239
-rw-r--r--gcc/config/cil32/tree-simp-cil-early.c94
11 files changed, 309 insertions, 157 deletions
diff --git a/gcc/config/cil32/cil-refs.c b/gcc/config/cil32/cil-refs.c
index 42461a6bd34..bdd35dd6783 100644
--- a/gcc/config/cil32/cil-refs.c
+++ b/gcc/config/cil32/cil-refs.c
@@ -71,7 +71,7 @@ static int fill_label_addrs (void **, void *);
static bool mostly_zeros_p (tree);
static bool all_zeros_p (tree);
static void expand_init_to_stmt_list1 (tree, tree, tree *, bool, tree *,
- void *, void *);
+ void *, void *, unsigned HOST_WIDE_INT);
static int statement_list_num_instr (tree);
/******************************************************************************
@@ -741,6 +741,23 @@ cil_pointer_type_p (tree type)
return false;
}
+/* Return an integer type of SIZE bits, unsigned if UNSIGNEDP is set, signed
+ otherwise. */
+
+tree
+get_integer_type (unsigned int size, bool unsignedp)
+{
+ switch (size)
+ {
+ case 8: return unsignedp ? unsigned_intQI_type_node : intQI_type_node;
+ case 16: return unsignedp ? unsigned_intHI_type_node : intHI_type_node;
+ case 32: return unsignedp ? unsigned_intSI_type_node : intSI_type_node;
+ case 64: return unsignedp ? unsigned_intDI_type_node : intDI_type_node;
+ default:
+ gcc_unreachable ();
+ }
+}
+
/******************************************************************************
* Strings *
******************************************************************************/
@@ -1107,7 +1124,8 @@ all_zeros_p (tree exp)
static void
expand_init_to_stmt_list1 (tree decl, tree init,
tree *stmt_list1, bool cleared,
- tree *stmt_list2, void *le_image, void *be_image)
+ tree *stmt_list2, void *le_image, void *be_image,
+ unsigned HOST_WIDE_INT image_offset)
{
tree decl_size = TYPE_SIZE_UNIT (TREE_TYPE (decl));
unsigned HOST_WIDE_INT size = tree_low_cst (decl_size, 1);
@@ -1160,10 +1178,10 @@ expand_init_to_stmt_list1 (tree decl, tree init,
append_to_statement_list (t, stmt_list1);
- memcpy(le_image, TREE_STRING_POINTER (init),
- tree_low_cst (decl_size, 1));
- memcpy(be_image, TREE_STRING_POINTER (init),
- tree_low_cst (decl_size, 1));
+ memcpy((unsigned char *) le_image + image_offset,
+ TREE_STRING_POINTER (init), tree_low_cst (decl_size, 1));
+ memcpy((unsigned char *) be_image + image_offset,
+ TREE_STRING_POINTER (init), tree_low_cst (decl_size, 1));
}
break;
@@ -1235,24 +1253,108 @@ expand_init_to_stmt_list1 (tree decl, tree init,
ltarget = build3 (COMPONENT_REF, TREE_TYPE (field), decl, field, NULL);
- if (le_image != NULL && !DECL_BIT_FIELD(field))
+ if (le_image != NULL && !DECL_BIT_FIELD (field))
{
- unsigned HOST_WIDE_INT offset = tree_low_cst (DECL_FIELD_OFFSET(field), 1);
- unsigned HOST_WIDE_INT bit_offset = tree_low_cst (DECL_FIELD_BIT_OFFSET(field), 1);
+ unsigned HOST_WIDE_INT offset = tree_low_cst (DECL_FIELD_OFFSET (field), 1);
+ unsigned HOST_WIDE_INT bit_offset = tree_low_cst (DECL_FIELD_BIT_OFFSET (field), 1);
gcc_assert (bit_offset % BITS_PER_UNIT == 0);
- offset += bit_offset / BITS_PER_UNIT;
+ offset += (bit_offset / BITS_PER_UNIT) + image_offset;
expand_init_to_stmt_list1 (ltarget, value,
stmt_list1, cleared,
stmt_list2,
- (void *) ((intptr_t) le_image + offset),
- (void *) ((intptr_t) be_image + offset));
+ le_image, be_image, offset);
+ }
+ else if (le_image != NULL && DECL_BIT_FIELD (field)
+ && (TARGET_LITTLE_ENDIAN || TARGET_BIG_ENDIAN))
+ {
+ unsigned char b0, b1, b2, b3;
+ unsigned HOST_WIDE_INT offset = 0;
+ HOST_WIDE_INT bit_size = 0;
+ HOST_WIDE_INT bit_pos = 0;
+ HOST_WIDE_INT cont_off;
+ HOST_WIDE_INT cont_size = 8;
+ enum machine_mode mode;
+ int unsignedp = 0;
+ int volatilep = 0;
+ tree cont_type;
+ tree shift_cst;
+ tree tmp;
+
+ get_inner_reference (ltarget, &bit_size, &bit_pos,
+ &tmp, &mode, &unsignedp,
+ &volatilep, false);
+
+ /* Calculate the container size. */
+ while ((bit_pos % cont_size + bit_size) > cont_size)
+ cont_size *= 2;
+
+ if (cont_size > 32)
+ {
+ expand_init_to_stmt_list1 (ltarget, value,
+ stmt_list1, cleared,
+ stmt_list2, NULL, NULL, 0);
+ }
+ else
+ {
+ cont_type = get_integer_type (cont_size, true);
+ cont_off = bit_pos % cont_size;
+
+ /* Calculate the container offset. */
+ if ((bit_pos - cont_off) / BITS_PER_UNIT != 0)
+ {
+ tmp = build_int_cst (intSI_type_node,
+ (bit_pos - cont_off)
+ / BITS_PER_UNIT);
+ offset = tree_low_cst (tmp, 1);
+ }
+
+ shift_cst = build_int_cst (intSI_type_node, cont_off);
+ tmp = fold_binary_to_constant (LSHIFT_EXPR, cont_type,
+ fold_convert (cont_type,
+ value),
+ shift_cst);
+
+ b0 = tree_low_cst (tmp, 1);
+ b1 = tree_low_cst (tmp, 1) >> 8;
+ b2 = tree_low_cst (tmp, 1) >> 16;
+ b3 = tree_low_cst (tmp, 1) >> 24;
+
+ switch (cont_size)
+ {
+ case 8:
+ *((unsigned char *) le_image + offset) |= b0;
+ *((unsigned char *) be_image + offset) |= b0;
+ break;
+
+ case 16:
+ *((unsigned char *) le_image + offset + 0) |= b0;
+ *((unsigned char *) le_image + offset + 1) |= b1;
+ *((unsigned char *) be_image + offset + 0) |= b1;
+ *((unsigned char *) be_image + offset + 1) |= b0;
+ break;
+
+ case 32:
+ *((unsigned char *) le_image + offset + 0) |= b0;
+ *((unsigned char *) le_image + offset + 1) |= b1;
+ *((unsigned char *) le_image + offset + 2) |= b2;
+ *((unsigned char *) le_image + offset + 3) |= b3;
+ *((unsigned char *) be_image + offset + 0) |= b3;
+ *((unsigned char *) be_image + offset + 1) |= b2;
+ *((unsigned char *) be_image + offset + 2) |= b1;
+ *((unsigned char *) be_image + offset + 3) |= b0;
+ break;
+
+ default:
+ gcc_unreachable ();
+ }
+ }
}
else
{
expand_init_to_stmt_list1 (ltarget, value,
stmt_list1, cleared,
- stmt_list2, NULL, NULL);
+ stmt_list2, NULL, NULL, 0);
}
}
}
@@ -1388,18 +1490,18 @@ expand_init_to_stmt_list1 (tree decl, tree init,
{
unsigned HOST_WIDE_INT offset;
- offset = tree_low_cst (index, 1) * tree_low_cst (elsize, 1);
+ offset = tree_low_cst (index, 1) * tree_low_cst (elsize, 1)
+ + image_offset;
expand_init_to_stmt_list1 (t, value,
stmt_list1, cleared,
stmt_list2,
- (void *)((intptr_t) le_image + offset),
- (void *)((intptr_t) be_image + offset));
+ le_image, be_image, offset);
}
else
{
expand_init_to_stmt_list1 (t, value,
stmt_list1, cleared,
- stmt_list2, NULL, NULL);
+ stmt_list2, NULL, NULL, 0);
}
}
}
@@ -1533,26 +1635,26 @@ expand_init_to_stmt_list1 (tree decl, tree init,
switch (type_size)
{
case 1:
- *(unsigned char *) le_image = b0;
- *(unsigned char *) be_image = b0;
+ *((unsigned char *) le_image + image_offset) = b0;
+ *((unsigned char *) be_image + image_offset) = b0;
break;
case 2:
- *((unsigned char *) le_image + 0) = b0;
- *((unsigned char *) le_image + 1) = b1;
- *((unsigned char *) be_image + 0) = b1;
- *((unsigned char *) be_image + 1) = b0;
+ *((unsigned char *) le_image + image_offset + 0) = b0;
+ *((unsigned char *) le_image + image_offset + 1) = b1;
+ *((unsigned char *) be_image + image_offset + 0) = b1;
+ *((unsigned char *) be_image + image_offset + 1) = b0;
break;
case 4:
- *((unsigned char *) le_image + 0) = b0;
- *((unsigned char *) le_image + 1) = b1;
- *((unsigned char *) le_image + 2) = b2;
- *((unsigned char *) le_image + 3) = b3;
- *((unsigned char *) be_image + 0) = b3;
- *((unsigned char *) be_image + 1) = b2;
- *((unsigned char *) be_image + 2) = b1;
- *((unsigned char *) be_image + 3) = b0;
+ *((unsigned char *) le_image + image_offset + 0) = b0;
+ *((unsigned char *) le_image + image_offset + 1) = b1;
+ *((unsigned char *) le_image + image_offset + 2) = b2;
+ *((unsigned char *) le_image + image_offset + 3) = b3;
+ *((unsigned char *) be_image + image_offset + 0) = b3;
+ *((unsigned char *) be_image + image_offset + 1) = b2;
+ *((unsigned char *) be_image + image_offset + 2) = b1;
+ *((unsigned char *) be_image + image_offset + 3) = b0;
break;
default:
@@ -1608,7 +1710,7 @@ expand_init_to_stmt_list (tree decl, tree init, tree *stmt_list)
expand_init_to_stmt_list1 (decl, init,
&stmt_list1, FALSE,
- &stmt_list2, le_image, be_image);
+ &stmt_list2, le_image, be_image, 0);
num_list1 = statement_list_num_instr (stmt_list1);
num_list2 = statement_list_num_instr (stmt_list2);
diff --git a/gcc/config/cil32/cil-refs.h b/gcc/config/cil32/cil-refs.h
index 88c0863daf2..4dfeef990dd 100644
--- a/gcc/config/cil32/cil-refs.h
+++ b/gcc/config/cil32/cil-refs.h
@@ -75,6 +75,7 @@ extern htab_t referenced_types_htab ( void );
extern tree promote_type_for_vararg (tree);
extern tree promote_local_var_type (tree);
extern bool cil_pointer_type_p (tree);
+extern tree get_integer_type (unsigned int, bool);
/******************************************************************************
* Strings *
diff --git a/gcc/config/cil32/cil-stmt-inline.h b/gcc/config/cil32/cil-stmt-inline.h
index 0bd42c01e69..498179434cc 100644
--- a/gcc/config/cil32/cil-stmt-inline.h
+++ b/gcc/config/cil32/cil-stmt-inline.h
@@ -159,34 +159,6 @@ cil_switch_case_label (const_cil_stmt stmt, size_t i)
return CASE_LABEL (stmt->arg.labels->cases[i]);
}
-/* Return the low value of the I-th case of CIL switch statement as an
- HOST_WIDE_INT instead of a tree. */
-
-static inline HOST_WIDE_INT
-cil_switch_case_low (const_cil_stmt stmt, size_t i)
-{
- gcc_assert (stmt->opcode == CIL_SWITCH);
- gcc_assert (i < stmt->arg.labels->ncases);
-
- return tree_low_cst (CASE_LOW (stmt->arg.labels->cases[i]), 0);
-}
-
-/* Return the high value of the I-th case of CIL switch statement as an
- HOST_WIDE_INT instead of a tree. If the case doesn't represent a range then
- this function will return the case value (i.e. the low value). */
-
-static inline HOST_WIDE_INT
-cil_switch_case_high (const_cil_stmt stmt, size_t i)
-{
- gcc_assert (stmt->opcode == CIL_SWITCH);
- gcc_assert (i < stmt->arg.labels->ncases);
-
- if (CASE_HIGH (stmt->arg.labels->cases[i]))
- return tree_low_cst (CASE_HIGH (stmt->arg.labels->cases[i]), 0);
- else
- return tree_low_cst (CASE_LOW (stmt->arg.labels->cases[i]), 0);
-}
-
/* Return the function declaration of a CIL LDFTN statement. */
static inline
diff --git a/gcc/config/cil32/cil-stmt.c b/gcc/config/cil32/cil-stmt.c
index 0480ce38d53..70fdcf0c4a9 100644
--- a/gcc/config/cil32/cil-stmt.c
+++ b/gcc/config/cil32/cil-stmt.c
@@ -266,6 +266,41 @@ cil_call_nargs_base (const_cil_stmt stmt)
}
}
+/* Return the low value of the I-th case of CIL switch statement as an
+ HOST_WIDE_INT instead of a tree. */
+
+HOST_WIDE_INT
+cil_switch_case_low (const_cil_stmt stmt, size_t i)
+{
+ tree value;
+
+ gcc_assert (stmt->opcode == CIL_SWITCH);
+ gcc_assert (i < stmt->arg.labels->ncases);
+
+ value = CASE_LOW (stmt->arg.labels->cases[i]);
+ return tree_low_cst (value, TYPE_UNSIGNED (TREE_TYPE (value)));
+}
+
+/* Return the high value of the I-th case of CIL switch statement as an
+ HOST_WIDE_INT instead of a tree. If the case doesn't represent a range then
+ this function will return the case value (i.e. the low value). */
+
+HOST_WIDE_INT
+cil_switch_case_high (const_cil_stmt stmt, size_t i)
+{
+ tree value;
+
+ gcc_assert (stmt->opcode == CIL_SWITCH);
+ gcc_assert (i < stmt->arg.labels->ncases);
+
+ if (CASE_HIGH (stmt->arg.labels->cases[i]))
+ value = CASE_HIGH (stmt->arg.labels->cases[i]);
+ else
+ value = CASE_LOW (stmt->arg.labels->cases[i]);
+
+ return tree_low_cst (value, TYPE_UNSIGNED (TREE_TYPE (value)));
+}
+
/* Create a deep copy of the CIL statement pointed by STMT and return it. */
cil_stmt
diff --git a/gcc/config/cil32/cil-stmt.h b/gcc/config/cil32/cil-stmt.h
index df4ddbb05f2..5e9426db410 100644
--- a/gcc/config/cil32/cil-stmt.h
+++ b/gcc/config/cil32/cil-stmt.h
@@ -55,6 +55,8 @@ extern void cil_set_prefix_unaligned (cil_stmt, int);
extern bool cil_prefix_volatile (const_cil_stmt);
extern void cil_set_prefix_volatile (cil_stmt, bool);
extern size_t cil_call_nargs_base (const_cil_stmt);
+extern HOST_WIDE_INT cil_switch_case_low (const_cil_stmt, size_t);
+extern HOST_WIDE_INT cil_switch_case_high (const_cil_stmt, size_t);
static inline enum cil_opcode cil_opcode (const_cil_stmt);
static inline basic_block cil_bb (const_cil_stmt);
@@ -69,8 +71,6 @@ static inline size_t cil_switch_ncases (const_cil_stmt);
static inline tree cil_switch_case (const_cil_stmt, size_t);
static inline tree cil_switch_default (const_cil_stmt);
static inline tree cil_switch_case_label (const_cil_stmt, size_t);
-static inline HOST_WIDE_INT cil_switch_case_low (const_cil_stmt, size_t);
-static inline HOST_WIDE_INT cil_switch_case_high (const_cil_stmt, size_t);
static inline tree cil_func (const_cil_stmt);
static inline cil_stmt cil_build_call (tree);
static inline cil_stmt cil_build_calli (tree);
diff --git a/gcc/config/cil32/cil32.md b/gcc/config/cil32/cil32.md
index 9ea4af49d7f..89ca838f123 100644
--- a/gcc/config/cil32/cil32.md
+++ b/gcc/config/cil32/cil32.md
@@ -184,6 +184,30 @@
""
"xor")
+(define_insn "ashl<mode>3"
+ [(set (match_operand:ALLINTEVALMODES 0 "nonimmediate_operand" "")
+ (ashift:ALLINTEVALMODES
+ (match_operand:ALLINTEVALMODES 1 "general_operand" "")
+ (match_operand:ALLINTEVALMODES 2 "general_operand" "")))]
+ ""
+ "ashl")
+
+(define_insn "lshr<mode>3"
+ [(set (match_operand:ALLINTEVALMODES 0 "nonimmediate_operand" "")
+ (lshiftrt:ALLINTEVALMODES
+ (match_operand:ALLINTEVALMODES 1 "general_operand" "")
+ (match_operand:ALLINTEVALMODES 2 "general_operand" "")))]
+ ""
+ "lshr")
+
+(define_insn "ashr<mode>3"
+ [(set (match_operand:ALLINTEVALMODES 0 "nonimmediate_operand" "")
+ (ashiftrt:ALLINTEVALMODES
+ (match_operand:ALLINTEVALMODES 1 "general_operand" "")
+ (match_operand:ALLINTEVALMODES 2 "general_operand" "")))]
+ ""
+ "ashr")
+
;; Call insns.
diff --git a/gcc/config/cil32/emit-cil.c b/gcc/config/cil32/emit-cil.c
index bc412bc9422..0c7f837d1ee 100644
--- a/gcc/config/cil32/emit-cil.c
+++ b/gcc/config/cil32/emit-cil.c
@@ -1488,13 +1488,8 @@ emit_call (FILE *file, const_cil_stmt call)
fprintf (file, " ");
- if (DECL_BUILT_IN (fdecl))
- {
- if (DECL_BUILT_IN_CLASS (fdecl) == BUILT_IN_MD)
- fprintf (file, "%s", IDENTIFIER_POINTER (DECL_NAME (fdecl)));
- else
- dump_decl_name (file, fdecl);
- }
+ if (DECL_BUILT_IN (fdecl) && DECL_BUILT_IN_CLASS (fdecl) == BUILT_IN_MD)
+ fprintf (file, "%s", IDENTIFIER_POINTER (DECL_NAME (fdecl)));
else
{
if (attrs.assembly_name)
@@ -2407,12 +2402,11 @@ emit_cil_1 (FILE *file)
emit_cil_bb (file, bb);
}
-/* FIXME
if (TARGET_EMIT_JIT_COMPILATION_HINTS)
{
basic_block_frequency_emit (file);
branch_probability_emit_and_reset (file);
- } */
+ }
fprintf (file,
"\n\t.maxstack %u\n"
diff --git a/gcc/config/cil32/gimple-to-cil.c b/gcc/config/cil32/gimple-to-cil.c
index 32c25388bcc..14e5a8a2366 100644
--- a/gcc/config/cil32/gimple-to-cil.c
+++ b/gcc/config/cil32/gimple-to-cil.c
@@ -97,7 +97,6 @@ static void gen_view_convert_expr (cil_stmt_iterator *, tree);
static void gen_complex_part_expr (cil_stmt_iterator *, tree);
static void gen_complex (cil_stmt_iterator *, tree, tree, tree);
static enum cil_opcode conv_opcode_from_type (tree);
-static tree get_integer_type (unsigned int, bool);
static void gen_integral_conv (cil_stmt_iterator *, tree, tree);
static void gen_conv (cil_stmt_iterator *, bool, tree, tree);
static void gen_rotate (cil_stmt_iterator *, tree);
@@ -218,6 +217,21 @@ gen_addr_expr (cil_stmt_iterator *csi, tree node)
gen_addr_expr (csi, GENERIC_TREE_OPERAND (node, 0));
break;
+ case REALPART_EXPR:
+ case IMAGPART_EXPR:
+ gen_addr_expr (csi, GENERIC_TREE_OPERAND (node, 0));
+
+ if (TREE_CODE (node) == IMAGPART_EXPR)
+ {
+ gen_integer_cst (csi,
+ fold_convert (intSI_type_node,
+ TYPE_SIZE_UNIT (TREE_TYPE (node))));
+ stmt = cil_build_stmt (CIL_ADD);
+ csi_insert_after (csi, stmt, CSI_CONTINUE_LINKING);
+ }
+
+ break;
+
default:
gcc_unreachable ();
}
@@ -1829,11 +1843,24 @@ gen_minmax_expr (cil_stmt_iterator *csi, tree node)
enum cil32_builtin builtin = 0;
gimple_to_cil_node (csi, TREE_OPERAND (node, 0));
+
+ if (POINTER_TYPE_P (type))
+ {
+ stmt = cil_build_stmt (CIL_CONV_I);
+ csi_insert_after (csi, stmt, CSI_CONTINUE_LINKING);
+ }
+
gimple_to_cil_node (csi, TREE_OPERAND (node, 1));
- if (INTEGRAL_TYPE_P (type))
+ if (POINTER_TYPE_P (type))
{
- unsignedp = TYPE_UNSIGNED (type);
+ stmt = cil_build_stmt (CIL_CONV_I);
+ csi_insert_after (csi, stmt, CSI_CONTINUE_LINKING);
+ }
+
+ if (INTEGRAL_TYPE_P (type) || POINTER_TYPE_P (type))
+ {
+ unsignedp = TYPE_UNSIGNED (type) || POINTER_TYPE_P (type);
if (size <= 32)
{
@@ -2486,23 +2513,6 @@ conv_opcode_from_type (tree type)
gcc_unreachable ();
}
-/* Return an integer type of SIZE bits, unsigned if UNSIGNEDP is set, signed
- otherwise. */
-
-static tree
-get_integer_type (unsigned int size, bool unsignedp)
-{
- switch (size)
- {
- case 8: return unsignedp ? unsigned_intQI_type_node : intQI_type_node;
- case 16: return unsignedp ? unsigned_intHI_type_node : intHI_type_node;
- case 32: return unsignedp ? unsigned_intSI_type_node : intSI_type_node;
- case 64: return unsignedp ? unsigned_intDI_type_node : intDI_type_node;
- default:
- gcc_unreachable ();
- }
-}
-
/* Emit a conversion from integral or pointer type SRC to integral type DST.
If the precision of DST is bigger than that of SRC, then SRC and DST have
to have the same signedness. */
@@ -2974,6 +2984,12 @@ gimple_to_cil_node (cil_stmt_iterator *csi, tree node)
case BIT_NOT_EXPR:
gimple_to_cil_node (csi, TREE_OPERAND (node, 0));
+ if (POINTER_TYPE_P (TREE_TYPE (TREE_OPERAND (node, 0))))
+ {
+ csi_insert_after (csi, cil_build_stmt (CIL_CONV_I),
+ CSI_CONTINUE_LINKING);
+ }
+
opcode = (TREE_CODE (node) == NEGATE_EXPR) ? CIL_NEG : CIL_NOT;
stmt = cil_build_stmt (opcode);
csi_insert_after (csi, stmt, CSI_CONTINUE_LINKING);
diff --git a/gcc/config/cil32/remove-convs.c b/gcc/config/cil32/remove-convs.c
index 9aa52b6ee33..6bc1a67fab1 100644
--- a/gcc/config/cil32/remove-convs.c
+++ b/gcc/config/cil32/remove-convs.c
@@ -170,8 +170,11 @@ fold_conversion (enum cil_opcode op, cil_type_t type)
break;
case CIL_CONV_I2:
- if (type == CIL_UNSIGNED_INT8)
- return true;
+ if ((type == CIL_INT8) || (type == CIL_UNSIGNED_INT8)
+ || (type == CIL_INT16))
+ {
+ return true;
+ }
break;
diff --git a/gcc/config/cil32/t-cil32 b/gcc/config/cil32/t-cil32
index 9c4129d5283..ed38493aa88 100644
--- a/gcc/config/cil32/t-cil32
+++ b/gcc/config/cil32/t-cil32
@@ -57,9 +57,9 @@ emit-hints.o: $(srcdir)/config/cil32/emit-hints.c \
cil-stack.o : $(srcdir)/config/cil32/cil-stack.c \
$(srcdir)/config/cil32/cil-stack.c $(srcdir)/config/cil32/cil-stack.h \
- $(srcdir)/config/cil32/cil-stmt.h $(srcdir)/config/cil32/cil-types.h \
- $(CONFIG_H) $(GGC_H) $(SYSTEM_H) $(TM_H) $(TREE_H) $(TREE_FLOW_H) \
- coretypes.h errors.h vec.h
+ $(srcdir)/config/cil32/cil-stmt.h $(srcdir)/config/cil32/cil-stmt-inline.h \
+ $(srcdir)/config/cil32/cil-types.h $(CONFIG_H) $(GGC_H) $(SYSTEM_H) $(TM_H) \
+ $(TREE_H) $(TREE_FLOW_H) coretypes.h errors.h vec.h
$(CC) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) $< $(OUTPUT_OPTION)
cil-stmt.o : $(srcdir)/config/cil32/cil-stmt.c \
@@ -79,42 +79,47 @@ gimple-to-cil.o : $(srcdir)/config/cil32/gimple-to-cil.c \
emit-cil.o : $(srcdir)/config/cil32/emit-cil.c \
$(srcdir)/config/cil32/emit-cil.h $(srcdir)/config/cil32/emit-hints.h \
$(srcdir)/config/cil32/cil-refs.h $(srcdir)/config/cil32/cil-stmt.h \
- $(srcdir)/config/cil32/cil-types.h $(CONFIG_H) $(GGC_H) $(SYSTEM_H) \
- $(TIMEVAR_H) $(TM_H) $(TREE_H) $(TREE_FLOW_H) $(TREE_PASS_H) coretypes.h \
- ebitmap.h errors.h langhooks.h output.h varray.h pointer-set.h real.h
+ $(srcdir)/config/cil32/cil-stmt-inline.h $(srcdir)/config/cil32/cil-types.h \
+ $(CONFIG_H) $(GGC_H) $(SYSTEM_H) $(TIMEVAR_H) $(TM_H) $(TREE_H) \
+ $(TREE_FLOW_H) $(TREE_PASS_H) coretypes.h ebitmap.h errors.h langhooks.h \
+ output.h varray.h pointer-set.h real.h
$(CC) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) $< $(OUTPUT_OPTION)
missing-protos.o : $(srcdir)/config/cil32/missing-protos.c \
$(srcdir)/config/cil32/cil-refs.h $(srcdir)/config/cil32/cil-stmt.h \
+ $(srcdir)/config/cil32/cil-stmt-inline.h \
$(srcdir)/config/cil32/cil-types.h $(CONFIG_H) $(FLAGS_H) $(SYSTEM_H) \
$(TIMEVAR_H) $(TM_H) $(TREE_H) $(TREE_PASS_H) coretypes.h errors.h \
pointer-set.h
$(CC) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) $< $(OUTPUT_OPTION)
peephole.o : $(srcdir)/config/cil32/peephole.c \
- $(srcdir)/config/cil32/cil-stmt.h $(srcdir)/config/cil32/cil-types.h \
- $(CONFIG_H) $(FLAGS_H) $(SYSTEM_H) $(TIMEVAR_H) $(TM_H) $(TREE_H) \
- $(TREE_PASS_H) coretypes.h
+ $(srcdir)/config/cil32/cil-stmt.h $(srcdir)/config/cil32/cil-stmt-inline.h \
+ $(srcdir)/config/cil32/cil-types.h $(CONFIG_H) $(FLAGS_H) $(SYSTEM_H) \
+ $(TIMEVAR_H) $(TM_H) $(TREE_H) $(TREE_PASS_H) coretypes.h
$(CC) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) $< $(OUTPUT_OPTION)
remove-convs.o : $(srcdir)/config/cil32/remove-convs.c \
$(srcdir)/config/cil32/cil-refs.h $(srcdir)/config/cil32/cil-stack.h \
- $(srcdir)/config/cil32/cil-stmt.h $(srcdir)/config/cil32/cil-types.h \
- $(CONFIG_H) $(FLAGS_H) $(SYSTEM_H) $(TIMEVAR_H) $(TM_H) $(TREE_H) \
- $(TREE_PASS_H) coretypes.h errors.h pointer-set.h
+ $(srcdir)/config/cil32/cil-stmt.h $(srcdir)/config/cil32/cil-stmt-inline.h \
+ $(srcdir)/config/cil32/cil-types.h $(CONFIG_H) $(FLAGS_H) $(SYSTEM_H) \
+ $(TIMEVAR_H) $(TM_H) $(TREE_H) $(TREE_PASS_H) coretypes.h errors.h \
+ pointer-set.h
$(CC) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) $< $(OUTPUT_OPTION)
remove-temps.o : $(srcdir)/config/cil32/remove-temps.c \
$(srcdir)/config/cil32/cil-refs.h $(srcdir)/config/cil32/cil-stack.h \
- $(srcdir)/config/cil32/cil-stmt.h $(srcdir)/config/cil32/cil-types.h \
- $(CONFIG_H) $(FLAGS_H) $(SYSTEM_H) $(TIMEVAR_H) $(TM_H) $(TREE_H) \
- $(TREE_PASS_H) coretypes.h errors.h pointer-set.h
+ $(srcdir)/config/cil32/cil-stmt.h $(srcdir)/config/cil32/cil-stmt-inline.h \
+ $(srcdir)/config/cil32/cil-types.h $(CONFIG_H) $(FLAGS_H) $(SYSTEM_H) \
+ $(TIMEVAR_H) $(TM_H) $(TREE_H) $(TREE_PASS_H) coretypes.h errors.h \
+ pointer-set.h
$(CC) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) $< $(OUTPUT_OPTION)
simp-cond.o : $(srcdir)/config/cil32/simp-cond.c \
$(srcdir)/config/cil32/cil-stack.h $(srcdir)/config/cil32/cil-stmt.h \
- $(srcdir)/config/cil32/cil-types.h $(CONFIG_H) $(FLAGS_H) $(SYSTEM_H) \
- $(TIMEVAR_H) $(TM_H) $(TREE_H) $(TREE_FLOW_H) $(TREE_PASS_H) coretypes.h
+ $(srcdir)/config/cil32/cil-stmt-inline.h $(srcdir)/config/cil32/cil-types.h \
+ $(CONFIG_H) $(FLAGS_H) $(SYSTEM_H) $(TIMEVAR_H) $(TM_H) $(TREE_H) \
+ $(TREE_FLOW_H) $(TREE_PASS_H) coretypes.h
$(CC) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) $< $(OUTPUT_OPTION)
tree-simp-cil-early.o: $(srcdir)/config/cil32/tree-simp-cil-early.c \
diff --git a/gcc/config/cil32/tree-simp-cil-early.c b/gcc/config/cil32/tree-simp-cil-early.c
index aa57e030471..967a5f5d09e 100644
--- a/gcc/config/cil32/tree-simp-cil-early.c
+++ b/gcc/config/cil32/tree-simp-cil-early.c
@@ -82,8 +82,8 @@ static bool simp_cil_early_gate (void);
******************************************************************************/
/* Values used by the switch-conversion heuristics */
-#define SIMP_SWITCH_RANGE_SIZE (4)
-#define SIMP_SWITCH_HOLE_SIZE (4)
+#define SIMP_SWITCH_RANGE_SIZE (3)
+#define SIMP_SWITCH_HOLE_SIZE (3)
/* Hash-table used for storing equivalent labels */
static struct pointer_map_t *eqv_labels = NULL;
@@ -144,8 +144,8 @@ is_eqv_label (tree label1, tree label2)
{
struct eqv_label_entry_t *t1, *t2;
- t1 = *pointer_map_contains(eqv_labels, label1);
- t2 = *pointer_map_contains(eqv_labels, label2);
+ t1 = *pointer_map_contains (eqv_labels, label1);
+ t2 = *pointer_map_contains (eqv_labels, label2);
if (t1 == NULL || t2 == NULL)
return false;
@@ -161,7 +161,7 @@ is_eqv_label (tree label1, tree label2)
not group equivalent labels which are non-adjacent. */
static void
-group_labels(tree func)
+group_labels (tree func)
{
tree_stmt_iterator tsi;
tree t = NULL_TREE;
@@ -193,7 +193,7 @@ group_labels(tree func)
}
}
-/* Used in pointer_map_traverse() to free eqv_label_t entries */
+/* Used in pointer_map_traverse () to free eqv_label_t entries */
static bool
eqv_label_dispose (void *key ATTRIBUTE_UNUSED, void **value,
@@ -307,41 +307,41 @@ case_to_cond_expr (tree switch_stmt, tree single_case, tree *list)
build1 (GOTO_EXPR, void_type_node, label_decl));
/* Append the COND_EXPR to the list */
- append_to_statement_list(cmp_stmt, list);
+ append_to_statement_list (cmp_stmt, list);
/* Create the label to the next statement and append it to the list */
label = build1 (LABEL_EXPR, void_type_node, label_decl);
- append_to_statement_list(label, list);
+ append_to_statement_list (label, list);
}
/* Turn a case range into a couple of COND_EXPRs */
static void
-case_range_to_cond_expr(tree switch_stmt, tree case_range, tree *list)
+case_range_to_cond_expr (tree switch_stmt, tree case_range, tree *list)
{
tree label_decl1 = create_artificial_label ();
tree label_decl2 = create_artificial_label ();
tree cmp1_stmt, cmp2_stmt, label;
- gcc_assert(CASE_HIGH (case_range) != NULL_TREE
- && CASE_LOW (case_range) != NULL_TREE);
+ gcc_assert (CASE_HIGH (case_range) != NULL_TREE
+ && CASE_LOW (case_range) != NULL_TREE);
/* Build the 1st COND_EXPR */
cmp1_stmt = build3 (COND_EXPR, void_type_node,
build2 (GE_EXPR, boolean_type_node,
SWITCH_COND (switch_stmt),
- CASE_LOW(case_range)),
+ CASE_LOW (case_range)),
build1 (GOTO_EXPR, void_type_node,
label_decl1),
build1 (GOTO_EXPR, void_type_node,
label_decl2));
/* Append the 1st COND_EXPR to the list */
- append_to_statement_list(cmp1_stmt, list);
+ append_to_statement_list (cmp1_stmt, list);
/* Create a new label and append it to the list */
label = build1 (LABEL_EXPR, void_type_node, label_decl1);
- append_to_statement_list(label, list);
+ append_to_statement_list (label, list);
/* Build the 2nd COND_EXPR */
cmp2_stmt = build3 (COND_EXPR, void_type_node,
@@ -358,7 +358,7 @@ case_range_to_cond_expr(tree switch_stmt, tree case_range, tree *list)
/* Create the label to the next statement and append it */
label = build1 (LABEL_EXPR, void_type_node, label_decl2);
- append_to_statement_list(label, list);
+ append_to_statement_list (label, list);
}
/* Turn the cases between <start> and <end> (included) into a new switch
@@ -368,26 +368,30 @@ static void
cases_to_switch (tree switch_stmt, unsigned int start, unsigned int end,
tree *list)
{
- tree label_decl = create_artificial_label ();
+ tree label_decl;
tree labels = SWITCH_LABELS (switch_stmt);
tree stmt, label, vec, deft, elt;
unsigned int i, len;
- double_int low, high, range, limit = shwi_to_double_int (8192);
+ tree low, high, range, limit;
+ tree type;
+
+ type = TREE_TYPE (CASE_LOW (TREE_VEC_ELT (labels, start)));
+ limit = build_int_cst (type, 8192);
while (start <= end)
{
+ label_decl = create_artificial_label ();
elt = TREE_VEC_ELT (labels, start);
- low = TREE_INT_CST (CASE_LOW (elt));
+ low = CASE_LOW (elt);
len = 1;
while (start + len <= end)
{
elt = TREE_VEC_ELT (labels, start + len);
- high = TREE_INT_CST (CASE_HIGH (elt) ? CASE_HIGH (elt)
- : CASE_LOW (elt));
- range = double_int_add (high, double_int_neg (low));
+ high = CASE_HIGH (elt) ? CASE_HIGH (elt) : CASE_LOW (elt);
+ range = size_binop (MINUS_EXPR, high, low);
- if (double_int_ucmp (range, limit) == -1)
+ if (tree_int_cst_lt (range, limit))
len++;
else
break;
@@ -409,11 +413,11 @@ cases_to_switch (tree switch_stmt, unsigned int start, unsigned int end,
SWITCH_COND (switch_stmt), NULL, vec);
/* Append the SWITCH to the list */
- append_to_statement_list(stmt, list);
+ append_to_statement_list (stmt, list);
/* Create a new label and append it to the list */
label = build1 (LABEL_EXPR, void_type_node, label_decl);
- append_to_statement_list(label, list);
+ append_to_statement_list (label, list);
/* Move ahead in the labels vector */
start += len;
@@ -433,18 +437,11 @@ simp_cil_switch (tree switch_stmt)
tree curr, next;
tree labels = SWITCH_LABELS (switch_stmt);
tree list = NULL_TREE;
- double_int range_size = shwi_to_double_int (SIMP_SWITCH_RANGE_SIZE);
- double_int hole_size = shwi_to_double_int (SIMP_SWITCH_HOLE_SIZE);
- double_int curr_high, next_low;
+ tree range_size, hole_size, curr_high, next_low;
+ tree type;
unsigned int i = 0;
unsigned int base_idx = 0;
- /* The switch body is lowered in gimplify.c, we should never have
- switches with a non-NULL SWITCH_BODY here. */
- gcc_assert (TREE_CODE (switch_stmt) == SWITCH_EXPR
- && SWITCH_LABELS (switch_stmt)
- && !SWITCH_BODY (switch_stmt));
-
merge_cases_into_ranges (switch_stmt);
if (TREE_VEC_LENGTH (labels) == 1)
@@ -454,7 +451,9 @@ simp_cil_switch (tree switch_stmt)
return NULL_TREE;
}
- gcc_assert (!is_copy_required (SWITCH_COND (switch_stmt)));
+ type = TREE_TYPE (CASE_LOW (TREE_VEC_ELT (labels, 0)));
+ range_size = build_int_cst (type, SIMP_SWITCH_RANGE_SIZE);
+ hole_size = build_int_cst (type, SIMP_SWITCH_HOLE_SIZE);
while (true)
{
@@ -481,7 +480,7 @@ simp_cil_switch (tree switch_stmt)
/* Add a label which jumps to the default label. */
append_to_statement_list (build1 (GOTO_EXPR, void_type_node,
- CASE_LABEL(next)),
+ CASE_LABEL (next)),
&list);
break;
}
@@ -492,13 +491,13 @@ simp_cil_switch (tree switch_stmt)
COND_EXPRs. We don't need to check if we have some pending cases to
deal with as we have already emitted them in the previous iteration
as implemented below. */
- double_int low = TREE_INT_CST (CASE_LOW (curr));
- double_int high = TREE_INT_CST (CASE_HIGH (curr));
+ tree low = size_binop (PLUS_EXPR, CASE_LOW (curr), range_size);
+ tree high = CASE_HIGH (curr);
/* if (low + SIMP_SWITCH_RANGE_SIZE > high) */
- if (double_int_scmp(double_int_add (low, range_size), high) == 1)
+ if (tree_int_cst_compare (low, high) == 1)
{
- gcc_assert(i == base_idx);
+ gcc_assert (i == base_idx);
case_range_to_cond_expr (switch_stmt, curr, &list);
i++;
@@ -511,11 +510,11 @@ simp_cil_switch (tree switch_stmt)
{
/* The next case is a range, if it's large enough blow it up into two
COND_EXPRs then emit the previous cases. */
- double_int low = TREE_INT_CST (CASE_LOW (next));
- double_int high = TREE_INT_CST (CASE_HIGH (next));
+ tree low = size_binop (PLUS_EXPR, CASE_LOW (next), range_size);
+ tree high = CASE_HIGH (next);
/* if (low + SIMP_SWITCH_RANGE_SIZE > high) */
- if (double_int_scmp(double_int_add (low, range_size), high) == 1)
+ if (tree_int_cst_compare (low, high) == 1)
{
if (base_idx != i)
cases_to_switch (switch_stmt, base_idx, i, &list);
@@ -533,14 +532,15 @@ simp_cil_switch (tree switch_stmt)
/* Detect 'holes', if a large enough hole is found emit the previous
cases. */
if (CASE_HIGH (curr) != NULL_TREE)
- curr_high = TREE_INT_CST (CASE_HIGH (curr));
+ curr_high = CASE_HIGH (curr);
else
- curr_high = TREE_INT_CST (CASE_LOW (curr));
+ curr_high = CASE_LOW (curr);
- next_low = TREE_INT_CST (CASE_LOW (next));
+ curr_high = size_binop (PLUS_EXPR, curr_high, hole_size);
+ next_low = CASE_LOW (next);
- if (double_int_scmp(double_int_add (curr_high, hole_size), next_low)
- == -1)
+ /* if (curr_high + SIMP_SWITCH_HOLE_SIZE < next_low) */
+ if (tree_int_cst_lt (curr_high, next_low))
{
if (base_idx != i)
cases_to_switch (switch_stmt, base_idx, i, &list);