diff options
-rw-r--r-- | target/linux/patches/3.16.2/sparc-memset.patch | 50 | ||||
-rw-r--r-- | toolchain/gcc/patches/4.8.3/miscompile.sparc | 154 |
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; - } |