diff options
Diffstat (limited to 'toolchain-layer/recipes-devtools/gcc/gcc-4.6/linaro/gcc-4.6-linaro-r106877.patch')
-rw-r--r-- | toolchain-layer/recipes-devtools/gcc/gcc-4.6/linaro/gcc-4.6-linaro-r106877.patch | 239 |
1 files changed, 239 insertions, 0 deletions
diff --git a/toolchain-layer/recipes-devtools/gcc/gcc-4.6/linaro/gcc-4.6-linaro-r106877.patch b/toolchain-layer/recipes-devtools/gcc/gcc-4.6/linaro/gcc-4.6-linaro-r106877.patch new file mode 100644 index 0000000000..b83b957c6f --- /dev/null +++ b/toolchain-layer/recipes-devtools/gcc/gcc-4.6/linaro/gcc-4.6-linaro-r106877.patch @@ -0,0 +1,239 @@ +2012-03-06 Ulrich Weigand <ulrich.weigand@linaro.org> + + Backport from mainline: + + gcc/ + * config/arm/arm.c (arm_sat_operator_match): New function. + * config/arm/arm-protos.h (arm_sat_operator_match): Add prototype. + * config/arm/arm.md ("insn" attribute): Add "sat" value. + ("SAT", "SATrev"): New code iterators. + ("SATlo", "SAThi"): New code iterator attributes. + ("*satsi_<SAT:code>"): New pattern. + ("*satsi_<SAT:code>_shift"): Likewise. + * config/arm/predicates.md (sat_shift_operator): New. + + gcc/testsuite/ + * gcc.target/arm/sat-1.c: New test. + +=== modified file 'gcc/config/arm/arm-protos.h' +--- old/gcc/config/arm/arm-protos.h 2012-02-22 13:31:54 +0000 ++++ new/gcc/config/arm/arm-protos.h 2012-02-29 14:29:56 +0000 +@@ -104,6 +104,7 @@ + extern int symbol_mentioned_p (rtx); + extern int label_mentioned_p (rtx); + extern RTX_CODE minmax_code (rtx); ++extern bool arm_sat_operator_match (rtx, rtx, int *, bool *); + extern int adjacent_mem_locations (rtx, rtx); + extern bool gen_ldm_seq (rtx *, int, bool); + extern bool gen_stm_seq (rtx *, int); + +=== modified file 'gcc/config/arm/arm.c' +--- old/gcc/config/arm/arm.c 2012-03-06 11:01:55 +0000 ++++ new/gcc/config/arm/arm.c 2012-03-06 13:24:25 +0000 +@@ -9978,6 +9978,42 @@ + } + } + ++/* Match pair of min/max operators that can be implemented via usat/ssat. */ ++ ++bool ++arm_sat_operator_match (rtx lo_bound, rtx hi_bound, ++ int *mask, bool *signed_sat) ++{ ++ /* The high bound must be a power of two minus one. */ ++ int log = exact_log2 (INTVAL (hi_bound) + 1); ++ if (log == -1) ++ return false; ++ ++ /* The low bound is either zero (for usat) or one less than the ++ negation of the high bound (for ssat). */ ++ if (INTVAL (lo_bound) == 0) ++ { ++ if (mask) ++ *mask = log; ++ if (signed_sat) ++ *signed_sat = false; ++ ++ return true; ++ } ++ ++ if (INTVAL (lo_bound) == -INTVAL (hi_bound) - 1) ++ { ++ if (mask) ++ *mask = log + 1; ++ if (signed_sat) ++ *signed_sat = true; ++ ++ return true; ++ } ++ ++ return false; ++} ++ + /* Return 1 if memory locations are adjacent. */ + int + adjacent_mem_locations (rtx a, rtx b) + +=== modified file 'gcc/config/arm/arm.md' +--- old/gcc/config/arm/arm.md 2012-03-02 13:53:14 +0000 ++++ new/gcc/config/arm/arm.md 2012-03-06 13:24:25 +0000 +@@ -286,7 +286,7 @@ + ;; scheduling information. + + (define_attr "insn" +- "mov,mvn,smulxy,smlaxy,smlalxy,smulwy,smlawx,mul,muls,mla,mlas,umull,umulls,umlal,umlals,smull,smulls,smlal,smlals,smlawy,smuad,smuadx,smlad,smladx,smusd,smusdx,smlsd,smlsdx,smmul,smmulr,smmla,umaal,smlald,smlsld,clz,mrs,msr,xtab,sdiv,udiv,other" ++ "mov,mvn,smulxy,smlaxy,smlalxy,smulwy,smlawx,mul,muls,mla,mlas,umull,umulls,umlal,umlals,smull,smulls,smlal,smlals,smlawy,smuad,smuadx,smlad,smladx,smusd,smusdx,smlsd,smlsdx,smmul,smmulr,smmla,umaal,smlald,smlsld,clz,mrs,msr,xtab,sdiv,udiv,sat,other" + (const_string "other")) + + ; TYPE attribute is used to detect floating point instructions which, if +@@ -3424,6 +3424,60 @@ + (const_int 12)))] + ) + ++(define_code_iterator SAT [smin smax]) ++(define_code_iterator SATrev [smin smax]) ++(define_code_attr SATlo [(smin "1") (smax "2")]) ++(define_code_attr SAThi [(smin "2") (smax "1")]) ++ ++(define_insn "*satsi_<SAT:code>" ++ [(set (match_operand:SI 0 "s_register_operand" "=r") ++ (SAT:SI (SATrev:SI (match_operand:SI 3 "s_register_operand" "r") ++ (match_operand:SI 1 "const_int_operand" "i")) ++ (match_operand:SI 2 "const_int_operand" "i")))] ++ "TARGET_32BIT && arm_arch6 && <SAT:CODE> != <SATrev:CODE> ++ && arm_sat_operator_match (operands[<SAT:SATlo>], operands[<SAT:SAThi>], NULL, NULL)" ++{ ++ int mask; ++ bool signed_sat; ++ if (!arm_sat_operator_match (operands[<SAT:SATlo>], operands[<SAT:SAThi>], ++ &mask, &signed_sat)) ++ gcc_unreachable (); ++ ++ operands[1] = GEN_INT (mask); ++ if (signed_sat) ++ return "ssat%?\t%0, %1, %3"; ++ else ++ return "usat%?\t%0, %1, %3"; ++} ++ [(set_attr "predicable" "yes") ++ (set_attr "insn" "sat")]) ++ ++(define_insn "*satsi_<SAT:code>_shift" ++ [(set (match_operand:SI 0 "s_register_operand" "=r") ++ (SAT:SI (SATrev:SI (match_operator:SI 3 "sat_shift_operator" ++ [(match_operand:SI 4 "s_register_operand" "r") ++ (match_operand:SI 5 "const_int_operand" "i")]) ++ (match_operand:SI 1 "const_int_operand" "i")) ++ (match_operand:SI 2 "const_int_operand" "i")))] ++ "TARGET_32BIT && arm_arch6 && <SAT:CODE> != <SATrev:CODE> ++ && arm_sat_operator_match (operands[<SAT:SATlo>], operands[<SAT:SAThi>], NULL, NULL)" ++{ ++ int mask; ++ bool signed_sat; ++ if (!arm_sat_operator_match (operands[<SAT:SATlo>], operands[<SAT:SAThi>], ++ &mask, &signed_sat)) ++ gcc_unreachable (); ++ ++ operands[1] = GEN_INT (mask); ++ if (signed_sat) ++ return "ssat%?\t%0, %1, %4%S3"; ++ else ++ return "usat%?\t%0, %1, %4%S3"; ++} ++ [(set_attr "predicable" "yes") ++ (set_attr "insn" "sat") ++ (set_attr "shift" "3") ++ (set_attr "type" "alu_shift")]) + + ;; Shift and rotation insns + + +=== modified file 'gcc/config/arm/predicates.md' +--- old/gcc/config/arm/predicates.md 2012-02-22 13:31:54 +0000 ++++ new/gcc/config/arm/predicates.md 2012-02-29 14:29:56 +0000 +@@ -241,6 +241,15 @@ + || ((unsigned HOST_WIDE_INT) INTVAL (XEXP (op, 1))) < 32"))) + (match_test "mode == GET_MODE (op)"))) + ++;; True for shift operators which can be used with saturation instructions. ++(define_special_predicate "sat_shift_operator" ++ (and (ior (and (match_code "mult") ++ (match_test "power_of_two_operand (XEXP (op, 1), mode)")) ++ (and (match_code "ashift,ashiftrt") ++ (match_test "GET_CODE (XEXP (op, 1)) == CONST_INT ++ && ((unsigned HOST_WIDE_INT) INTVAL (XEXP (op, 1)) < 32)"))) ++ (match_test "mode == GET_MODE (op)"))) ++ + ;; True for MULT, to identify which variant of shift_operator is in use. + (define_special_predicate "mult_operator" + (match_code "mult")) + +=== added file 'gcc/testsuite/gcc.target/arm/sat-1.c' +--- old/gcc/testsuite/gcc.target/arm/sat-1.c 1970-01-01 00:00:00 +0000 ++++ new/gcc/testsuite/gcc.target/arm/sat-1.c 2012-02-29 14:29:56 +0000 +@@ -0,0 +1,64 @@ ++/* { dg-do compile } */ ++/* { dg-require-effective-target arm_arm_ok } */ ++/* { dg-require-effective-target arm_arch_v6_ok } */ ++/* { dg-options "-O2 -marm" } */ ++/* { dg-add-options arm_arch_v6 } */ ++ ++ ++static inline int sat1 (int a, int amin, int amax) ++{ ++ if (a < amin) return amin; ++ else if (a > amax) return amax; ++ else return a; ++} ++ ++static inline int sat2 (int a, int amin, int amax) ++{ ++ if (a > amax) return amax; ++ else if (a < amin) return amin; ++ else return a; ++} ++ ++int u1 (int x) ++{ ++ return sat1 (x, 0, 63); ++} ++ ++int us1 (int x) ++{ ++ return sat1 (x >> 5, 0, 63); ++} ++ ++int s1 (int x) ++{ ++ return sat1 (x, -64, 63); ++} ++ ++int ss1 (int x) ++{ ++ return sat1 (x >> 5, -64, 63); ++} ++ ++int u2 (int x) ++{ ++ return sat2 (x, 0, 63); ++} ++ ++int us2 (int x) ++{ ++ return sat2 (x >> 5, 0, 63); ++} ++ ++int s2 (int x) ++{ ++ return sat2 (x, -64, 63); ++} ++ ++int ss2 (int x) ++{ ++ return sat2 (x >> 5, -64, 63); ++} ++ ++/* { dg-final { scan-assembler-times "usat" 4 } } */ ++/* { dg-final { scan-assembler-times "ssat" 4 } } */ ++ + |