summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--target/linux/patches/3.16.2/sparc-memset.patch50
-rw-r--r--toolchain/gcc/patches/4.8.3/miscompile.sparc154
2 files changed, 50 insertions, 154 deletions
diff --git a/target/linux/patches/3.16.2/sparc-memset.patch b/target/linux/patches/3.16.2/sparc-memset.patch
new file mode 100644
index 000000000..022c87b3a
--- /dev/null
+++ b/target/linux/patches/3.16.2/sparc-memset.patch
@@ -0,0 +1,50 @@
+This makes memset follow the standard (instead of returning 0 on success). This
+is needed when certain versions of gcc optimizes around memset calls and assume
+that the address argument is preserved in %o0.
+
+Signed-off-by: Andreas Larsson <andreas@gaisler.com>
+
+diff -Nur linux-3.16.2.orig/arch/sparc/lib/memset.S linux-3.16.2/arch/sparc/lib/memset.S
+--- linux-3.16.2.orig/arch/sparc/lib/memset.S 2014-09-06 01:37:11.000000000 +0200
++++ linux-3.16.2/arch/sparc/lib/memset.S 2014-09-18 09:53:49.563047773 +0200
+@@ -65,6 +65,8 @@
+ .globl __memset_start, __memset_end
+ __memset_start:
+ memset:
++ mov %o0, %g1
++ mov 1, %g4
+ and %o1, 0xff, %g3
+ sll %g3, 8, %g2
+ or %g3, %g2, %g3
+@@ -89,6 +91,7 @@
+ sub %o0, %o2, %o0
+
+ __bzero:
++ clr %g4
+ mov %g0, %g3
+ 1:
+ cmp %o1, 7
+@@ -151,8 +154,8 @@
+ bne,a 8f
+ EX(stb %g3, [%o0], and %o1, 1)
+ 8:
+- retl
+- clr %o0
++ b 0f
++ nop
+ 7:
+ be 13b
+ orcc %o1, 0, %g0
+@@ -164,6 +167,12 @@
+ bne 8b
+ EX(stb %g3, [%o0 - 1], add %o1, 1)
+ 0:
++ andcc %g4, 1, %g0
++ be 5f
++ nop
++ retl
++ mov %g1, %o0
++5:
+ retl
+ clr %o0
+ __memset_end:
diff --git a/toolchain/gcc/patches/4.8.3/miscompile.sparc b/toolchain/gcc/patches/4.8.3/miscompile.sparc
deleted file mode 100644
index b7ac26396..000000000
--- a/toolchain/gcc/patches/4.8.3/miscompile.sparc
+++ /dev/null
@@ -1,154 +0,0 @@
-diff -Nur gcc-4.8.3.orig/gcc/tree-ssa-forwprop.c gcc-4.8.3/gcc/tree-ssa-forwprop.c
---- gcc-4.8.3.orig/gcc/tree-ssa-forwprop.c 2013-02-25 16:31:31.000000000 +0100
-+++ gcc-4.8.3/gcc/tree-ssa-forwprop.c 2014-05-23 15:12:47.004949946 +0200
-@@ -688,6 +688,130 @@
- recompute_tree_invariant_for_addr_expr (gimple_assign_rhs1 (stmt));
- }
-
-+ /* DEF_RHS contains the address of the 0th element in an array.
-+ USE_STMT uses type of DEF_RHS to compute the address of an
-+ arbitrary element within the array. The (variable) byte offset
-+ of the element is contained in OFFSET.
-+
-+ We walk back through the use-def chains of OFFSET to verify that
-+ it is indeed computing the offset of an element within the array
-+ and extract the index corresponding to the given byte offset.
-+
-+ We then try to fold the entire address expression into a form
-+ &array[index].
-+
-+ If we are successful, we replace the right hand side of USE_STMT
-+ with the new address computation. */
-+
-+ static bool
-+ forward_propagate_addr_into_variable_array_index (tree offset,
-+ tree def_rhs,
-+ gimple_stmt_iterator *use_stmt_gsi)
-+ {
-+ tree index, tunit;
-+ gimple offset_def, use_stmt = gsi_stmt (*use_stmt_gsi);
-+ tree new_rhs, tmp;
-+
-+ if (TREE_CODE (TREE_OPERAND (def_rhs, 0)) == ARRAY_REF)
-+ tunit = TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (def_rhs)));
-+ else if (TREE_CODE (TREE_TYPE (TREE_OPERAND (def_rhs, 0))) == ARRAY_TYPE)
-+ tunit = TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (TREE_TYPE (def_rhs))));
-+ else
-+ return false;
-+ if (!host_integerp (tunit, 1))
-+ return false;
-+
-+ /* Get the offset's defining statement. */
-+ offset_def = SSA_NAME_DEF_STMT (offset);
-+
-+ /* Try to find an expression for a proper index. This is either a
-+ multiplication expression by the element size or just the ssa name we came
-+ along in case the element size is one. In that case, however, we do not
-+ allow multiplications because they can be computing index to a higher
-+ level dimension (PR 37861). */
-+ if (integer_onep (tunit))
-+ {
-+ if (is_gimple_assign (offset_def)
-+ && gimple_assign_rhs_code (offset_def) == MULT_EXPR)
-+ return false;
-+
-+ index = offset;
-+ }
-+ else
-+ {
-+ /* The statement which defines OFFSET before type conversion
-+ must be a simple GIMPLE_ASSIGN. */
-+ if (!is_gimple_assign (offset_def))
-+ return false;
-+
-+ /* The RHS of the statement which defines OFFSET must be a
-+ multiplication of an object by the size of the array elements.
-+ This implicitly verifies that the size of the array elements
-+ is constant. */
-+ if (gimple_assign_rhs_code (offset_def) == MULT_EXPR
-+ && TREE_CODE (gimple_assign_rhs2 (offset_def)) == INTEGER_CST
-+ && tree_int_cst_equal (gimple_assign_rhs2 (offset_def), tunit))
-+ {
-+ /* The first operand to the MULT_EXPR is the desired index. */
-+ index = gimple_assign_rhs1 (offset_def);
-+ }
-+ /* If we have idx * tunit + CST * tunit re-associate that. */
-+ else if ((gimple_assign_rhs_code (offset_def) == PLUS_EXPR
-+ || gimple_assign_rhs_code (offset_def) == MINUS_EXPR)
-+ && TREE_CODE (gimple_assign_rhs1 (offset_def)) == SSA_NAME
-+ && TREE_CODE (gimple_assign_rhs2 (offset_def)) == INTEGER_CST
-+ && (tmp = div_if_zero_remainder (EXACT_DIV_EXPR,
-+ gimple_assign_rhs2 (offset_def),
-+ tunit)) != NULL_TREE)
-+ {
-+ gimple offset_def2 = SSA_NAME_DEF_STMT (gimple_assign_rhs1 (offset_def));
-+ if (is_gimple_assign (offset_def2)
-+ && gimple_assign_rhs_code (offset_def2) == MULT_EXPR
-+ && TREE_CODE (gimple_assign_rhs2 (offset_def2)) == INTEGER_CST
-+ && tree_int_cst_equal (gimple_assign_rhs2 (offset_def2), tunit))
-+ {
-+ index = fold_build2 (gimple_assign_rhs_code (offset_def),
-+ TREE_TYPE (offset),
-+ gimple_assign_rhs1 (offset_def2), tmp);
-+ }
-+ else
-+ return false;
-+ }
-+ else
-+ return false;
-+ }
-+
-+ /* Replace the pointer addition with array indexing. */
-+ index = force_gimple_operand_gsi (use_stmt_gsi, index, true, NULL_TREE,
-+ true, GSI_SAME_STMT);
-+ if (TREE_CODE (TREE_OPERAND (def_rhs, 0)) == ARRAY_REF)
-+ {
-+ new_rhs = unshare_expr (def_rhs);
-+ TREE_OPERAND (TREE_OPERAND (new_rhs, 0), 1) = index;
-+ }
-+ else
-+ {
-+ new_rhs = build4 (ARRAY_REF, TREE_TYPE (TREE_TYPE (TREE_TYPE (def_rhs))),
-+ unshare_expr (TREE_OPERAND (def_rhs, 0)),
-+ index, integer_zero_node, NULL_TREE);
-+ new_rhs = build_fold_addr_expr (new_rhs);
-+ if (!useless_type_conversion_p (TREE_TYPE (gimple_assign_lhs (use_stmt)),
-+ TREE_TYPE (new_rhs)))
-+ {
-+ new_rhs = force_gimple_operand_gsi (use_stmt_gsi, new_rhs, true,
-+ NULL_TREE, true, GSI_SAME_STMT);
-+ new_rhs = fold_convert (TREE_TYPE (gimple_assign_lhs (use_stmt)),
-+ new_rhs);
-+ }
-+ }
-+ gimple_assign_set_rhs_from_tree (use_stmt_gsi, new_rhs);
-+ fold_stmt (use_stmt_gsi);
-+ tidy_after_forward_propagate_addr (gsi_stmt (*use_stmt_gsi));
-+ return true;
-+ }
-+
-+
-+
- /* NAME is a SSA_NAME representing DEF_RHS which is of the form
- ADDR_EXPR <whatever>.
-
-@@ -977,6 +1101,19 @@
- tidy_after_forward_propagate_addr (use_stmt);
- return true;
- }
-+ /* Try to optimize &x[0] p+ OFFSET where OFFSET is defined by
-+ converting a multiplication of an index by the size of the
-+ array elements, then the result is converted into the proper
-+ type for the arithmetic. */
-+ if (TREE_CODE (rhs2) == SSA_NAME
-+ && (TREE_CODE (array_ref) != ARRAY_REF
-+ || integer_zerop (TREE_OPERAND (array_ref, 1)))
-+ && useless_type_conversion_p (TREE_TYPE (name), TREE_TYPE (def_rhs))
-+ /* Avoid problems with IVopts creating PLUS_EXPRs with a
-+ different type than their operands. */
-+ && useless_type_conversion_p (TREE_TYPE (lhs), TREE_TYPE (def_rhs)))
-+ return forward_propagate_addr_into_variable_array_index (rhs2, def_rhs,
-+ use_stmt_gsi);
-
- return false;
- }