diff options
author | Khem Raj <raj.khem@gmail.com> | 2010-12-03 23:17:10 -0800 |
---|---|---|
committer | Khem Raj <raj.khem@gmail.com> | 2010-12-03 23:17:10 -0800 |
commit | 73085615dea4b640c5b4e29a4c15ef40c2c875a5 (patch) | |
tree | a711fe60ec64f991028df9bd318b92dba88510a2 /recipes/gcc | |
parent | d0fe619acf5f00f42bb3444b77a0660b465b17c1 (diff) | |
download | openembedded-73085615dea4b640c5b4e29a4c15ef40c2c875a5.tar.gz |
gcc-4.5: Apply linaro updates and upstream updates
Signed-off-by: Khem Raj <raj.khem@gmail.com>
Diffstat (limited to 'recipes/gcc')
-rw-r--r-- | recipes/gcc/gcc-4.5.inc | 11 | ||||
-rw-r--r-- | recipes/gcc/gcc-4.5/linaro/gcc-4.5-linaro-r99416.patch (renamed from recipes/gcc/gcc-4.5/gcc-linaro-fix-lp-653316.patch) | 25 | ||||
-rw-r--r-- | recipes/gcc/gcc-4.5/linaro/gcc-4.5-linaro-r99417.patch | 52 | ||||
-rw-r--r-- | recipes/gcc/gcc-4.5/linaro/gcc-4.5-linaro-r99418.patch | 24 | ||||
-rw-r--r-- | recipes/gcc/gcc-4.5/linaro/gcc-4.5-linaro-r99419.patch | 756 | ||||
-rw-r--r-- | recipes/gcc/gcc-4.5/linaro/gcc-4.5-linaro-r99420.patch (renamed from recipes/gcc/gcc-4.5/gcc-vmovl-PR45805.patch) | 20 |
6 files changed, 866 insertions, 22 deletions
diff --git a/recipes/gcc/gcc-4.5.inc b/recipes/gcc/gcc-4.5.inc index 30899807c0..8118b85533 100644 --- a/recipes/gcc/gcc-4.5.inc +++ b/recipes/gcc/gcc-4.5.inc @@ -8,9 +8,9 @@ DEPENDS = "mpfr gmp libmpc libelf" NATIVEDEPS = "mpfr-native gmp-native libmpc-native" -INC_PR = "r20" +INC_PR = "r21" -SRCREV = "166342" +SRCREV = "167449" PV = "4.5" # BINV should be incremented after updating to a revision # after a minor gcc release (e.g. 4.5.1 or 4.5.2) has been made @@ -131,9 +131,12 @@ SRC_URI = "svn://gcc.gnu.org/svn/gcc/branches;module=${BRANCH} \ file://linaro/gcc-4.5-linaro-r99413.patch \ file://linaro/gcc-4.5-linaro-r99414.patch \ file://linaro/gcc-4.5-linaro-r99415.patch \ - file://gcc-vmovl-PR45805.patch \ + file://linaro/gcc-4.5-linaro-r99416.patch \ + file://linaro/gcc-4.5-linaro-r99417.patch \ + file://linaro/gcc-4.5-linaro-r99418.patch \ + file://linaro/gcc-4.5-linaro-r99419.patch \ + file://linaro/gcc-4.5-linaro-r99420.patch \ file://gcc-scalar-widening-pr45847.patch \ - file://gcc-linaro-fix-lp-653316.patch \ " SRC_URI_append_mips64 = " file://mips64-nomultilib.patch " diff --git a/recipes/gcc/gcc-4.5/gcc-linaro-fix-lp-653316.patch b/recipes/gcc/gcc-4.5/linaro/gcc-4.5-linaro-r99416.patch index 72a221b1d2..3697bc95b0 100644 --- a/recipes/gcc/gcc-4.5/gcc-linaro-fix-lp-653316.patch +++ b/recipes/gcc/gcc-4.5/linaro/gcc-4.5-linaro-r99416.patch @@ -14,11 +14,9 @@ * gcc.dg/20101010-1.c: New testcase. === modified file 'gcc/ifcvt.c' -Index: gcc-4.5/gcc/ifcvt.c -=================================================================== ---- gcc-4.5.orig/gcc/ifcvt.c -+++ gcc-4.5/gcc/ifcvt.c -@@ -88,6 +88,8 @@ static int count_bb_insns (const_basic_b +--- a/gcc/ifcvt.c 2010-10-04 00:50:43 +0000 ++++ b/gcc/ifcvt.c 2010-10-15 10:01:07 +0000 +@@ -88,6 +88,8 @@ static bool cheap_bb_rtx_cost_p (const_basic_block, int); static rtx first_active_insn (basic_block); static rtx last_active_insn (basic_block, int); @@ -27,7 +25,7 @@ Index: gcc-4.5/gcc/ifcvt.c static basic_block block_fallthru (basic_block); static int cond_exec_process_insns (ce_if_block_t *, rtx, rtx, rtx, rtx, int); static rtx cond_exec_get_condition (rtx); -@@ -230,6 +232,48 @@ last_active_insn (basic_block bb, int sk +@@ -230,6 +232,48 @@ return insn; } @@ -76,7 +74,7 @@ Index: gcc-4.5/gcc/ifcvt.c /* Return the basic block reached by falling though the basic block BB. */ static basic_block -@@ -448,9 +492,9 @@ cond_exec_process_if_block (ce_if_block_ +@@ -448,9 +492,9 @@ if (n_matching > 0) { if (then_end) @@ -88,7 +86,7 @@ Index: gcc-4.5/gcc/ifcvt.c n_insns -= 2 * n_matching; } -@@ -488,9 +532,9 @@ cond_exec_process_if_block (ce_if_block_ +@@ -488,9 +532,9 @@ if (n_matching > 0) { if (then_start) @@ -100,7 +98,7 @@ Index: gcc-4.5/gcc/ifcvt.c n_insns -= 2 * n_matching; } } -@@ -646,7 +690,7 @@ cond_exec_process_if_block (ce_if_block_ +@@ -646,7 +690,7 @@ { rtx from = then_first_tail; if (!INSN_P (from)) @@ -109,10 +107,10 @@ Index: gcc-4.5/gcc/ifcvt.c delete_insn_chain (from, BB_END (then_bb), false); } if (else_last_head) -Index: gcc-4.5/gcc/testsuite/gcc.dg/20101010-1.c -=================================================================== ---- /dev/null -+++ gcc-4.5/gcc/testsuite/gcc.dg/20101010-1.c + +=== added file 'gcc/testsuite/gcc.dg/20101010-1.c' +--- a/gcc/testsuite/gcc.dg/20101010-1.c 1970-01-01 00:00:00 +0000 ++++ b/gcc/testsuite/gcc.dg/20101010-1.c 2010-10-15 10:01:07 +0000 @@ -0,0 +1,14 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fno-crossjumping" } */ @@ -128,3 +126,4 @@ Index: gcc-4.5/gcc/testsuite/gcc.dg/20101010-1.c + } + return -1; +} + diff --git a/recipes/gcc/gcc-4.5/linaro/gcc-4.5-linaro-r99417.patch b/recipes/gcc/gcc-4.5/linaro/gcc-4.5-linaro-r99417.patch new file mode 100644 index 0000000000..6df93a043a --- /dev/null +++ b/recipes/gcc/gcc-4.5/linaro/gcc-4.5-linaro-r99417.patch @@ -0,0 +1,52 @@ +2010-10-15 Jie Zhang <jie@codesourcery.com> + + Backport from mainline: + + gcc/testsuite/ + 2010-10-15 Jie Zhang <jie@codesourcery.com> + + * lib/lto.exp (lto-link-and-maybe-run): Use the default linker + script when relocatable linking. + +=== modified file 'gcc/testsuite/lib/lto.exp' +--- a/gcc/testsuite/lib/lto.exp 2010-06-29 15:35:54 +0000 ++++ b/gcc/testsuite/lib/lto.exp 2010-10-15 16:08:25 +0000 +@@ -156,6 +156,7 @@ + global testcase + global tool + global compile_type ++ global board_info + + # Check that all of the objects were built successfully. + foreach obj [split $objlist] { +@@ -170,10 +171,29 @@ + set options "" + lappend options "additional_flags=$optall $optfile" + ++ set target_board [target_info name] ++ set relocatable 0 ++ ++ # Some LTO tests do relocatable linking. Some target boards set ++ # a linker script which can't be used for relocatable linking. ++ # Use the default linker script instead. ++ if { [lsearch -exact [split "$optall $optfile"] "-r"] >= 0 } { ++ set relocatable 1 ++ } ++ ++ if { $relocatable } { ++ set saved_ldscript [board_info $target_board ldscript] ++ set board_info($target_board,ldscript) "" ++ } ++ + # Link the objects into an executable. + set comp_output [${tool}_target_compile "$objlist" $dest executable \ + "$options"] + ++ if { $relocatable } { ++ set board_info($target_board,ldscript) $saved_ldscript ++ } ++ + # Prune unimportant visibility warnings before checking output. + set comp_output [lto_prune_warns $comp_output] + + diff --git a/recipes/gcc/gcc-4.5/linaro/gcc-4.5-linaro-r99418.patch b/recipes/gcc/gcc-4.5/linaro/gcc-4.5-linaro-r99418.patch new file mode 100644 index 0000000000..ebda1cd231 --- /dev/null +++ b/recipes/gcc/gcc-4.5/linaro/gcc-4.5-linaro-r99418.patch @@ -0,0 +1,24 @@ +2010-10-20 Yao Qi <yao@codesourcery.com> + + Merge from Sourcery G++ to fix LP:660021 + 2010-10-18 Paul Brook <paul@codesourcery.com> + + * tree-vect-stmts.c (supportable_widening_operation): Check if wide + vector type exists. + +=== modified file 'gcc/tree-vect-stmts.c' +--- a/gcc/tree-vect-stmts.c 2010-07-23 15:51:08 +0000 ++++ b/gcc/tree-vect-stmts.c 2010-10-20 16:52:04 +0000 +@@ -4650,6 +4650,11 @@ + tree wide_vectype = get_vectype_for_scalar_type (type); + enum tree_code c1, c2; + ++ /* Check we have a valid vector type for the result. */ ++ if (!wide_vectype) ++ return false; ++ ++ + /* The result of a vectorized widening operation usually requires two vectors + (because the widened results do not fit int one vector). The generated + vector results would normally be expected to be generated in the same + diff --git a/recipes/gcc/gcc-4.5/linaro/gcc-4.5-linaro-r99419.patch b/recipes/gcc/gcc-4.5/linaro/gcc-4.5-linaro-r99419.patch new file mode 100644 index 0000000000..f5267c743b --- /dev/null +++ b/recipes/gcc/gcc-4.5/linaro/gcc-4.5-linaro-r99419.patch @@ -0,0 +1,756 @@ +2010-10-22 Julian Brown <julian@codesourcery.com> + + Backport from mainline: + + 2010-10-18 Marcus Shawcroft <marcus.shawcroft@arm.com> + + gcc/testsuite/ + * gcc.target/arm/synchronize.c: Permit dmb or mcr in assembler scan. + +2010-10-14 Julian Brown <julian@codesourcery.com> + + Backport from mainline: + + 2010-08-18 Marcus Shawcroft <marcus.shawcroft@arm.com> + + gcc/ + * config/arm/arm-protos.h (arm_expand_sync): New. + (arm_output_memory_barrier, arm_output_sync_insn): New. + (arm_sync_loop_insns): New. + * config/arm/arm.c (FL_ARCH7): New. + (FL_FOR_ARCH7): Include FL_ARCH7. + (arm_arch7): New. + (arm_print_operand): Support %C markup. + (arm_legitimize_sync_memory): New. + (arm_emit, arm_insn_count, arm_count, arm_output_asm_insn): New. + (arm_process_output_memory_barrier, arm_output_memory_barrier): New. + (arm_ldrex_suffix, arm_output_ldrex, arm_output_strex): New. + (arm_output_op2, arm_output_op3, arm_output_sync_loop): New. + (arm_get_sync_operand, FETCH_SYNC_OPERAND): New. + (arm_process_output_sync_insn, arm_output_sync_insn): New. + (arm_sync_loop_insns,arm_call_generator, arm_expand_sync): New. + * config/arm/arm.h (struct arm_sync_generator): New. + (TARGET_HAVE_DMB, TARGET_HAVE_DMB_MCR): New. + (TARGET_HAVE_MEMORY_BARRIER): New. + (TARGET_HAVE_LDREX, TARGET_HAVE_LDREXBHD): New. + * config/arm/arm.md: Include sync.md. + (UNSPEC_MEMORY_BARRIER): New. + (VUNSPEC_SYNC_COMPARE_AND_SWAP, VUNSPEC_SYNC_LOCK): New. + (VUNSPEC_SYNC_OP):New. + (VUNSPEC_SYNC_NEW_OP, VUNSPEC_SYNC_OLD_OP): New. + (sync_result, sync_memory, sync_required_value): New attributes. + (sync_new_value, sync_t1, sync_t2): Likewise. + (sync_release_barrier, sync_op): Likewise. + (length): Add logic to length attribute defintion to call + arm_sync_loop_insns when appropriate. + * config/arm/sync.md: New file. + + 2010-09-02 Marcus Shawcroft <marcus.shawcroft@arm.com> + + gcc/ + * config/arm/predicates.md (arm_sync_memory_operand): New. + * config/arm/sync.md (arm_sync_compare_and_swapsi): Change predicate + to arm_sync_memory_operand and constraint to Q. + (arm_sync_compare_and_swap<mode>): Likewise. + (arm_sync_compare_and_swap<mode>): Likewise. + (arm_sync_lock_test_and_setsi): Likewise. + (arm_sync_lock_test_and_set<mode>): Likewise. + (arm_sync_new_<sync_optab>si): Likewise. + (arm_sync_new_nandsi): Likewise. + (arm_sync_new_<sync_optab><mode>): Likewise. + (arm_sync_new_nand<mode>): Likewise. + (arm_sync_old_<sync_optab>si): Likewise. + (arm_sync_old_nandsi): Likewise. + (arm_sync_old_<sync_optab><mode>): Likewise. + (arm_sync_old_nand<mode>): Likewise. + + 2010-09-13 Marcus Shawcroft <marcus.shawcroft@arm.com> + + gcc/ + * config/arm/arm.md: (define_attr "conds"): Update comment. + * config/arm/sync.md (arm_sync_compare_and_swapsi): Change + conds attribute to clob. + (arm_sync_compare_and_swapsi): Likewise. + (arm_sync_compare_and_swap<mode>): Likewise. + (arm_sync_lock_test_and_setsi): Likewise. + (arm_sync_lock_test_and_set<mode>): Likewise. + (arm_sync_new_<sync_optab>si): Likewise. + (arm_sync_new_nandsi): Likewise. + (arm_sync_new_<sync_optab><mode>): Likewise. + (arm_sync_new_nand<mode>): Likewise. + (arm_sync_old_<sync_optab>si): Likewise. + (arm_sync_old_nandsi): Likewise. + (arm_sync_old_<sync_optab><mode>): Likewise. + (arm_sync_old_nand<mode>): Likewise. + + 2010-09-13 Marcus Shawcroft <marcus.shawcroft@arm.com> + + gcc/testsuite/ + * gcc.target/arm/sync-1.c: New. + + 2010-10-20 Yao Qi <yao@codesourcery.com> + + Merge from Sourcery G++ to fix LP:660021 +@@ -110,22 +200,56 @@ + + Backport from FSF: + +- 2010-08-07 Marcus Shawcroft <marcus.shawcroft@arm.com> +- +- gcc/ +- * config/arm/linux-atomic.c (SUBWORD_VAL_CAS): Instantiate with +- 'unsigned short' and 'unsigned char' instead of 'short' and +- 'char'. (SUBWORD_BOOL_CAS): Likewise. +- (SUBWORD_SYNC_OP): Likewise. +- (SUBWORD_TEST_AND_SET): Likewise. +- (FETCH_AND_OP_WORD): Parenthesise INF_OP +- (SUBWORD_SYNC_OP): Likewise. +- (OP_AND_FETCH_WORD): Likewise. +- +- gcc/testsuite/ +- * lib/target-supports.exp: (check_effective_target_sync_int_long): +- Add arm*-*-linux-gnueabi. +- (check_effective_target_sync_char_short): Likewise. ++ gcc/ ++ 2010-08-18 Marcus Shawcroft <marcus.shawcroft@arm.com> ++ * config/arm/arm-protos.h (arm_expand_sync): New. ++ (arm_output_memory_barrier, arm_output_sync_insn): New. ++ (arm_sync_loop_insns): New. ++ * config/arm/arm.c (FL_ARCH7): New. ++ (FL_FOR_ARCH7): Include FL_ARCH7. ++ (arm_arch7): New. ++ (arm_print_operand): Support %C markup. ++ (arm_legitimize_sync_memory): New. ++ (arm_emit, arm_insn_count, arm_count, arm_output_asm_insn): New. ++ (arm_process_output_memory_barrier, arm_output_memory_barrier): New. ++ (arm_ldrex_suffix, arm_output_ldrex, arm_output_strex): New. ++ (arm_output_op2, arm_output_op3, arm_output_sync_loop): New. ++ (arm_get_sync_operand, FETCH_SYNC_OPERAND): New. ++ (arm_process_output_sync_insn, arm_output_sync_insn): New. ++ (arm_sync_loop_insns,arm_call_generator, arm_expand_sync): New. ++ * config/arm/arm.h (struct arm_sync_generator): New. ++ (TARGET_HAVE_DMB, TARGET_HAVE_DMB_MCR): New. ++ (TARGET_HAVE_MEMORY_BARRIER): New. ++ (TARGET_HAVE_LDREX, TARGET_HAVE_LDREXBHD): New. ++ * config/arm/arm.md: Include sync.md. ++ (UNSPEC_MEMORY_BARRIER): New. ++ (VUNSPEC_SYNC_COMPARE_AND_SWAP, VUNSPEC_SYNC_LOCK): New. ++ (VUNSPEC_SYNC_OP):New. ++ (VUNSPEC_SYNC_NEW_OP, VUNSPEC_SYNC_OLD_OP): New. ++ (sync_result, sync_memory, sync_required_value): New attributes. ++ (sync_new_value, sync_t1, sync_t2): Likewise. ++ (sync_release_barrier, sync_op): Likewise. ++ (length): Add logic to length attribute defintion to call ++ arm_sync_loop_insns when appropriate. ++ * config/arm/sync.md: New file. ++ ++ gcc/ ++ 2010-09-02 Marcus Shawcroft <marcus.shawcroft@arm.com> ++ * config/arm/predicates.md (arm_sync_memory_operand): New. ++ * config/arm/sync.md (arm_sync_compare_and_swapsi): Change predicate ++ to arm_sync_memory_operand and constraint to Q. ++ (arm_sync_compare_and_swap<mode>): Likewise. ++ (arm_sync_compare_and_swap<mode>): Likewise. ++ (arm_sync_lock_test_and_setsi): Likewise. ++ (arm_sync_lock_test_and_set<mode>): Likewise. ++ (arm_sync_new_<sync_optab>si): Likewise. ++ (arm_sync_new_nandsi): Likewise. ++ (arm_sync_new_<sync_optab><mode>): Likewise. ++ (arm_sync_new_nand<mode>): Likewise. ++ (arm_sync_old_<sync_optab>si): Likewise. ++ (arm_sync_old_nandsi): Likewise. ++ (arm_sync_old_<sync_optab><mode>): Likewise. ++ (arm_sync_old_nand<mode>): Likewise. + + 2010-09-30 Jie Zhang <jie@codesourcery.com> + + +=== modified file 'gcc/config/arm/arm-protos.h' +--- a/gcc/config/arm/arm-protos.h 2010-10-14 11:33:26 +0000 ++++ b/gcc/config/arm/arm-protos.h 2010-11-04 10:45:05 +0000 +@@ -151,6 +151,11 @@ + extern void arm_set_return_address (rtx, rtx); + extern int arm_eliminable_register (rtx); + extern const char *arm_output_shift(rtx *, int); ++extern void arm_expand_sync (enum machine_mode, struct arm_sync_generator *, ++ rtx, rtx, rtx, rtx); ++extern const char *arm_output_memory_barrier (rtx *); ++extern const char *arm_output_sync_insn (rtx, rtx *); ++extern unsigned int arm_sync_loop_insns (rtx , rtx *); + + extern bool arm_output_addr_const_extra (FILE *, rtx); + + +=== modified file 'gcc/config/arm/arm.c' +--- a/gcc/config/arm/arm.c 2010-10-15 06:01:22 +0000 ++++ b/gcc/config/arm/arm.c 2010-11-04 10:45:05 +0000 +@@ -602,6 +602,7 @@ + #define FL_NEON (1 << 20) /* Neon instructions. */ + #define FL_ARCH7EM (1 << 21) /* Instructions present in the ARMv7E-M + architecture. */ ++#define FL_ARCH7 (1 << 22) /* Architecture 7. */ + + #define FL_IWMMXT (1 << 29) /* XScale v2 or "Intel Wireless MMX technology". */ + +@@ -626,7 +627,7 @@ + #define FL_FOR_ARCH6ZK FL_FOR_ARCH6K + #define FL_FOR_ARCH6T2 (FL_FOR_ARCH6 | FL_THUMB2) + #define FL_FOR_ARCH6M (FL_FOR_ARCH6 & ~FL_NOTM) +-#define FL_FOR_ARCH7 (FL_FOR_ARCH6T2 &~ FL_NOTM) ++#define FL_FOR_ARCH7 ((FL_FOR_ARCH6T2 & ~FL_NOTM) | FL_ARCH7) + #define FL_FOR_ARCH7A (FL_FOR_ARCH7 | FL_NOTM | FL_ARCH6K) + #define FL_FOR_ARCH7R (FL_FOR_ARCH7A | FL_DIV) + #define FL_FOR_ARCH7M (FL_FOR_ARCH7 | FL_DIV) +@@ -664,6 +665,9 @@ + /* Nonzero if this chip supports the ARM 6K extensions. */ + int arm_arch6k = 0; + ++/* Nonzero if this chip supports the ARM 7 extensions. */ ++int arm_arch7 = 0; ++ + /* Nonzero if instructions not present in the 'M' profile can be used. */ + int arm_arch_notm = 0; + +@@ -1602,6 +1606,7 @@ + arm_arch6 = (insn_flags & FL_ARCH6) != 0; + arm_arch6k = (insn_flags & FL_ARCH6K) != 0; + arm_arch_notm = (insn_flags & FL_NOTM) != 0; ++ arm_arch7 = (insn_flags & FL_ARCH7) != 0; + arm_arch7em = (insn_flags & FL_ARCH7EM) != 0; + arm_arch_thumb2 = (insn_flags & FL_THUMB2) != 0; + arm_arch_xscale = (insn_flags & FL_XSCALE) != 0; +@@ -16562,6 +16567,17 @@ + } + return; + ++ case 'C': ++ { ++ rtx addr; ++ ++ gcc_assert (GET_CODE (x) == MEM); ++ addr = XEXP (x, 0); ++ gcc_assert (GET_CODE (addr) == REG); ++ asm_fprintf (stream, "[%r]", REGNO (addr)); ++ } ++ return; ++ + /* Translate an S register number into a D register number and element index. */ + case 'y': + { +@@ -22793,4 +22809,372 @@ + is_packed); + } + ++/* Legitimize a memory reference for sync primitive implemented using ++ ldrex / strex. We currently force the form of the reference to be ++ indirect without offset. We do not yet support the indirect offset ++ addressing supported by some ARM targets for these ++ instructions. */ ++static rtx ++arm_legitimize_sync_memory (rtx memory) ++{ ++ rtx addr = force_reg (Pmode, XEXP (memory, 0)); ++ rtx legitimate_memory = gen_rtx_MEM (GET_MODE (memory), addr); ++ ++ set_mem_alias_set (legitimate_memory, ALIAS_SET_MEMORY_BARRIER); ++ MEM_VOLATILE_P (legitimate_memory) = MEM_VOLATILE_P (memory); ++ return legitimate_memory; ++} ++ ++/* An instruction emitter. */ ++typedef void (* emit_f) (int label, const char *, rtx *); ++ ++/* An instruction emitter that emits via the conventional ++ output_asm_insn. */ ++static void ++arm_emit (int label ATTRIBUTE_UNUSED, const char *pattern, rtx *operands) ++{ ++ output_asm_insn (pattern, operands); ++} ++ ++/* Count the number of emitted synchronization instructions. */ ++static unsigned arm_insn_count; ++ ++/* An emitter that counts emitted instructions but does not actually ++ emit instruction into the the instruction stream. */ ++static void ++arm_count (int label, ++ const char *pattern ATTRIBUTE_UNUSED, ++ rtx *operands ATTRIBUTE_UNUSED) ++{ ++ if (! label) ++ ++ arm_insn_count; ++} ++ ++/* Construct a pattern using conventional output formatting and feed ++ it to output_asm_insn. Provides a mechanism to construct the ++ output pattern on the fly. Note the hard limit on the pattern ++ buffer size. */ ++static void ++arm_output_asm_insn (emit_f emit, int label, rtx *operands, ++ const char *pattern, ...) ++{ ++ va_list ap; ++ char buffer[256]; ++ ++ va_start (ap, pattern); ++ vsprintf (buffer, pattern, ap); ++ va_end (ap); ++ emit (label, buffer, operands); ++} ++ ++/* Emit the memory barrier instruction, if any, provided by this ++ target to a specified emitter. */ ++static void ++arm_process_output_memory_barrier (emit_f emit, rtx *operands) ++{ ++ if (TARGET_HAVE_DMB) ++ { ++ /* Note we issue a system level barrier. We should consider ++ issuing a inner shareabilty zone barrier here instead, ie. ++ "DMB ISH". */ ++ emit (0, "dmb\tsy", operands); ++ return; ++ } ++ ++ if (TARGET_HAVE_DMB_MCR) ++ { ++ emit (0, "mcr\tp15, 0, r0, c7, c10, 5", operands); ++ return; ++ } ++ ++ gcc_unreachable (); ++} ++ ++/* Emit the memory barrier instruction, if any, provided by this ++ target. */ ++const char * ++arm_output_memory_barrier (rtx *operands) ++{ ++ arm_process_output_memory_barrier (arm_emit, operands); ++ return ""; ++} ++ ++/* Helper to figure out the instruction suffix required on ldrex/strex ++ for operations on an object of the specified mode. */ ++static const char * ++arm_ldrex_suffix (enum machine_mode mode) ++{ ++ switch (mode) ++ { ++ case QImode: return "b"; ++ case HImode: return "h"; ++ case SImode: return ""; ++ case DImode: return "d"; ++ default: ++ gcc_unreachable (); ++ } ++ return ""; ++} ++ ++/* Emit an ldrex{b,h,d, } instruction appropriate for the specified ++ mode. */ ++static void ++arm_output_ldrex (emit_f emit, ++ enum machine_mode mode, ++ rtx target, ++ rtx memory) ++{ ++ const char *suffix = arm_ldrex_suffix (mode); ++ rtx operands[2]; ++ ++ operands[0] = target; ++ operands[1] = memory; ++ arm_output_asm_insn (emit, 0, operands, "ldrex%s\t%%0, %%C1", suffix); ++} ++ ++/* Emit a strex{b,h,d, } instruction appropriate for the specified ++ mode. */ ++static void ++arm_output_strex (emit_f emit, ++ enum machine_mode mode, ++ const char *cc, ++ rtx result, ++ rtx value, ++ rtx memory) ++{ ++ const char *suffix = arm_ldrex_suffix (mode); ++ rtx operands[3]; ++ ++ operands[0] = result; ++ operands[1] = value; ++ operands[2] = memory; ++ arm_output_asm_insn (emit, 0, operands, "strex%s%s\t%%0, %%1, %%C2", suffix, ++ cc); ++} ++ ++/* Helper to emit a two operand instruction. */ ++static void ++arm_output_op2 (emit_f emit, const char *mnemonic, rtx d, rtx s) ++{ ++ rtx operands[2]; ++ ++ operands[0] = d; ++ operands[1] = s; ++ arm_output_asm_insn (emit, 0, operands, "%s\t%%0, %%1", mnemonic); ++} ++ ++/* Helper to emit a three operand instruction. */ ++static void ++arm_output_op3 (emit_f emit, const char *mnemonic, rtx d, rtx a, rtx b) ++{ ++ rtx operands[3]; ++ ++ operands[0] = d; ++ operands[1] = a; ++ operands[2] = b; ++ arm_output_asm_insn (emit, 0, operands, "%s\t%%0, %%1, %%2", mnemonic); ++} ++ ++/* Emit a load store exclusive synchronization loop. ++ ++ do ++ old_value = [mem] ++ if old_value != required_value ++ break; ++ t1 = sync_op (old_value, new_value) ++ [mem] = t1, t2 = [0|1] ++ while ! t2 ++ ++ Note: ++ t1 == t2 is not permitted ++ t1 == old_value is permitted ++ ++ required_value: ++ ++ RTX register or const_int representing the required old_value for ++ the modify to continue, if NULL no comparsion is performed. */ ++static void ++arm_output_sync_loop (emit_f emit, ++ enum machine_mode mode, ++ rtx old_value, ++ rtx memory, ++ rtx required_value, ++ rtx new_value, ++ rtx t1, ++ rtx t2, ++ enum attr_sync_op sync_op, ++ int early_barrier_required) ++{ ++ rtx operands[1]; ++ ++ gcc_assert (t1 != t2); ++ ++ if (early_barrier_required) ++ arm_process_output_memory_barrier (emit, NULL); ++ ++ arm_output_asm_insn (emit, 1, operands, "%sLSYT%%=:", LOCAL_LABEL_PREFIX); ++ ++ arm_output_ldrex (emit, mode, old_value, memory); ++ ++ if (required_value) ++ { ++ rtx operands[2]; ++ ++ operands[0] = old_value; ++ operands[1] = required_value; ++ arm_output_asm_insn (emit, 0, operands, "cmp\t%%0, %%1"); ++ arm_output_asm_insn (emit, 0, operands, "bne\t%sLSYB%%=", LOCAL_LABEL_PREFIX); ++ } ++ ++ switch (sync_op) ++ { ++ case SYNC_OP_ADD: ++ arm_output_op3 (emit, "add", t1, old_value, new_value); ++ break; ++ ++ case SYNC_OP_SUB: ++ arm_output_op3 (emit, "sub", t1, old_value, new_value); ++ break; ++ ++ case SYNC_OP_IOR: ++ arm_output_op3 (emit, "orr", t1, old_value, new_value); ++ break; ++ ++ case SYNC_OP_XOR: ++ arm_output_op3 (emit, "eor", t1, old_value, new_value); ++ break; ++ ++ case SYNC_OP_AND: ++ arm_output_op3 (emit,"and", t1, old_value, new_value); ++ break; ++ ++ case SYNC_OP_NAND: ++ arm_output_op3 (emit, "and", t1, old_value, new_value); ++ arm_output_op2 (emit, "mvn", t1, t1); ++ break; ++ ++ case SYNC_OP_NONE: ++ t1 = new_value; ++ break; ++ } ++ ++ arm_output_strex (emit, mode, "", t2, t1, memory); ++ operands[0] = t2; ++ arm_output_asm_insn (emit, 0, operands, "teq\t%%0, #0"); ++ arm_output_asm_insn (emit, 0, operands, "bne\t%sLSYT%%=", LOCAL_LABEL_PREFIX); ++ ++ arm_process_output_memory_barrier (emit, NULL); ++ arm_output_asm_insn (emit, 1, operands, "%sLSYB%%=:", LOCAL_LABEL_PREFIX); ++} ++ ++static rtx ++arm_get_sync_operand (rtx *operands, int index, rtx default_value) ++{ ++ if (index > 0) ++ default_value = operands[index - 1]; ++ ++ return default_value; ++} ++ ++#define FETCH_SYNC_OPERAND(NAME, DEFAULT) \ ++ arm_get_sync_operand (operands, (int) get_attr_sync_##NAME (insn), DEFAULT); ++ ++/* Extract the operands for a synchroniztion instruction from the ++ instructions attributes and emit the instruction. */ ++static void ++arm_process_output_sync_insn (emit_f emit, rtx insn, rtx *operands) ++{ ++ rtx result, memory, required_value, new_value, t1, t2; ++ int early_barrier; ++ enum machine_mode mode; ++ enum attr_sync_op sync_op; ++ ++ result = FETCH_SYNC_OPERAND(result, 0); ++ memory = FETCH_SYNC_OPERAND(memory, 0); ++ required_value = FETCH_SYNC_OPERAND(required_value, 0); ++ new_value = FETCH_SYNC_OPERAND(new_value, 0); ++ t1 = FETCH_SYNC_OPERAND(t1, 0); ++ t2 = FETCH_SYNC_OPERAND(t2, 0); ++ early_barrier = ++ get_attr_sync_release_barrier (insn) == SYNC_RELEASE_BARRIER_YES; ++ sync_op = get_attr_sync_op (insn); ++ mode = GET_MODE (memory); ++ ++ arm_output_sync_loop (emit, mode, result, memory, required_value, ++ new_value, t1, t2, sync_op, early_barrier); ++} ++ ++/* Emit a synchronization instruction loop. */ ++const char * ++arm_output_sync_insn (rtx insn, rtx *operands) ++{ ++ arm_process_output_sync_insn (arm_emit, insn, operands); ++ return ""; ++} ++ ++/* Count the number of machine instruction that will be emitted for a ++ synchronization instruction. Note that the emitter used does not ++ emit instructions, it just counts instructions being carefull not ++ to count labels. */ ++unsigned int ++arm_sync_loop_insns (rtx insn, rtx *operands) ++{ ++ arm_insn_count = 0; ++ arm_process_output_sync_insn (arm_count, insn, operands); ++ return arm_insn_count; ++} ++ ++/* Helper to call a target sync instruction generator, dealing with ++ the variation in operands required by the different generators. */ ++static rtx ++arm_call_generator (struct arm_sync_generator *generator, rtx old_value, ++ rtx memory, rtx required_value, rtx new_value) ++{ ++ switch (generator->op) ++ { ++ case arm_sync_generator_omn: ++ gcc_assert (! required_value); ++ return generator->u.omn (old_value, memory, new_value); ++ ++ case arm_sync_generator_omrn: ++ gcc_assert (required_value); ++ return generator->u.omrn (old_value, memory, required_value, new_value); ++ } ++ ++ return NULL; ++} ++ ++/* Expand a synchronization loop. The synchronization loop is expanded ++ as an opaque block of instructions in order to ensure that we do ++ not subsequently get extraneous memory accesses inserted within the ++ critical region. The exclusive access property of ldrex/strex is ++ only guaranteed in there are no intervening memory accesses. */ ++void ++arm_expand_sync (enum machine_mode mode, ++ struct arm_sync_generator *generator, ++ rtx target, rtx memory, rtx required_value, rtx new_value) ++{ ++ if (target == NULL) ++ target = gen_reg_rtx (mode); ++ ++ memory = arm_legitimize_sync_memory (memory); ++ if (mode != SImode) ++ { ++ rtx load_temp = gen_reg_rtx (SImode); ++ ++ if (required_value) ++ required_value = convert_modes (SImode, mode, required_value, true); ++ ++ new_value = convert_modes (SImode, mode, new_value, true); ++ emit_insn (arm_call_generator (generator, load_temp, memory, ++ required_value, new_value)); ++ emit_move_insn (target, gen_lowpart (mode, load_temp)); ++ } ++ else ++ { ++ emit_insn (arm_call_generator (generator, target, memory, required_value, ++ new_value)); ++ } ++} ++ + #include "gt-arm.h" + +=== modified file 'gcc/config/arm/arm.h' +--- a/gcc/config/arm/arm.h 2010-10-15 10:44:40 +0000 ++++ b/gcc/config/arm/arm.h 2010-11-04 10:45:05 +0000 +@@ -128,6 +128,24 @@ + /* The processor for which instructions should be scheduled. */ + extern enum processor_type arm_tune; + ++enum arm_sync_generator_tag ++ { ++ arm_sync_generator_omn, ++ arm_sync_generator_omrn ++ }; ++ ++/* Wrapper to pass around a polymorphic pointer to a sync instruction ++ generator and. */ ++struct arm_sync_generator ++{ ++ enum arm_sync_generator_tag op; ++ union ++ { ++ rtx (* omn) (rtx, rtx, rtx); ++ rtx (* omrn) (rtx, rtx, rtx, rtx); ++ } u; ++}; ++ + typedef enum arm_cond_code + { + ARM_EQ = 0, ARM_NE, ARM_CS, ARM_CC, ARM_MI, ARM_PL, ARM_VS, ARM_VC, +@@ -272,6 +290,20 @@ + for Thumb-2. */ + #define TARGET_UNIFIED_ASM TARGET_THUMB2 + ++/* Nonzero if this chip provides the DMB instruction. */ ++#define TARGET_HAVE_DMB (arm_arch7) ++ ++/* Nonzero if this chip implements a memory barrier via CP15. */ ++#define TARGET_HAVE_DMB_MCR (arm_arch6k && ! TARGET_HAVE_DMB) ++ ++/* Nonzero if this chip implements a memory barrier instruction. */ ++#define TARGET_HAVE_MEMORY_BARRIER (TARGET_HAVE_DMB || TARGET_HAVE_DMB_MCR) ++ ++/* Nonzero if this chip supports ldrex and strex */ ++#define TARGET_HAVE_LDREX ((arm_arch6 && TARGET_ARM) || arm_arch7) ++ ++/* Nonzero if this chip supports ldrex{bhd} and strex{bhd}. */ ++#define TARGET_HAVE_LDREXBHD ((arm_arch6k && TARGET_ARM) || arm_arch7) + + /* True iff the full BPABI is being used. If TARGET_BPABI is true, + then TARGET_AAPCS_BASED must be true -- but the converse does not +@@ -405,6 +437,12 @@ + /* Nonzero if this chip supports the ARM Architecture 6 extensions. */ + extern int arm_arch6; + ++/* Nonzero if this chip supports the ARM Architecture 6k extensions. */ ++extern int arm_arch6k; ++ ++/* Nonzero if this chip supports the ARM Architecture 7 extensions. */ ++extern int arm_arch7; ++ + /* Nonzero if instructions not present in the 'M' profile can be used. */ + extern int arm_arch_notm; + + +=== modified file 'gcc/config/arm/arm.md' +--- a/gcc/config/arm/arm.md 2010-10-14 11:33:26 +0000 ++++ b/gcc/config/arm/arm.md 2010-11-04 10:45:05 +0000 +@@ -103,6 +103,7 @@ + (UNSPEC_RBIT 26) ; rbit operation. + (UNSPEC_SYMBOL_OFFSET 27) ; The offset of the start of the symbol from + ; another symbolic address. ++ (UNSPEC_MEMORY_BARRIER 28) ; Represent a memory barrier. + ] + ) + +@@ -139,6 +140,11 @@ + (VUNSPEC_ALIGN32 16) ; Used to force 32-byte alignment. + (VUNSPEC_EH_RETURN 20); Use to override the return address for exception + ; handling. ++ (VUNSPEC_SYNC_COMPARE_AND_SWAP 21) ; Represent an atomic compare swap. ++ (VUNSPEC_SYNC_LOCK 22) ; Represent a sync_lock_test_and_set. ++ (VUNSPEC_SYNC_OP 23) ; Represent a sync_<op> ++ (VUNSPEC_SYNC_NEW_OP 24) ; Represent a sync_new_<op> ++ (VUNSPEC_SYNC_OLD_OP 25) ; Represent a sync_old_<op> + ] + ) + +@@ -163,8 +169,21 @@ + (define_attr "fpu" "none,fpa,fpe2,fpe3,maverick,vfp" + (const (symbol_ref "arm_fpu_attr"))) + ++(define_attr "sync_result" "none,0,1,2,3,4,5" (const_string "none")) ++(define_attr "sync_memory" "none,0,1,2,3,4,5" (const_string "none")) ++(define_attr "sync_required_value" "none,0,1,2,3,4,5" (const_string "none")) ++(define_attr "sync_new_value" "none,0,1,2,3,4,5" (const_string "none")) ++(define_attr "sync_t1" "none,0,1,2,3,4,5" (const_string "none")) ++(define_attr "sync_t2" "none,0,1,2,3,4,5" (const_string "none")) ++(define_attr "sync_release_barrier" "yes,no" (const_string "yes")) ++(define_attr "sync_op" "none,add,sub,ior,xor,and,nand" ++ (const_string "none")) ++ + ; LENGTH of an instruction (in bytes) +-(define_attr "length" "" (const_int 4)) ++(define_attr "length" "" ++ (cond [(not (eq_attr "sync_memory" "none")) ++ (symbol_ref "arm_sync_loop_insns (insn, operands) * 4") ++ ] (const_int 4))) + + ; POOL_RANGE is how far away from a constant pool entry that this insn + ; can be placed. If the distance is zero, then this insn will never +@@ -11549,4 +11568,5 @@ + (include "thumb2.md") + ;; Neon patterns + (include "neon.md") +- ++;; Synchronization Primitives ++(include "sync.md") + +=== modified file 'gcc/config/arm/predicates.md' +--- a/gcc/config/arm/predicates.md 2010-10-14 11:33:26 +0000 ++++ b/gcc/config/arm/predicates.md 2010-11-04 10:45:05 +0000 +@@ -573,6 +573,11 @@ + (and (match_test "TARGET_32BIT") + (match_operand 0 "arm_di_operand")))) + ++;; True if the operand is memory reference suitable for a ldrex/strex. ++(define_predicate "arm_sync_memory_operand" ++ (and (match_operand 0 "memory_operand") ++ (match_code "reg" "0"))) ++ + ;; Predicates for parallel expanders based on mode. + (define_special_predicate "vect_par_constant_high" + (match_code "parallel") + +=== modified file 'gcc/testsuite/gcc.target/arm/synchronize.c' +--- a/gcc/testsuite/gcc.target/arm/synchronize.c 2009-08-12 14:55:19 +0000 ++++ b/gcc/testsuite/gcc.target/arm/synchronize.c 2010-11-04 10:45:05 +0000 +@@ -1,4 +1,4 @@ +-/* { dg-final { scan-assembler "__sync_synchronize" { target arm*-*-linux-*eabi } } } */ ++/* { dg-final { scan-assembler "__sync_synchronize|dmb|mcr" { target arm*-*-linux-*eabi } } } */ + + void *foo (void) + { + diff --git a/recipes/gcc/gcc-4.5/gcc-vmovl-PR45805.patch b/recipes/gcc/gcc-4.5/linaro/gcc-4.5-linaro-r99420.patch index e228cb754c..a2edc4b793 100644 --- a/recipes/gcc/gcc-4.5/gcc-vmovl-PR45805.patch +++ b/recipes/gcc/gcc-4.5/linaro/gcc-4.5-linaro-r99420.patch @@ -1,9 +1,18 @@ -Source: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=45805 +2010-10-18 Kazu Hirata <kazu@codesourcery.com> -Index: gcc-4.5/gcc/config/arm/neon.md -=================================================================== ---- gcc-4.5.orig/gcc/config/arm/neon.md 2010-09-28 12:04:38.000000000 -0700 -+++ gcc-4.5/gcc/config/arm/neon.md 2010-09-28 12:07:28.026227000 -0700 + Issue #9720 + Backport from mainline: + gcc/ + 2010-10-07 Tejas Belagod <tejas.belagod@arm.com> + * config/arm/neon.md (neon_unpack<US>_<mode>): Add 'w' to + constraint, add register specifier in instruction template. + (neon_vec_pack_trunc_<mode>): Likewise. + (neon_vec_<US>mult_<mode>): Add register specifier to + instruction template. + +=== modified file 'gcc/config/arm/neon.md' +--- a/gcc/config/arm/neon.md 2010-09-09 14:11:34 +0000 ++++ b/gcc/config/arm/neon.md 2010-11-04 11:47:50 +0000 @@ -5682,9 +5682,9 @@ ;; Vectorize for non-neon-quad case (define_insn "neon_unpack<US>_<mode>" @@ -25,3 +34,4 @@ Index: gcc-4.5/gcc/config/arm/neon.md [(set_attr "neon_type" "neon_shift_1")] ) + |