mirror of
https://github.com/openembedded/meta-openembedded.git
synced 2025-12-14 14:25:53 +01:00
gcc 4.5: sync with both OE and yocto
Signed-off-by: Koen Kooi <koen@dominion.thruhere.net>
This commit is contained in:
parent
8bb6722b13
commit
7eb7dce48b
|
|
@ -1,10 +1,18 @@
|
|||
require gcc-common.inc
|
||||
LICENSE = "GPLv3"
|
||||
|
||||
DEPENDS =+ "mpfr gmp libmpc elfutils"
|
||||
NATIVEDEPS = "mpfr-native gmp-native gettext-native libmpc-native elfutils-native"
|
||||
|
||||
SRCREV = "165931"
|
||||
LICENSE="GCC RUNTIME LIBRARY EXCEPTION & GPLv2 & GPLv3 & LGPLv2.1 & LGPLv3"
|
||||
|
||||
LIC_FILES_CHKSUM = "file://COPYING;md5=59530bdf33659b29e73d4adb9f9f6552 \
|
||||
file://COPYING3;md5=d32239bcb673463ab874e80d47fae504 \
|
||||
file://COPYING3.LIB;md5=6a6a8e020838b23406c81b19c1d46df6 \
|
||||
file://COPYING.LIB;md5=2d5025d4aa3495befef8f17206a5b0a1 \
|
||||
file://COPYING.RUNTIME;md5=fe60d87048567d4fe8c8a0ed2448bcc8"
|
||||
|
||||
|
||||
SRCREV = "167948"
|
||||
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
|
||||
|
|
@ -12,121 +20,144 @@ PV = "4.5"
|
|||
# 4.5.1 then the value below will be 2 which will mean 4.5.2
|
||||
# which will be next minor release and so on.
|
||||
|
||||
BINV = "${PV}.2"
|
||||
BINV = "${PV}.3"
|
||||
BRANCH = "gcc-4_5-branch"
|
||||
PR_append = "+svnr${SRCPV}"
|
||||
|
||||
|
||||
SRC_URI = "svn://gcc.gnu.org/svn/gcc/branches;module=${BRANCH} \
|
||||
file://gcc-4.3.1-ARCH_FLAGS_FOR_TARGET.patch \
|
||||
file://100-uclibc-conf.patch \
|
||||
file://gcc-uclibc-locale-ctype_touplow_t.patch \
|
||||
file://cache-amnesia.patch \
|
||||
file://gcc-flags-for-build.patch \
|
||||
file://libstdc++-emit-__cxa_end_cleanup-in-text.patch \
|
||||
file://arm-bswapsi2.patch \
|
||||
file://Makefile.in.patch \
|
||||
file://linaro/gcc-4.5-linaro-r99297.patch \
|
||||
file://linaro/gcc-4.5-linaro-r99298.patch \
|
||||
file://linaro/gcc-4.5-linaro-r99299.patch \
|
||||
file://linaro/gcc-4.5-linaro-r99300.patch \
|
||||
file://linaro/gcc-4.5-linaro-r99301.patch \
|
||||
file://linaro/gcc-4.5-linaro-r99302.patch \
|
||||
file://linaro/gcc-4.5-linaro-r99303.patch \
|
||||
file://linaro/gcc-4.5-linaro-r99304.patch \
|
||||
file://linaro/gcc-4.5-linaro-r99305.patch \
|
||||
file://linaro/gcc-4.5-linaro-r99306.patch \
|
||||
file://linaro/gcc-4.5-linaro-r99307.patch \
|
||||
file://linaro/gcc-4.5-linaro-r99308.patch \
|
||||
file://linaro/gcc-4.5-linaro-r99310.patch \
|
||||
file://linaro/gcc-4.5-linaro-r99312.patch \
|
||||
file://linaro/gcc-4.5-linaro-r99313.patch \
|
||||
file://linaro/gcc-4.5-linaro-r99314.patch \
|
||||
file://linaro/gcc-4.5-linaro-r99315.patch \
|
||||
file://linaro/gcc-4.5-linaro-r99316.patch \
|
||||
file://linaro/gcc-4.5-linaro-r99318.patch \
|
||||
file://linaro/gcc-4.5-linaro-r99319.patch \
|
||||
file://linaro/gcc-4.5-linaro-r99320.patch \
|
||||
file://linaro/gcc-4.5-linaro-r99321.patch \
|
||||
file://linaro/gcc-4.5-linaro-r99322.patch \
|
||||
file://linaro/gcc-4.5-linaro-r99323.patch \
|
||||
file://linaro/gcc-4.5-linaro-r99324.patch \
|
||||
file://linaro/gcc-4.5-linaro-r99325.patch \
|
||||
file://linaro/gcc-4.5-linaro-r99326.patch \
|
||||
file://linaro/gcc-4.5-linaro-r99327.patch \
|
||||
file://linaro/gcc-4.5-linaro-r99332.patch \
|
||||
file://linaro/gcc-4.5-linaro-r99335.patch \
|
||||
file://linaro/gcc-4.5-linaro-r99336.patch \
|
||||
file://linaro/gcc-4.5-linaro-r99337.patch \
|
||||
file://linaro/gcc-4.5-linaro-r99338.patch \
|
||||
file://linaro/gcc-4.5-linaro-r99339.patch \
|
||||
file://linaro/gcc-4.5-linaro-r99340.patch \
|
||||
file://linaro/gcc-4.5-linaro-r99341.patch \
|
||||
file://linaro/gcc-4.5-linaro-r99342.patch \
|
||||
file://linaro/gcc-4.5-linaro-r99343.patch \
|
||||
file://linaro/gcc-4.5-linaro-r99344.patch \
|
||||
file://linaro/gcc-4.5-linaro-r99345.patch \
|
||||
file://linaro/gcc-4.5-linaro-r99346.patch \
|
||||
file://linaro/gcc-4.5-linaro-r99347.patch \
|
||||
file://linaro/gcc-4.5-linaro-r99348.patch \
|
||||
file://linaro/gcc-4.5-linaro-r99349.patch \
|
||||
# file://linaro/gcc-4.5-linaro-r99350.patch \
|
||||
file://linaro/gcc-4.5-linaro-r99351.patch \
|
||||
file://linaro/gcc-4.5-linaro-r99352.patch \
|
||||
file://linaro/gcc-4.5-linaro-r99353.patch \
|
||||
file://linaro/gcc-4.5-linaro-r99354.patch \
|
||||
file://linaro/gcc-4.5-linaro-r99355.patch \
|
||||
file://linaro/gcc-4.5-linaro-r99356.patch \
|
||||
file://linaro/gcc-4.5-linaro-r99357.patch \
|
||||
file://linaro/gcc-4.5-linaro-r99358.patch \
|
||||
file://linaro/gcc-4.5-linaro-r99359.patch \
|
||||
file://linaro/gcc-4.5-linaro-r99360.patch \
|
||||
file://linaro/gcc-4.5-linaro-r99361.patch \
|
||||
file://linaro/gcc-4.5-linaro-r99363.patch \
|
||||
file://linaro/gcc-4.5-linaro-r99364.patch \
|
||||
file://linaro/gcc-4.5-linaro-r99365.patch \
|
||||
file://linaro/gcc-4.5-linaro-r99366.patch \
|
||||
file://linaro/gcc-4.5-linaro-r99367.patch \
|
||||
file://linaro/gcc-4.5-linaro-r99368.patch \
|
||||
file://linaro/gcc-4.5-linaro-r99369.patch \
|
||||
file://linaro/gcc-4.5-linaro-r99371.patch \
|
||||
file://linaro/gcc-4.5-linaro-r99372.patch \
|
||||
file://linaro/gcc-4.5-linaro-r99373.patch \
|
||||
file://linaro/gcc-4.5-linaro-r99374.patch \
|
||||
file://linaro/gcc-4.5-linaro-r99375.patch \
|
||||
file://linaro/gcc-4.5-linaro-r99376.patch \
|
||||
file://linaro/gcc-4.5-linaro-r99377.patch \
|
||||
file://linaro/gcc-4.5-linaro-r99378.patch \
|
||||
file://linaro/gcc-4.5-linaro-r99379.patch \
|
||||
file://linaro/gcc-4.5-linaro-r99380.patch \
|
||||
file://linaro/gcc-4.5-linaro-r99381.patch \
|
||||
file://linaro/gcc-4.5-linaro-r99383.patch \
|
||||
file://linaro/gcc-4.5-linaro-r99384.patch \
|
||||
file://linaro/gcc-4.5-linaro-r99385.patch \
|
||||
file://linaro/gcc-4.5-linaro-r99388.patch \
|
||||
file://linaro/gcc-4.5-linaro-r99391.patch \
|
||||
file://linaro/gcc-4.5-linaro-r99392.patch \
|
||||
file://linaro/gcc-4.5-linaro-r99393.patch \
|
||||
file://linaro/gcc-4.5-linaro-r99395.patch \
|
||||
file://linaro/gcc-4.5-linaro-r99396.patch \
|
||||
file://linaro/gcc-4.5-linaro-r99397.patch \
|
||||
file://linaro/gcc-4.5-linaro-r99398.patch \
|
||||
file://linaro/gcc-4.5-linaro-r99402.patch \
|
||||
file://linaro/gcc-4.5-linaro-r99403.patch \
|
||||
file://linaro/gcc-4.5-linaro-r99404.patch \
|
||||
file://linaro/gcc-4.5-linaro-r99405.patch \
|
||||
file://linaro/gcc-4.5-linaro-r99406.patch \
|
||||
file://linaro/gcc-4.5-linaro-r99407.patch \
|
||||
file://linaro/gcc-4.5-linaro-r99408.patch \
|
||||
file://linaro/gcc-4.5-linaro-r99409.patch \
|
||||
file://linaro/gcc-4.5-linaro-r99410.patch \
|
||||
file://linaro/gcc-4.5-linaro-r99411.patch \
|
||||
file://linaro/gcc-4.5-linaro-r99412.patch \
|
||||
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://gcc-scalar-widening-pr45847.patch \
|
||||
file://gcc-linaro-fix-lp-653316.patch \
|
||||
file://gcc-4.3.1-ARCH_FLAGS_FOR_TARGET.patch \
|
||||
file://100-uclibc-conf.patch \
|
||||
file://gcc-uclibc-locale-ctype_touplow_t.patch \
|
||||
file://cache-amnesia.patch \
|
||||
file://gcc-flags-for-build.patch \
|
||||
file://libstdc++-emit-__cxa_end_cleanup-in-text.patch \
|
||||
file://arm-bswapsi2.patch \
|
||||
file://Makefile.in.patch \
|
||||
file://gcc-armv4-pass-fix-v4bx-to-ld.patch \
|
||||
file://linaro/gcc-4.5-linaro-r99297.patch \
|
||||
file://linaro/gcc-4.5-linaro-r99298.patch \
|
||||
file://linaro/gcc-4.5-linaro-r99299.patch \
|
||||
file://linaro/gcc-4.5-linaro-r99300.patch \
|
||||
file://linaro/gcc-4.5-linaro-r99301.patch \
|
||||
file://linaro/gcc-4.5-linaro-r99302.patch \
|
||||
file://linaro/gcc-4.5-linaro-r99303.patch \
|
||||
file://linaro/gcc-4.5-linaro-r99304.patch \
|
||||
file://linaro/gcc-4.5-linaro-r99305.patch \
|
||||
file://linaro/gcc-4.5-linaro-r99306.patch \
|
||||
file://linaro/gcc-4.5-linaro-r99307.patch \
|
||||
file://linaro/gcc-4.5-linaro-r99308.patch \
|
||||
file://linaro/gcc-4.5-linaro-r99310.patch \
|
||||
file://linaro/gcc-4.5-linaro-r99312.patch \
|
||||
file://linaro/gcc-4.5-linaro-r99313.patch \
|
||||
file://linaro/gcc-4.5-linaro-r99314.patch \
|
||||
file://linaro/gcc-4.5-linaro-r99315.patch \
|
||||
file://linaro/gcc-4.5-linaro-r99316.patch \
|
||||
file://linaro/gcc-4.5-linaro-r99318.patch \
|
||||
file://linaro/gcc-4.5-linaro-r99319.patch \
|
||||
file://linaro/gcc-4.5-linaro-r99320.patch \
|
||||
file://linaro/gcc-4.5-linaro-r99321.patch \
|
||||
file://linaro/gcc-4.5-linaro-r99322.patch \
|
||||
file://linaro/gcc-4.5-linaro-r99323.patch \
|
||||
file://linaro/gcc-4.5-linaro-r99324.patch \
|
||||
file://linaro/gcc-4.5-linaro-r99325.patch \
|
||||
file://linaro/gcc-4.5-linaro-r99326.patch \
|
||||
file://linaro/gcc-4.5-linaro-r99327.patch \
|
||||
file://linaro/gcc-4.5-linaro-r99332.patch \
|
||||
file://linaro/gcc-4.5-linaro-r99335.patch \
|
||||
file://linaro/gcc-4.5-linaro-r99336.patch \
|
||||
file://linaro/gcc-4.5-linaro-r99337.patch \
|
||||
file://linaro/gcc-4.5-linaro-r99338.patch \
|
||||
file://linaro/gcc-4.5-linaro-r99339.patch \
|
||||
file://linaro/gcc-4.5-linaro-r99340.patch \
|
||||
file://linaro/gcc-4.5-linaro-r99341.patch \
|
||||
file://linaro/gcc-4.5-linaro-r99342.patch \
|
||||
file://linaro/gcc-4.5-linaro-r99343.patch \
|
||||
file://linaro/gcc-4.5-linaro-r99344.patch \
|
||||
file://linaro/gcc-4.5-linaro-r99345.patch \
|
||||
file://linaro/gcc-4.5-linaro-r99346.patch \
|
||||
file://linaro/gcc-4.5-linaro-r99347.patch \
|
||||
file://linaro/gcc-4.5-linaro-r99348.patch \
|
||||
file://linaro/gcc-4.5-linaro-r99349.patch \
|
||||
# file://linaro/gcc-4.5-linaro-r99350.patch \
|
||||
file://linaro/gcc-4.5-linaro-r99351.patch \
|
||||
file://linaro/gcc-4.5-linaro-r99352.patch \
|
||||
file://linaro/gcc-4.5-linaro-r99353.patch \
|
||||
file://linaro/gcc-4.5-linaro-r99354.patch \
|
||||
file://linaro/gcc-4.5-linaro-r99355.patch \
|
||||
file://linaro/gcc-4.5-linaro-r99356.patch \
|
||||
file://linaro/gcc-4.5-linaro-r99357.patch \
|
||||
file://linaro/gcc-4.5-linaro-r99358.patch \
|
||||
file://linaro/gcc-4.5-linaro-r99359.patch \
|
||||
file://linaro/gcc-4.5-linaro-r99360.patch \
|
||||
file://linaro/gcc-4.5-linaro-r99361.patch \
|
||||
file://linaro/gcc-4.5-linaro-r99363.patch \
|
||||
file://linaro/gcc-4.5-linaro-r99364.patch \
|
||||
file://linaro/gcc-4.5-linaro-r99365.patch \
|
||||
file://linaro/gcc-4.5-linaro-r99366.patch \
|
||||
file://linaro/gcc-4.5-linaro-r99367.patch \
|
||||
file://linaro/gcc-4.5-linaro-r99368.patch \
|
||||
file://linaro/gcc-4.5-linaro-r99369.patch \
|
||||
file://linaro/gcc-4.5-linaro-r99371.patch \
|
||||
file://linaro/gcc-4.5-linaro-r99372.patch \
|
||||
file://linaro/gcc-4.5-linaro-r99373.patch \
|
||||
file://linaro/gcc-4.5-linaro-r99374.patch \
|
||||
file://linaro/gcc-4.5-linaro-r99375.patch \
|
||||
file://linaro/gcc-4.5-linaro-r99376.patch \
|
||||
file://linaro/gcc-4.5-linaro-r99377.patch \
|
||||
file://linaro/gcc-4.5-linaro-r99378.patch \
|
||||
file://linaro/gcc-4.5-linaro-r99379.patch \
|
||||
file://linaro/gcc-4.5-linaro-r99380.patch \
|
||||
file://linaro/gcc-4.5-linaro-r99381.patch \
|
||||
file://linaro/gcc-4.5-linaro-r99383.patch \
|
||||
file://linaro/gcc-4.5-linaro-r99384.patch \
|
||||
file://linaro/gcc-4.5-linaro-r99385.patch \
|
||||
file://linaro/gcc-4.5-linaro-r99388.patch \
|
||||
file://linaro/gcc-4.5-linaro-r99391.patch \
|
||||
file://linaro/gcc-4.5-linaro-r99392.patch \
|
||||
file://linaro/gcc-4.5-linaro-r99393.patch \
|
||||
file://linaro/gcc-4.5-linaro-r99395.patch \
|
||||
file://linaro/gcc-4.5-linaro-r99396.patch \
|
||||
file://linaro/gcc-4.5-linaro-r99397.patch \
|
||||
file://linaro/gcc-4.5-linaro-r99398.patch \
|
||||
file://linaro/gcc-4.5-linaro-r99402.patch \
|
||||
file://linaro/gcc-4.5-linaro-r99403.patch \
|
||||
file://linaro/gcc-4.5-linaro-r99404.patch \
|
||||
file://linaro/gcc-4.5-linaro-r99405.patch \
|
||||
file://linaro/gcc-4.5-linaro-r99406.patch \
|
||||
file://linaro/gcc-4.5-linaro-r99407.patch \
|
||||
file://linaro/gcc-4.5-linaro-r99408.patch \
|
||||
file://linaro/gcc-4.5-linaro-r99409.patch \
|
||||
file://linaro/gcc-4.5-linaro-r99410.patch \
|
||||
file://linaro/gcc-4.5-linaro-r99411.patch \
|
||||
file://linaro/gcc-4.5-linaro-r99412.patch \
|
||||
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://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://linaro/gcc-4.5-linaro-r99421.patch \
|
||||
file://linaro/gcc-4.5-linaro-r99423.patch \
|
||||
file://linaro/gcc-4.5-linaro-r99424.patch \
|
||||
file://linaro/gcc-4.5-linaro-r99425.patch \
|
||||
file://linaro/gcc-4.5-linaro-r99426.patch \
|
||||
file://linaro/gcc-4.5-linaro-r99429.patch \
|
||||
file://linaro/gcc-4.5-linaro-r99432.patch \
|
||||
file://linaro/gcc-4.5-linaro-r99433.patch \
|
||||
file://linaro/gcc-4.5-linaro-r99434.patch \
|
||||
file://linaro/gcc-4.5-linaro-r99435.patch \
|
||||
file://linaro/gcc-4.5-linaro-r99436.patch \
|
||||
file://linaro/gcc-4.5-linaro-r99437.patch \
|
||||
file://linaro/gcc-4.5-linaro-r99439.patch \
|
||||
file://linaro/gcc-4.5-linaro-r99440.patch \
|
||||
file://linaro/gcc-4.5-linaro-r99441.patch \
|
||||
file://linaro/gcc-4.5-linaro-r99442.patch \
|
||||
file://linaro/gcc-4.5-linaro-r99443.patch \
|
||||
file://linaro/gcc-4.5-linaro-r99444.patch \
|
||||
file://gcc-scalar-widening-pr45847.patch \
|
||||
file://gcc-arm-qihi-split-PR46883.patch \
|
||||
\
|
||||
file://optional_libstdc.patch \
|
||||
file://64bithack.patch \
|
||||
|
|
|
|||
|
|
@ -0,0 +1,52 @@
|
|||
Backport of http://gcc.gnu.org/ml/gcc-patches/2010-12/msg01096.html
|
||||
This should fix the ICE found in samba
|
||||
|
||||
-Khem
|
||||
|
||||
Index: a/gcc/config/arm/arm.md
|
||||
===================================================================
|
||||
--- a/gcc/config/arm/arm.md (revision 167797)
|
||||
+++ b/gcc/config/arm/arm.md (working copy)
|
||||
@@ -4137,8 +4137,8 @@
|
||||
})
|
||||
|
||||
(define_split
|
||||
- [(set (match_operand:SI 0 "register_operand" "")
|
||||
- (zero_extend:SI (match_operand:HI 1 "register_operand" "")))]
|
||||
+ [(set (match_operand:SI 0 "s_register_operand" "")
|
||||
+ (zero_extend:SI (match_operand:HI 1 "s_register_operand" "")))]
|
||||
"!TARGET_THUMB2 && !arm_arch6"
|
||||
[(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 16)))
|
||||
(set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 16)))]
|
||||
@@ -4244,8 +4244,8 @@
|
||||
})
|
||||
|
||||
(define_split
|
||||
- [(set (match_operand:SI 0 "register_operand" "")
|
||||
- (zero_extend:SI (match_operand:QI 1 "register_operand" "")))]
|
||||
+ [(set (match_operand:SI 0 "s_register_operand" "")
|
||||
+ (zero_extend:SI (match_operand:QI 1 "s_register_operand" "")))]
|
||||
"!arm_arch6"
|
||||
[(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 24)))
|
||||
(set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 24)))]
|
||||
Index: a/gcc/testsuite/gcc.target/arm/pr46883.c
|
||||
===================================================================
|
||||
--- a/gcc/testsuite/gcc.target/arm/pr46883.c (revision 0)
|
||||
+++ b/gcc/testsuite/gcc.target/arm/pr46883.c (revision 0)
|
||||
@@ -0,0 +1,16 @@
|
||||
+/* { dg-do compile } */
|
||||
+/* { dg-options "-O1 -march=armv5te" } */
|
||||
+
|
||||
+void bar (unsigned char *q, unsigned short *data16s, int len)
|
||||
+{
|
||||
+ int i;
|
||||
+
|
||||
+ for (i = 0; i < len; i++)
|
||||
+ {
|
||||
+ q[2 * i] =
|
||||
+ (((data16s[i] & 0xFF) << 8) | ((data16s[i] >> 8) & 0xFF)) & 0xFF;
|
||||
+ q[2 * i + 1] =
|
||||
+ ((unsigned short)
|
||||
+ (((data16s[i] & 0xFF) << 8) | ((data16s[i] >> 8) & 0xFF))) >> 8;
|
||||
+ }
|
||||
+}
|
||||
|
|
@ -0,0 +1,29 @@
|
|||
The LINK_SPEC for linux gets overwritten by linux-eabi.h which
|
||||
means the value of TARGET_FIX_V4BX_SPEC gets lost and as a result
|
||||
the option is not passed to linker when chosing march=armv4
|
||||
This patch redefines this in linux-eabi.h and reinserts it
|
||||
for eabi defaulting toolchains.
|
||||
|
||||
We might want to send it upstream
|
||||
|
||||
-Khem
|
||||
Index: gcc-4.5/gcc/config/arm/linux-eabi.h
|
||||
===================================================================
|
||||
--- gcc-4.5.orig/gcc/config/arm/linux-eabi.h
|
||||
+++ gcc-4.5/gcc/config/arm/linux-eabi.h
|
||||
@@ -63,10 +63,14 @@
|
||||
#undef GLIBC_DYNAMIC_LINKER
|
||||
#define GLIBC_DYNAMIC_LINKER "/lib/ld-linux.so.3"
|
||||
|
||||
+/* For armv4 we pass --fix-v4bx to linker to support EABI */
|
||||
+#undef TARGET_FIX_V4BX_SPEC
|
||||
+#define TARGET_FIX_V4BX_SPEC " %{mcpu=arm8|mcpu=arm810|mcpu=strongarm*|march=armv4:--fix-v4bx}"
|
||||
+
|
||||
/* At this point, bpabi.h will have clobbered LINK_SPEC. We want to
|
||||
use the GNU/Linux version, not the generic BPABI version. */
|
||||
#undef LINK_SPEC
|
||||
-#define LINK_SPEC LINUX_TARGET_LINK_SPEC BE8_LINK_SPEC
|
||||
+#define LINK_SPEC LINUX_TARGET_LINK_SPEC BE8_LINK_SPEC TARGET_FIX_V4BX_SPEC
|
||||
|
||||
/* Use the default LIBGCC_SPEC, not the version in linux-elf.h, as we
|
||||
do not use -lfloat. */
|
||||
File diff suppressed because it is too large
Load Diff
130
recipes-devtools/gcc/gcc-4.5/linaro/gcc-4.5-linaro-r99416.patch
Normal file
130
recipes-devtools/gcc/gcc-4.5/linaro/gcc-4.5-linaro-r99416.patch
Normal file
|
|
@ -0,0 +1,130 @@
|
|||
2010-10-15 Chung-Lin Tang <cltang@codesourcery.com>
|
||||
|
||||
Backport from mainline:
|
||||
|
||||
2010-10-15 Chung-Lin Tang <cltang@codesourcery.com>
|
||||
|
||||
gcc/
|
||||
* ifcvt.c (find_active_insn_before): New function.
|
||||
(find_active_insn_after): New function.
|
||||
(cond_exec_process_if_block): Use new functions to replace
|
||||
prev_active_insn() and next_active_insn().
|
||||
|
||||
gcc/testsuite/
|
||||
* 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
|
||||
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);
|
||||
+static rtx find_active_insn_before (basic_block, rtx);
|
||||
+static rtx find_active_insn_after (basic_block, rtx);
|
||||
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
|
||||
return insn;
|
||||
}
|
||||
|
||||
+/* Return the active insn before INSN inside basic block CURR_BB. */
|
||||
+
|
||||
+static rtx
|
||||
+find_active_insn_before (basic_block curr_bb, rtx insn)
|
||||
+{
|
||||
+ if (!insn || insn == BB_HEAD (curr_bb))
|
||||
+ return NULL_RTX;
|
||||
+
|
||||
+ while ((insn = PREV_INSN (insn)) != NULL_RTX)
|
||||
+ {
|
||||
+ if (NONJUMP_INSN_P (insn) || JUMP_P (insn) || CALL_P (insn))
|
||||
+ break;
|
||||
+
|
||||
+ /* No other active insn all the way to the start of the basic block. */
|
||||
+ if (insn == BB_HEAD (curr_bb))
|
||||
+ return NULL_RTX;
|
||||
+ }
|
||||
+
|
||||
+ return insn;
|
||||
+}
|
||||
+
|
||||
+/* Return the active insn after INSN inside basic block CURR_BB. */
|
||||
+
|
||||
+static rtx
|
||||
+find_active_insn_after (basic_block curr_bb, rtx insn)
|
||||
+{
|
||||
+ if (!insn || insn == BB_END (curr_bb))
|
||||
+ return NULL_RTX;
|
||||
+
|
||||
+ while ((insn = NEXT_INSN (insn)) != NULL_RTX)
|
||||
+ {
|
||||
+ if (NONJUMP_INSN_P (insn) || JUMP_P (insn) || CALL_P (insn))
|
||||
+ break;
|
||||
+
|
||||
+ /* No other active insn all the way to the end of the basic block. */
|
||||
+ if (insn == BB_END (curr_bb))
|
||||
+ return NULL_RTX;
|
||||
+ }
|
||||
+
|
||||
+ return insn;
|
||||
+}
|
||||
+
|
||||
/* 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_
|
||||
if (n_matching > 0)
|
||||
{
|
||||
if (then_end)
|
||||
- then_end = prev_active_insn (then_first_tail);
|
||||
+ then_end = find_active_insn_before (then_bb, then_first_tail);
|
||||
if (else_end)
|
||||
- else_end = prev_active_insn (else_first_tail);
|
||||
+ else_end = find_active_insn_before (else_bb, else_first_tail);
|
||||
n_insns -= 2 * n_matching;
|
||||
}
|
||||
|
||||
@@ -488,9 +532,9 @@ cond_exec_process_if_block (ce_if_block_
|
||||
if (n_matching > 0)
|
||||
{
|
||||
if (then_start)
|
||||
- then_start = next_active_insn (then_last_head);
|
||||
+ then_start = find_active_insn_after (then_bb, then_last_head);
|
||||
if (else_start)
|
||||
- else_start = next_active_insn (else_last_head);
|
||||
+ else_start = find_active_insn_after (else_bb, else_last_head);
|
||||
n_insns -= 2 * n_matching;
|
||||
}
|
||||
}
|
||||
@@ -646,7 +690,7 @@ cond_exec_process_if_block (ce_if_block_
|
||||
{
|
||||
rtx from = then_first_tail;
|
||||
if (!INSN_P (from))
|
||||
- from = next_active_insn (from);
|
||||
+ from = find_active_insn_after (then_bb, from);
|
||||
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
|
||||
@@ -0,0 +1,14 @@
|
||||
+/* { dg-do compile } */
|
||||
+/* { dg-options "-O2 -fno-crossjumping" } */
|
||||
+
|
||||
+int foo (void)
|
||||
+{
|
||||
+ int len;
|
||||
+ if (bar1 (&len))
|
||||
+ {
|
||||
+ char devpath [len];
|
||||
+ if (bar2 (devpath) == len)
|
||||
+ return len;
|
||||
+ }
|
||||
+ return -1;
|
||||
+}
|
||||
|
|
@ -0,0 +1,53 @@
|
|||
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'
|
||||
Index: gcc-4.5/gcc/testsuite/lib/lto.exp
|
||||
===================================================================
|
||||
--- gcc-4.5.orig/gcc/testsuite/lib/lto.exp
|
||||
+++ gcc-4.5/gcc/testsuite/lib/lto.exp
|
||||
@@ -156,6 +156,7 @@ proc lto-link-and-maybe-run { testname o
|
||||
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 @@ proc lto-link-and-maybe-run { testname o
|
||||
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]
|
||||
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
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'
|
||||
Index: gcc-4.5/gcc/tree-vect-stmts.c
|
||||
===================================================================
|
||||
--- gcc-4.5.orig/gcc/tree-vect-stmts.c
|
||||
+++ gcc-4.5/gcc/tree-vect-stmts.c
|
||||
@@ -4867,6 +4867,11 @@ supportable_widening_operation (enum tre
|
||||
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
|
||||
734
recipes-devtools/gcc/gcc-4.5/linaro/gcc-4.5-linaro-r99419.patch
Normal file
734
recipes-devtools/gcc/gcc-4.5/linaro/gcc-4.5-linaro-r99419.patch
Normal file
|
|
@ -0,0 +1,734 @@
|
|||
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.
|
||||
|
||||
|
||||
Backport from FSF:
|
||||
|
||||
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.
|
||||
|
||||
=== modified file 'gcc/config/arm/arm-protos.h'
|
||||
Index: gcc-4.5/gcc/config/arm/arm-protos.h
|
||||
===================================================================
|
||||
--- gcc-4.5.orig/gcc/config/arm/arm-protos.h
|
||||
+++ gcc-4.5/gcc/config/arm/arm-protos.h
|
||||
@@ -151,6 +151,11 @@ extern const char *vfp_output_fstmd (rtx
|
||||
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);
|
||||
|
||||
Index: gcc-4.5/gcc/config/arm/arm.c
|
||||
===================================================================
|
||||
--- gcc-4.5.orig/gcc/config/arm/arm.c
|
||||
+++ gcc-4.5/gcc/config/arm/arm.c
|
||||
@@ -602,6 +602,7 @@ static int thumb_call_reg_needed;
|
||||
#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 @@ static int thumb_call_reg_needed;
|
||||
#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 @@ int arm_arch6 = 0;
|
||||
/* 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_override_options (void)
|
||||
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 @@ arm_print_operand (FILE *stream, rtx x,
|
||||
}
|
||||
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 @@ arm_builtin_support_vector_misalignment
|
||||
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"
|
||||
Index: gcc-4.5/gcc/config/arm/arm.h
|
||||
===================================================================
|
||||
--- gcc-4.5.orig/gcc/config/arm/arm.h
|
||||
+++ gcc-4.5/gcc/config/arm/arm.h
|
||||
@@ -128,6 +128,24 @@ enum target_cpus
|
||||
/* 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 @@ extern void (*arm_lang_output_object_att
|
||||
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 @@ extern int arm_arch5e;
|
||||
/* 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;
|
||||
|
||||
Index: gcc-4.5/gcc/config/arm/arm.md
|
||||
===================================================================
|
||||
--- gcc-4.5.orig/gcc/config/arm/arm.md
|
||||
+++ gcc-4.5/gcc/config/arm/arm.md
|
||||
@@ -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")
|
||||
Index: gcc-4.5/gcc/config/arm/predicates.md
|
||||
===================================================================
|
||||
--- gcc-4.5.orig/gcc/config/arm/predicates.md
|
||||
+++ gcc-4.5/gcc/config/arm/predicates.md
|
||||
@@ -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")
|
||||
Index: gcc-4.5/gcc/testsuite/gcc.target/arm/synchronize.c
|
||||
===================================================================
|
||||
--- gcc-4.5.orig/gcc/testsuite/gcc.target/arm/synchronize.c
|
||||
+++ gcc-4.5/gcc/testsuite/gcc.target/arm/synchronize.c
|
||||
@@ -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)
|
||||
{
|
||||
|
|
@ -0,0 +1,38 @@
|
|||
2010-10-18 Kazu Hirata <kazu@codesourcery.com>
|
||||
|
||||
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'
|
||||
Index: gcc-4.5/gcc/config/arm/neon.md
|
||||
===================================================================
|
||||
--- gcc-4.5.orig/gcc/config/arm/neon.md
|
||||
+++ gcc-4.5/gcc/config/arm/neon.md
|
||||
@@ -5682,9 +5682,9 @@
|
||||
;; Vectorize for non-neon-quad case
|
||||
(define_insn "neon_unpack<US>_<mode>"
|
||||
[(set (match_operand:<V_widen> 0 "register_operand" "=w")
|
||||
- (SE:<V_widen> (match_operand:VDI 1 "register_operand" "")))]
|
||||
+ (SE:<V_widen> (match_operand:VDI 1 "register_operand" "w")))]
|
||||
"TARGET_NEON"
|
||||
- "vmovl.<US><V_sz_elem> %q0, %1"
|
||||
+ "vmovl.<US><V_sz_elem> %q0, %P1"
|
||||
[(set_attr "neon_type" "neon_shift_1")]
|
||||
)
|
||||
|
||||
@@ -5721,7 +5721,7 @@
|
||||
(SE:<V_widen>
|
||||
(match_operand:VDI 2 "register_operand" "w"))))]
|
||||
"TARGET_NEON"
|
||||
- "vmull.<US><V_sz_elem> %q0, %1, %2"
|
||||
+ "vmull.<US><V_sz_elem> %q0, %P1, %P2"
|
||||
[(set_attr "neon_type" "neon_shift_1")]
|
||||
)
|
||||
|
||||
|
|
@ -0,0 +1,94 @@
|
|||
2010-10-20 Nathan Froyd <froydnj@codesourcery.com>
|
||||
|
||||
Issue #9781
|
||||
|
||||
Backport from mainline:
|
||||
|
||||
gcc/
|
||||
2010-10-20 Nathan Froyd <froydnj@codesourcery.com>
|
||||
|
||||
* ifcvt.c (noce_emit_cmove): If both of the values are SUBREGs, try
|
||||
emitting the conditional move in the inner mode of the SUBREG.
|
||||
|
||||
|
||||
=== modified file 'gcc/ifcvt.c'
|
||||
--- old/gcc/ifcvt.c 2010-10-15 10:01:07 +0000
|
||||
+++ new/gcc/ifcvt.c 2010-11-04 12:11:15 +0000
|
||||
@@ -1338,6 +1338,9 @@
|
||||
noce_emit_cmove (struct noce_if_info *if_info, rtx x, enum rtx_code code,
|
||||
rtx cmp_a, rtx cmp_b, rtx vfalse, rtx vtrue)
|
||||
{
|
||||
+ rtx target;
|
||||
+ int unsignedp;
|
||||
+
|
||||
/* If earliest == jump, try to build the cmove insn directly.
|
||||
This is helpful when combine has created some complex condition
|
||||
(like for alpha's cmovlbs) that we can't hope to regenerate
|
||||
@@ -1372,10 +1375,62 @@
|
||||
return NULL_RTX;
|
||||
|
||||
#if HAVE_conditional_move
|
||||
- return emit_conditional_move (x, code, cmp_a, cmp_b, VOIDmode,
|
||||
- vtrue, vfalse, GET_MODE (x),
|
||||
- (code == LTU || code == GEU
|
||||
- || code == LEU || code == GTU));
|
||||
+ unsignedp = (code == LTU || code == GEU
|
||||
+ || code == LEU || code == GTU);
|
||||
+
|
||||
+ target = emit_conditional_move (x, code, cmp_a, cmp_b, VOIDmode,
|
||||
+ vtrue, vfalse, GET_MODE (x),
|
||||
+ unsignedp);
|
||||
+ if (target)
|
||||
+ return target;
|
||||
+
|
||||
+ /* We might be faced with a situation like:
|
||||
+
|
||||
+ x = (reg:M TARGET)
|
||||
+ vtrue = (subreg:M (reg:N VTRUE) BYTE)
|
||||
+ vfalse = (subreg:M (reg:N VFALSE) BYTE)
|
||||
+
|
||||
+ We can't do a conditional move in mode M, but it's possible that we
|
||||
+ could do a conditional move in mode N instead and take a subreg of
|
||||
+ the result.
|
||||
+
|
||||
+ If we can't create new pseudos, though, don't bother. */
|
||||
+ if (reload_completed)
|
||||
+ return NULL_RTX;
|
||||
+
|
||||
+ if (GET_CODE (vtrue) == SUBREG && GET_CODE (vfalse) == SUBREG)
|
||||
+ {
|
||||
+ rtx reg_vtrue = SUBREG_REG (vtrue);
|
||||
+ rtx reg_vfalse = SUBREG_REG (vfalse);
|
||||
+ unsigned int byte_vtrue = SUBREG_BYTE (vtrue);
|
||||
+ unsigned int byte_vfalse = SUBREG_BYTE (vfalse);
|
||||
+ rtx promoted_target;
|
||||
+
|
||||
+ if (GET_MODE (reg_vtrue) != GET_MODE (reg_vfalse)
|
||||
+ || byte_vtrue != byte_vfalse
|
||||
+ || (SUBREG_PROMOTED_VAR_P (vtrue)
|
||||
+ != SUBREG_PROMOTED_VAR_P (vfalse))
|
||||
+ || (SUBREG_PROMOTED_UNSIGNED_P (vtrue)
|
||||
+ != SUBREG_PROMOTED_UNSIGNED_P (vfalse)))
|
||||
+ return NULL_RTX;
|
||||
+
|
||||
+ promoted_target = gen_reg_rtx (GET_MODE (reg_vtrue));
|
||||
+
|
||||
+ target = emit_conditional_move (promoted_target, code, cmp_a, cmp_b,
|
||||
+ VOIDmode, reg_vtrue, reg_vfalse,
|
||||
+ GET_MODE (reg_vtrue), unsignedp);
|
||||
+ /* Nope, couldn't do it in that mode either. */
|
||||
+ if (!target)
|
||||
+ return NULL_RTX;
|
||||
+
|
||||
+ target = gen_rtx_SUBREG (GET_MODE (vtrue), promoted_target, byte_vtrue);
|
||||
+ SUBREG_PROMOTED_VAR_P (target) = SUBREG_PROMOTED_VAR_P (vtrue);
|
||||
+ SUBREG_PROMOTED_UNSIGNED_SET (target, SUBREG_PROMOTED_UNSIGNED_P (vtrue));
|
||||
+ emit_move_insn (x, target);
|
||||
+ return x;
|
||||
+ }
|
||||
+ else
|
||||
+ return NULL_RTX;
|
||||
#else
|
||||
/* We'll never get here, as noce_process_if_block doesn't call the
|
||||
functions involved. Ifdef code, however, should be discouraged
|
||||
|
||||
114
recipes-devtools/gcc/gcc-4.5/linaro/gcc-4.5-linaro-r99423.patch
Normal file
114
recipes-devtools/gcc/gcc-4.5/linaro/gcc-4.5-linaro-r99423.patch
Normal file
|
|
@ -0,0 +1,114 @@
|
|||
2010-10-25 Jie Zhang <jie@codesourcery.com>
|
||||
|
||||
Issue #9812
|
||||
|
||||
Backport from mainline:
|
||||
|
||||
gcc/
|
||||
2010-10-25 Jie Zhang <jie@codesourcery.com>
|
||||
* combine.c (try_combine): If insns need to be kept around,
|
||||
check that they can be copied in the merged instruction.
|
||||
|
||||
gcc/testsuite/
|
||||
2010-10-25 Jie Zhang <jie@codesourcery.com>
|
||||
* g++.dg/opt/combine.c: New test.
|
||||
|
||||
=== modified file 'gcc/combine.c'
|
||||
--- old/gcc/combine.c 2010-09-20 22:37:32 +0000
|
||||
+++ new/gcc/combine.c 2010-11-04 12:39:28 +0000
|
||||
@@ -2809,6 +2809,17 @@
|
||||
= i1 && ! (i1_feeds_i3 ? dead_or_set_p (i3, i1dest)
|
||||
: (dead_or_set_p (i3, i1dest) || dead_or_set_p (i2, i1dest)));
|
||||
|
||||
+ /* We are about to copy insns for the case where they need to be kept
|
||||
+ around. Check that they can be copied in the merged instruction. */
|
||||
+
|
||||
+ if (targetm.cannot_copy_insn_p
|
||||
+ && ((added_sets_2 && targetm.cannot_copy_insn_p (i2))
|
||||
+ || (i1 && added_sets_1 && targetm.cannot_copy_insn_p (i1))))
|
||||
+ {
|
||||
+ undo_all ();
|
||||
+ return 0;
|
||||
+ }
|
||||
+
|
||||
/* If the set in I2 needs to be kept around, we must make a copy of
|
||||
PATTERN (I2), so that when we substitute I1SRC for I1DEST in
|
||||
PATTERN (I2), we are only substituting for the original I1DEST, not into
|
||||
|
||||
=== added file 'gcc/testsuite/g++.dg/opt/combine.C'
|
||||
--- old/gcc/testsuite/g++.dg/opt/combine.C 1970-01-01 00:00:00 +0000
|
||||
+++ new/gcc/testsuite/g++.dg/opt/combine.C 2010-11-04 12:39:28 +0000
|
||||
@@ -0,0 +1,72 @@
|
||||
+// { dg-do assemble { target fpic } }
|
||||
+// { dg-options "-O2 -fweb -fPIC -fvisibility=hidden" }
|
||||
+
|
||||
+class QBasicAtomicInt
|
||||
+{
|
||||
+public:
|
||||
+ volatile int _q_value;
|
||||
+ inline operator int () const {return _q_value;}
|
||||
+};
|
||||
+class QVariant;
|
||||
+class QScriptContext;
|
||||
+class QScriptEngine;
|
||||
+class QScriptValue
|
||||
+{
|
||||
+public:
|
||||
+ QVariant toVariant () const;
|
||||
+};
|
||||
+class QScriptDebuggerBackendPrivate
|
||||
+{
|
||||
+ static QScriptValue trace (QScriptContext *context);
|
||||
+};
|
||||
+template <typename T> struct QMetaTypeId { };
|
||||
+template <typename T> struct QMetaTypeId2
|
||||
+{
|
||||
+ static inline int qt_metatype_id ()
|
||||
+ {
|
||||
+ return QMetaTypeId<T>::qt_metatype_id () ;
|
||||
+ }
|
||||
+};
|
||||
+template <typename T> inline int qMetaTypeId (T * = 0)
|
||||
+{
|
||||
+ return QMetaTypeId2<T>::qt_metatype_id () ;
|
||||
+}
|
||||
+class QVariant { };
|
||||
+template<typename T> inline T qvariant_cast (const QVariant &v)
|
||||
+{
|
||||
+ const int vid = qMetaTypeId<T> ((0)) ;
|
||||
+};
|
||||
+class QScriptContext
|
||||
+{
|
||||
+public:
|
||||
+ QScriptValue callee () const;
|
||||
+};
|
||||
+class QScriptEngine
|
||||
+{
|
||||
+public:
|
||||
+ static bool convertV2 (const QScriptValue &value , int type , void *ptr) ;
|
||||
+};
|
||||
+inline bool qscriptvalue_cast_helper (const QScriptValue &value , int type , void *ptr)
|
||||
+{
|
||||
+ return QScriptEngine::convertV2 (value, type, ptr) ;
|
||||
+}
|
||||
+template<typename T> T qscriptvalue_cast (const QScriptValue &value)
|
||||
+{
|
||||
+ T t;
|
||||
+ const int id = qMetaTypeId<T> () ;
|
||||
+ if ( qscriptvalue_cast_helper (value, id, &t))
|
||||
+ return qvariant_cast<T> (value.toVariant ()) ;
|
||||
+}
|
||||
+template <> struct QMetaTypeId< QScriptDebuggerBackendPrivate* >
|
||||
+{
|
||||
+ static int qt_metatype_id ()
|
||||
+ {
|
||||
+ static QBasicAtomicInt metatype_id = { (0) };
|
||||
+ return metatype_id;
|
||||
+ }
|
||||
+};
|
||||
+QScriptValue QScriptDebuggerBackendPrivate::trace (QScriptContext *context)
|
||||
+{
|
||||
+ QScriptValue data = context->callee () ;
|
||||
+ QScriptDebuggerBackendPrivate *self = qscriptvalue_cast<QScriptDebuggerBackendPrivate*> (data) ;
|
||||
+}
|
||||
|
||||
687
recipes-devtools/gcc/gcc-4.5/linaro/gcc-4.5-linaro-r99424.patch
Normal file
687
recipes-devtools/gcc/gcc-4.5/linaro/gcc-4.5-linaro-r99424.patch
Normal file
|
|
@ -0,0 +1,687 @@
|
|||
Issue #1259
|
||||
|
||||
Backport from mainline:
|
||||
|
||||
gcc/
|
||||
2010-10-22 Jie Zhang <jie@codesourcery.com>
|
||||
|
||||
* expr.c (emit_group_load_1): Update calls to extract_bit_field.
|
||||
(copy_blkmode_from_reg): Likewise.
|
||||
(read_complex_part): Likewise.
|
||||
(expand_expr_real_1): Calculate packedp and pass it to
|
||||
extract_bit_field.
|
||||
* expr.h (extract_bit_field): Update declaration.
|
||||
* calls.c (store_unaligned_arguments_into_pseudos): Update call
|
||||
to extract_bit_field.
|
||||
* expmed.c (extract_fixed_bit_field): Update calls to
|
||||
extract_fixed_bit_field.
|
||||
(store_split_bit_field): Likewise.
|
||||
(extract_bit_field_1): Add new argument packedp.
|
||||
(extract_bit_field): Add new argument packedp.
|
||||
(extract_fixed_bit_field): Add new argument packedp and let
|
||||
packed attribute override volatile.
|
||||
* stmt.c (expand_return): Update call to extract_bit_field.
|
||||
|
||||
2010-10-15 Jie Zhang <jie@codesourcery.com>
|
||||
|
||||
* doc/invoke.texi: Add -fstrict-volatile-bitfields to
|
||||
Option Summary and Index.
|
||||
|
||||
2010-07-13 DJ Delorie <dj@redhat.com>
|
||||
|
||||
* config/h8300/h8300.c (h8300_init_once): Default to
|
||||
-fstrict_volatile_bitfields.
|
||||
|
||||
* config/sh/sh.c (sh_override_options): Default to
|
||||
-fstrict_volatile_bitfields.
|
||||
|
||||
* config/rx/rx.c (rx_option_override): New.
|
||||
|
||||
* config/m32c/m32c.c (m32c_override_options): Default to
|
||||
-fstrict_volatile_bitfields.
|
||||
|
||||
2010-06-16 DJ Delorie <dj@redhat.com>
|
||||
|
||||
* common.opt (-fstrict-volatile-bitfields): new.
|
||||
* doc/invoke.texi: Document it.
|
||||
* fold-const.c (optimize_bit_field_compare): For volatile
|
||||
bitfields, use the field's type to determine the mode, not the
|
||||
field's size.
|
||||
* expr.c (expand_assignment): Likewise.
|
||||
(get_inner_reference): Likewise.
|
||||
(expand_expr_real_1): Likewise.
|
||||
* expmed.c (store_fixed_bit_field): Likewise.
|
||||
(extract_bit_field_1): Likewise.
|
||||
(extract_fixed_bit_field): Likewise.
|
||||
|
||||
gcc/testsuite/
|
||||
2010-08-19 Uros Bizjak <ubizjak@gmail.com>
|
||||
|
||||
PR testsuite/45324
|
||||
* gcc.target/i386/volatile-bitfields-1.c: Also scan movb.
|
||||
|
||||
2010-06-16 DJ Delorie <dj@redhat.com>
|
||||
|
||||
* gcc.target/i386/volatile-bitfields-1.c: New.
|
||||
* gcc.target/i386/volatile-bitfields-2.c: New.
|
||||
|
||||
=== modified file 'gcc/calls.c'
|
||||
--- old/gcc/calls.c 2010-10-04 00:50:43 +0000
|
||||
+++ new/gcc/calls.c 2010-11-04 12:43:52 +0000
|
||||
@@ -878,7 +878,7 @@
|
||||
int bitsize = MIN (bytes * BITS_PER_UNIT, BITS_PER_WORD);
|
||||
|
||||
args[i].aligned_regs[j] = reg;
|
||||
- word = extract_bit_field (word, bitsize, 0, 1, NULL_RTX,
|
||||
+ word = extract_bit_field (word, bitsize, 0, 1, false, NULL_RTX,
|
||||
word_mode, word_mode);
|
||||
|
||||
/* There is no need to restrict this code to loading items
|
||||
|
||||
=== modified file 'gcc/common.opt'
|
||||
--- old/gcc/common.opt 2010-07-29 14:59:35 +0000
|
||||
+++ new/gcc/common.opt 2010-11-04 12:43:52 +0000
|
||||
@@ -613,6 +613,10 @@
|
||||
Common Report Var(flag_loop_block) Optimization
|
||||
Enable Loop Blocking transformation
|
||||
|
||||
+fstrict-volatile-bitfields
|
||||
+Common Report Var(flag_strict_volatile_bitfields) Init(-1)
|
||||
+Force bitfield accesses to match their type width
|
||||
+
|
||||
fguess-branch-probability
|
||||
Common Report Var(flag_guess_branch_prob) Optimization
|
||||
Enable guessing of branch probabilities
|
||||
|
||||
=== modified file 'gcc/config/h8300/h8300.c'
|
||||
--- old/gcc/config/h8300/h8300.c 2010-04-02 18:54:46 +0000
|
||||
+++ new/gcc/config/h8300/h8300.c 2010-11-04 12:43:52 +0000
|
||||
@@ -403,6 +403,10 @@
|
||||
restore er6 though, so bump up the cost. */
|
||||
h8300_move_ratio = 6;
|
||||
}
|
||||
+
|
||||
+ /* This target defaults to strict volatile bitfields. */
|
||||
+ if (flag_strict_volatile_bitfields < 0)
|
||||
+ flag_strict_volatile_bitfields = 1;
|
||||
}
|
||||
|
||||
/* Implement REG_CLASS_FROM_LETTER.
|
||||
|
||||
=== modified file 'gcc/config/m32c/m32c.c'
|
||||
--- old/gcc/config/m32c/m32c.c 2009-10-22 18:46:26 +0000
|
||||
+++ new/gcc/config/m32c/m32c.c 2010-11-04 12:43:52 +0000
|
||||
@@ -428,6 +428,10 @@
|
||||
|
||||
if (TARGET_A24)
|
||||
flag_ivopts = 0;
|
||||
+
|
||||
+ /* This target defaults to strict volatile bitfields. */
|
||||
+ if (flag_strict_volatile_bitfields < 0)
|
||||
+ flag_strict_volatile_bitfields = 1;
|
||||
}
|
||||
|
||||
/* Defining data structures for per-function information */
|
||||
|
||||
=== modified file 'gcc/config/rx/rx.c'
|
||||
--- old/gcc/config/rx/rx.c 2010-07-27 14:39:53 +0000
|
||||
+++ new/gcc/config/rx/rx.c 2010-11-04 12:43:52 +0000
|
||||
@@ -2187,6 +2187,14 @@
|
||||
}
|
||||
}
|
||||
|
||||
+static void
|
||||
+rx_option_override (void)
|
||||
+{
|
||||
+ /* This target defaults to strict volatile bitfields. */
|
||||
+ if (flag_strict_volatile_bitfields < 0)
|
||||
+ flag_strict_volatile_bitfields = 1;
|
||||
+}
|
||||
+
|
||||
|
||||
static bool
|
||||
rx_allocate_stack_slots_for_args (void)
|
||||
@@ -2759,6 +2767,9 @@
|
||||
#undef TARGET_CC_MODES_COMPATIBLE
|
||||
#define TARGET_CC_MODES_COMPATIBLE rx_cc_modes_compatible
|
||||
|
||||
+#undef TARGET_OPTION_OVERRIDE
|
||||
+#define TARGET_OPTION_OVERRIDE rx_option_override
|
||||
+
|
||||
struct gcc_target targetm = TARGET_INITIALIZER;
|
||||
|
||||
/* #include "gt-rx.h" */
|
||||
|
||||
=== modified file 'gcc/config/sh/sh.c'
|
||||
--- old/gcc/config/sh/sh.c 2010-05-05 21:12:17 +0000
|
||||
+++ new/gcc/config/sh/sh.c 2010-11-04 12:43:52 +0000
|
||||
@@ -950,6 +950,10 @@
|
||||
|
||||
if (sh_fixed_range_str)
|
||||
sh_fix_range (sh_fixed_range_str);
|
||||
+
|
||||
+ /* This target defaults to strict volatile bitfields. */
|
||||
+ if (flag_strict_volatile_bitfields < 0)
|
||||
+ flag_strict_volatile_bitfields = 1;
|
||||
}
|
||||
|
||||
/* Print the operand address in x to the stream. */
|
||||
|
||||
=== modified file 'gcc/doc/invoke.texi'
|
||||
--- old/gcc/doc/invoke.texi 2010-10-04 00:50:43 +0000
|
||||
+++ new/gcc/doc/invoke.texi 2010-11-04 12:43:52 +0000
|
||||
@@ -922,7 +922,7 @@
|
||||
-fargument-noalias-global -fargument-noalias-anything @gol
|
||||
-fleading-underscore -ftls-model=@var{model} @gol
|
||||
-ftrapv -fwrapv -fbounds-check @gol
|
||||
--fvisibility}
|
||||
+-fvisibility -fstrict-volatile-bitfields}
|
||||
@end table
|
||||
|
||||
@menu
|
||||
@@ -17629,6 +17629,33 @@
|
||||
An overview of these techniques, their benefits and how to use them
|
||||
is at @w{@uref{http://gcc.gnu.org/wiki/Visibility}}.
|
||||
|
||||
+@item -fstrict-volatile-bitfields
|
||||
+@opindex fstrict-volatile-bitfields
|
||||
+This option should be used if accesses to volatile bitfields (or other
|
||||
+structure fields, although the compiler usually honors those types
|
||||
+anyway) should use a single access in a mode of the same size as the
|
||||
+container's type, aligned to a natural alignment if possible. For
|
||||
+example, targets with memory-mapped peripheral registers might require
|
||||
+all such accesses to be 16 bits wide; with this flag the user could
|
||||
+declare all peripheral bitfields as ``unsigned short'' (assuming short
|
||||
+is 16 bits on these targets) to force GCC to use 16 bit accesses
|
||||
+instead of, perhaps, a more efficient 32 bit access.
|
||||
+
|
||||
+If this option is disabled, the compiler will use the most efficient
|
||||
+instruction. In the previous example, that might be a 32-bit load
|
||||
+instruction, even though that will access bytes that do not contain
|
||||
+any portion of the bitfield, or memory-mapped registers unrelated to
|
||||
+the one being updated.
|
||||
+
|
||||
+If the target requires strict alignment, and honoring the container
|
||||
+type would require violating this alignment, a warning is issued.
|
||||
+However, the access happens as the user requested, under the
|
||||
+assumption that the user knows something about the target hardware
|
||||
+that GCC is unaware of.
|
||||
+
|
||||
+The default value of this option is determined by the application binary
|
||||
+interface for the target processor.
|
||||
+
|
||||
@end table
|
||||
|
||||
@c man end
|
||||
|
||||
=== modified file 'gcc/expmed.c'
|
||||
--- old/gcc/expmed.c 2010-10-04 00:50:43 +0000
|
||||
+++ new/gcc/expmed.c 2010-11-04 12:43:52 +0000
|
||||
@@ -47,7 +47,7 @@
|
||||
static rtx extract_fixed_bit_field (enum machine_mode, rtx,
|
||||
unsigned HOST_WIDE_INT,
|
||||
unsigned HOST_WIDE_INT,
|
||||
- unsigned HOST_WIDE_INT, rtx, int);
|
||||
+ unsigned HOST_WIDE_INT, rtx, int, bool);
|
||||
static rtx mask_rtx (enum machine_mode, int, int, int);
|
||||
static rtx lshift_value (enum machine_mode, rtx, int, int);
|
||||
static rtx extract_split_bit_field (rtx, unsigned HOST_WIDE_INT,
|
||||
@@ -904,8 +904,14 @@
|
||||
if (GET_MODE_BITSIZE (mode) == 0
|
||||
|| GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (word_mode))
|
||||
mode = word_mode;
|
||||
- mode = get_best_mode (bitsize, bitpos + offset * BITS_PER_UNIT,
|
||||
- MEM_ALIGN (op0), mode, MEM_VOLATILE_P (op0));
|
||||
+
|
||||
+ if (MEM_VOLATILE_P (op0)
|
||||
+ && GET_MODE_BITSIZE (GET_MODE (op0)) > 0
|
||||
+ && flag_strict_volatile_bitfields > 0)
|
||||
+ mode = GET_MODE (op0);
|
||||
+ else
|
||||
+ mode = get_best_mode (bitsize, bitpos + offset * BITS_PER_UNIT,
|
||||
+ MEM_ALIGN (op0), mode, MEM_VOLATILE_P (op0));
|
||||
|
||||
if (mode == VOIDmode)
|
||||
{
|
||||
@@ -1099,7 +1105,7 @@
|
||||
endianness compensation) to fetch the piece we want. */
|
||||
part = extract_fixed_bit_field (word_mode, value, 0, thissize,
|
||||
total_bits - bitsize + bitsdone,
|
||||
- NULL_RTX, 1);
|
||||
+ NULL_RTX, 1, false);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -1110,7 +1116,7 @@
|
||||
& (((HOST_WIDE_INT) 1 << thissize) - 1));
|
||||
else
|
||||
part = extract_fixed_bit_field (word_mode, value, 0, thissize,
|
||||
- bitsdone, NULL_RTX, 1);
|
||||
+ bitsdone, NULL_RTX, 1, false);
|
||||
}
|
||||
|
||||
/* If OP0 is a register, then handle OFFSET here.
|
||||
@@ -1176,7 +1182,8 @@
|
||||
|
||||
static rtx
|
||||
extract_bit_field_1 (rtx str_rtx, unsigned HOST_WIDE_INT bitsize,
|
||||
- unsigned HOST_WIDE_INT bitnum, int unsignedp, rtx target,
|
||||
+ unsigned HOST_WIDE_INT bitnum,
|
||||
+ int unsignedp, bool packedp, rtx target,
|
||||
enum machine_mode mode, enum machine_mode tmode,
|
||||
bool fallback_p)
|
||||
{
|
||||
@@ -1378,6 +1385,14 @@
|
||||
? mode_for_size (bitsize, GET_MODE_CLASS (tmode), 0)
|
||||
: mode);
|
||||
|
||||
+ /* If the bitfield is volatile, we need to make sure the access
|
||||
+ remains on a type-aligned boundary. */
|
||||
+ if (GET_CODE (op0) == MEM
|
||||
+ && MEM_VOLATILE_P (op0)
|
||||
+ && GET_MODE_BITSIZE (GET_MODE (op0)) > 0
|
||||
+ && flag_strict_volatile_bitfields > 0)
|
||||
+ goto no_subreg_mode_swap;
|
||||
+
|
||||
if (((bitsize >= BITS_PER_WORD && bitsize == GET_MODE_BITSIZE (mode)
|
||||
&& bitpos % BITS_PER_WORD == 0)
|
||||
|| (mode1 != BLKmode
|
||||
@@ -1450,7 +1465,7 @@
|
||||
rtx result_part
|
||||
= extract_bit_field (op0, MIN (BITS_PER_WORD,
|
||||
bitsize - i * BITS_PER_WORD),
|
||||
- bitnum + bit_offset, 1, target_part, mode,
|
||||
+ bitnum + bit_offset, 1, false, target_part, mode,
|
||||
word_mode);
|
||||
|
||||
gcc_assert (target_part);
|
||||
@@ -1649,7 +1664,7 @@
|
||||
xop0 = adjust_address (op0, bestmode, xoffset);
|
||||
xop0 = force_reg (bestmode, xop0);
|
||||
result = extract_bit_field_1 (xop0, bitsize, xbitpos,
|
||||
- unsignedp, target,
|
||||
+ unsignedp, packedp, target,
|
||||
mode, tmode, false);
|
||||
if (result)
|
||||
return result;
|
||||
@@ -1663,7 +1678,7 @@
|
||||
return NULL;
|
||||
|
||||
target = extract_fixed_bit_field (int_mode, op0, offset, bitsize,
|
||||
- bitpos, target, unsignedp);
|
||||
+ bitpos, target, unsignedp, packedp);
|
||||
return convert_extracted_bit_field (target, mode, tmode, unsignedp);
|
||||
}
|
||||
|
||||
@@ -1674,6 +1689,7 @@
|
||||
|
||||
STR_RTX is the structure containing the byte (a REG or MEM).
|
||||
UNSIGNEDP is nonzero if this is an unsigned bit field.
|
||||
+ PACKEDP is nonzero if the field has the packed attribute.
|
||||
MODE is the natural mode of the field value once extracted.
|
||||
TMODE is the mode the caller would like the value to have;
|
||||
but the value may be returned with type MODE instead.
|
||||
@@ -1685,10 +1701,10 @@
|
||||
|
||||
rtx
|
||||
extract_bit_field (rtx str_rtx, unsigned HOST_WIDE_INT bitsize,
|
||||
- unsigned HOST_WIDE_INT bitnum, int unsignedp, rtx target,
|
||||
- enum machine_mode mode, enum machine_mode tmode)
|
||||
+ unsigned HOST_WIDE_INT bitnum, int unsignedp, bool packedp,
|
||||
+ rtx target, enum machine_mode mode, enum machine_mode tmode)
|
||||
{
|
||||
- return extract_bit_field_1 (str_rtx, bitsize, bitnum, unsignedp,
|
||||
+ return extract_bit_field_1 (str_rtx, bitsize, bitnum, unsignedp, packedp,
|
||||
target, mode, tmode, true);
|
||||
}
|
||||
|
||||
@@ -1704,6 +1720,8 @@
|
||||
which is significant on bigendian machines.)
|
||||
|
||||
UNSIGNEDP is nonzero for an unsigned bit field (don't sign-extend value).
|
||||
+ PACKEDP is true if the field has the packed attribute.
|
||||
+
|
||||
If TARGET is nonzero, attempts to store the value there
|
||||
and return TARGET, but this is not guaranteed.
|
||||
If TARGET is not used, create a pseudo-reg of mode TMODE for the value. */
|
||||
@@ -1713,7 +1731,7 @@
|
||||
unsigned HOST_WIDE_INT offset,
|
||||
unsigned HOST_WIDE_INT bitsize,
|
||||
unsigned HOST_WIDE_INT bitpos, rtx target,
|
||||
- int unsignedp)
|
||||
+ int unsignedp, bool packedp)
|
||||
{
|
||||
unsigned int total_bits = BITS_PER_WORD;
|
||||
enum machine_mode mode;
|
||||
@@ -1730,8 +1748,19 @@
|
||||
includes the entire field. If such a mode would be larger than
|
||||
a word, we won't be doing the extraction the normal way. */
|
||||
|
||||
- mode = get_best_mode (bitsize, bitpos + offset * BITS_PER_UNIT,
|
||||
- MEM_ALIGN (op0), word_mode, MEM_VOLATILE_P (op0));
|
||||
+ if (MEM_VOLATILE_P (op0)
|
||||
+ && flag_strict_volatile_bitfields > 0)
|
||||
+ {
|
||||
+ if (GET_MODE_BITSIZE (GET_MODE (op0)) > 0)
|
||||
+ mode = GET_MODE (op0);
|
||||
+ else if (target && GET_MODE_BITSIZE (GET_MODE (target)) > 0)
|
||||
+ mode = GET_MODE (target);
|
||||
+ else
|
||||
+ mode = tmode;
|
||||
+ }
|
||||
+ else
|
||||
+ mode = get_best_mode (bitsize, bitpos + offset * BITS_PER_UNIT,
|
||||
+ MEM_ALIGN (op0), word_mode, MEM_VOLATILE_P (op0));
|
||||
|
||||
if (mode == VOIDmode)
|
||||
/* The only way this should occur is if the field spans word
|
||||
@@ -1752,12 +1781,67 @@
|
||||
* BITS_PER_UNIT);
|
||||
}
|
||||
|
||||
- /* Get ref to an aligned byte, halfword, or word containing the field.
|
||||
- Adjust BITPOS to be position within a word,
|
||||
- and OFFSET to be the offset of that word.
|
||||
- Then alter OP0 to refer to that word. */
|
||||
- bitpos += (offset % (total_bits / BITS_PER_UNIT)) * BITS_PER_UNIT;
|
||||
- offset -= (offset % (total_bits / BITS_PER_UNIT));
|
||||
+ /* If we're accessing a volatile MEM, we can't do the next
|
||||
+ alignment step if it results in a multi-word access where we
|
||||
+ otherwise wouldn't have one. So, check for that case
|
||||
+ here. */
|
||||
+ if (MEM_P (op0)
|
||||
+ && MEM_VOLATILE_P (op0)
|
||||
+ && flag_strict_volatile_bitfields > 0
|
||||
+ && bitpos + bitsize <= total_bits
|
||||
+ && bitpos + bitsize + (offset % (total_bits / BITS_PER_UNIT)) * BITS_PER_UNIT > total_bits)
|
||||
+ {
|
||||
+ if (STRICT_ALIGNMENT)
|
||||
+ {
|
||||
+ static bool informed_about_misalignment = false;
|
||||
+ bool warned;
|
||||
+
|
||||
+ if (packedp)
|
||||
+ {
|
||||
+ if (bitsize == total_bits)
|
||||
+ warned = warning_at (input_location, OPT_fstrict_volatile_bitfields,
|
||||
+ "multiple accesses to volatile structure member"
|
||||
+ " because of packed attribute");
|
||||
+ else
|
||||
+ warned = warning_at (input_location, OPT_fstrict_volatile_bitfields,
|
||||
+ "multiple accesses to volatile structure bitfield"
|
||||
+ " because of packed attribute");
|
||||
+
|
||||
+ return extract_split_bit_field (op0, bitsize,
|
||||
+ bitpos + offset * BITS_PER_UNIT,
|
||||
+ unsignedp);
|
||||
+ }
|
||||
+
|
||||
+ if (bitsize == total_bits)
|
||||
+ warned = warning_at (input_location, OPT_fstrict_volatile_bitfields,
|
||||
+ "mis-aligned access used for structure member");
|
||||
+ else
|
||||
+ warned = warning_at (input_location, OPT_fstrict_volatile_bitfields,
|
||||
+ "mis-aligned access used for structure bitfield");
|
||||
+
|
||||
+ if (! informed_about_misalignment && warned)
|
||||
+ {
|
||||
+ informed_about_misalignment = true;
|
||||
+ inform (input_location,
|
||||
+ "When a volatile object spans multiple type-sized locations,"
|
||||
+ " the compiler must choose between using a single mis-aligned access to"
|
||||
+ " preserve the volatility, or using multiple aligned accesses to avoid"
|
||||
+ " runtime faults. This code may fail at runtime if the hardware does"
|
||||
+ " not allow this access.");
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+
|
||||
+ /* Get ref to an aligned byte, halfword, or word containing the field.
|
||||
+ Adjust BITPOS to be position within a word,
|
||||
+ and OFFSET to be the offset of that word.
|
||||
+ Then alter OP0 to refer to that word. */
|
||||
+ bitpos += (offset % (total_bits / BITS_PER_UNIT)) * BITS_PER_UNIT;
|
||||
+ offset -= (offset % (total_bits / BITS_PER_UNIT));
|
||||
+ }
|
||||
+
|
||||
op0 = adjust_address (op0, mode, offset);
|
||||
}
|
||||
|
||||
@@ -1966,7 +2050,7 @@
|
||||
extract_fixed_bit_field wants offset in bytes. */
|
||||
part = extract_fixed_bit_field (word_mode, word,
|
||||
offset * unit / BITS_PER_UNIT,
|
||||
- thissize, thispos, 0, 1);
|
||||
+ thissize, thispos, 0, 1, false);
|
||||
bitsdone += thissize;
|
||||
|
||||
/* Shift this part into place for the result. */
|
||||
|
||||
=== modified file 'gcc/expr.c'
|
||||
--- old/gcc/expr.c 2010-10-04 00:50:43 +0000
|
||||
+++ new/gcc/expr.c 2010-11-04 12:43:52 +0000
|
||||
@@ -1749,7 +1749,7 @@
|
||||
&& (!REG_P (tmps[i]) || GET_MODE (tmps[i]) != mode))
|
||||
tmps[i] = extract_bit_field (tmps[i], bytelen * BITS_PER_UNIT,
|
||||
(bytepos % slen0) * BITS_PER_UNIT,
|
||||
- 1, NULL_RTX, mode, mode);
|
||||
+ 1, false, NULL_RTX, mode, mode);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -1759,7 +1759,7 @@
|
||||
mem = assign_stack_temp (GET_MODE (src), slen, 0);
|
||||
emit_move_insn (mem, src);
|
||||
tmps[i] = extract_bit_field (mem, bytelen * BITS_PER_UNIT,
|
||||
- 0, 1, NULL_RTX, mode, mode);
|
||||
+ 0, 1, false, NULL_RTX, mode, mode);
|
||||
}
|
||||
}
|
||||
/* FIXME: A SIMD parallel will eventually lead to a subreg of a
|
||||
@@ -1800,7 +1800,7 @@
|
||||
tmps[i] = src;
|
||||
else
|
||||
tmps[i] = extract_bit_field (src, bytelen * BITS_PER_UNIT,
|
||||
- bytepos * BITS_PER_UNIT, 1, NULL_RTX,
|
||||
+ bytepos * BITS_PER_UNIT, 1, false, NULL_RTX,
|
||||
mode, mode);
|
||||
|
||||
if (shift)
|
||||
@@ -2213,7 +2213,7 @@
|
||||
bitpos for the destination store (left justified). */
|
||||
store_bit_field (dst, bitsize, bitpos % BITS_PER_WORD, copy_mode,
|
||||
extract_bit_field (src, bitsize,
|
||||
- xbitpos % BITS_PER_WORD, 1,
|
||||
+ xbitpos % BITS_PER_WORD, 1, false,
|
||||
NULL_RTX, copy_mode, copy_mode));
|
||||
}
|
||||
|
||||
@@ -2970,7 +2970,7 @@
|
||||
}
|
||||
|
||||
return extract_bit_field (cplx, ibitsize, imag_p ? ibitsize : 0,
|
||||
- true, NULL_RTX, imode, imode);
|
||||
+ true, false, NULL_RTX, imode, imode);
|
||||
}
|
||||
|
||||
/* A subroutine of emit_move_insn_1. Yet another lowpart generator.
|
||||
@@ -4233,6 +4233,13 @@
|
||||
|
||||
to_rtx = expand_normal (tem);
|
||||
|
||||
+ /* If the bitfield is volatile, we want to access it in the
|
||||
+ field's mode, not the computed mode. */
|
||||
+ if (volatilep
|
||||
+ && GET_CODE (to_rtx) == MEM
|
||||
+ && flag_strict_volatile_bitfields > 0)
|
||||
+ to_rtx = adjust_address (to_rtx, mode1, 0);
|
||||
+
|
||||
if (offset != 0)
|
||||
{
|
||||
enum machine_mode address_mode;
|
||||
@@ -5993,6 +6000,12 @@
|
||||
mode = DECL_MODE (field);
|
||||
else if (DECL_MODE (field) == BLKmode)
|
||||
blkmode_bitfield = true;
|
||||
+ else if (TREE_THIS_VOLATILE (exp)
|
||||
+ && flag_strict_volatile_bitfields > 0)
|
||||
+ /* Volatile bitfields should be accessed in the mode of the
|
||||
+ field's type, not the mode computed based on the bit
|
||||
+ size. */
|
||||
+ mode = TYPE_MODE (DECL_BIT_FIELD_TYPE (field));
|
||||
|
||||
*punsignedp = DECL_UNSIGNED (field);
|
||||
}
|
||||
@@ -8848,6 +8861,7 @@
|
||||
HOST_WIDE_INT bitsize, bitpos;
|
||||
tree offset;
|
||||
int volatilep = 0, must_force_mem;
|
||||
+ bool packedp = false;
|
||||
tree tem = get_inner_reference (exp, &bitsize, &bitpos, &offset,
|
||||
&mode1, &unsignedp, &volatilep, true);
|
||||
rtx orig_op0, memloc;
|
||||
@@ -8857,6 +8871,11 @@
|
||||
infinitely recurse. */
|
||||
gcc_assert (tem != exp);
|
||||
|
||||
+ if (TYPE_PACKED (TREE_TYPE (TREE_OPERAND (exp, 0)))
|
||||
+ || (TREE_CODE (TREE_OPERAND (exp, 1)) == FIELD_DECL
|
||||
+ && DECL_PACKED (TREE_OPERAND (exp, 1))))
|
||||
+ packedp = true;
|
||||
+
|
||||
/* If TEM's type is a union of variable size, pass TARGET to the inner
|
||||
computation, since it will need a temporary and TARGET is known
|
||||
to have to do. This occurs in unchecked conversion in Ada. */
|
||||
@@ -8873,6 +8892,14 @@
|
||||
|| modifier == EXPAND_STACK_PARM)
|
||||
? modifier : EXPAND_NORMAL);
|
||||
|
||||
+
|
||||
+ /* If the bitfield is volatile, we want to access it in the
|
||||
+ field's mode, not the computed mode. */
|
||||
+ if (volatilep
|
||||
+ && GET_CODE (op0) == MEM
|
||||
+ && flag_strict_volatile_bitfields > 0)
|
||||
+ op0 = adjust_address (op0, mode1, 0);
|
||||
+
|
||||
mode2
|
||||
= CONSTANT_P (op0) ? TYPE_MODE (TREE_TYPE (tem)) : GET_MODE (op0);
|
||||
|
||||
@@ -8998,6 +9025,9 @@
|
||||
&& GET_MODE_CLASS (mode) != MODE_COMPLEX_FLOAT
|
||||
&& modifier != EXPAND_CONST_ADDRESS
|
||||
&& modifier != EXPAND_INITIALIZER)
|
||||
+ /* If the field is volatile, we always want an aligned
|
||||
+ access. */
|
||||
+ || (volatilep && flag_strict_volatile_bitfields > 0)
|
||||
/* If the field isn't aligned enough to fetch as a memref,
|
||||
fetch it as a bit field. */
|
||||
|| (mode1 != BLKmode
|
||||
@@ -9058,7 +9088,7 @@
|
||||
if (MEM_P (op0) && REG_P (XEXP (op0, 0)))
|
||||
mark_reg_pointer (XEXP (op0, 0), MEM_ALIGN (op0));
|
||||
|
||||
- op0 = extract_bit_field (op0, bitsize, bitpos, unsignedp,
|
||||
+ op0 = extract_bit_field (op0, bitsize, bitpos, unsignedp, packedp,
|
||||
(modifier == EXPAND_STACK_PARM
|
||||
? NULL_RTX : target),
|
||||
ext_mode, ext_mode);
|
||||
|
||||
=== modified file 'gcc/expr.h'
|
||||
--- old/gcc/expr.h 2010-02-19 09:53:51 +0000
|
||||
+++ new/gcc/expr.h 2010-11-04 12:43:52 +0000
|
||||
@@ -802,7 +802,7 @@
|
||||
extern void store_bit_field (rtx, unsigned HOST_WIDE_INT,
|
||||
unsigned HOST_WIDE_INT, enum machine_mode, rtx);
|
||||
extern rtx extract_bit_field (rtx, unsigned HOST_WIDE_INT,
|
||||
- unsigned HOST_WIDE_INT, int, rtx,
|
||||
+ unsigned HOST_WIDE_INT, int, bool, rtx,
|
||||
enum machine_mode, enum machine_mode);
|
||||
extern rtx extract_low_bits (enum machine_mode, enum machine_mode, rtx);
|
||||
extern rtx expand_mult (enum machine_mode, rtx, rtx, rtx, int);
|
||||
|
||||
=== modified file 'gcc/fold-const.c'
|
||||
--- old/gcc/fold-const.c 2010-10-04 00:50:43 +0000
|
||||
+++ new/gcc/fold-const.c 2010-11-04 12:43:52 +0000
|
||||
@@ -4208,11 +4208,16 @@
|
||||
|
||||
/* See if we can find a mode to refer to this field. We should be able to,
|
||||
but fail if we can't. */
|
||||
- nmode = get_best_mode (lbitsize, lbitpos,
|
||||
- const_p ? TYPE_ALIGN (TREE_TYPE (linner))
|
||||
- : MIN (TYPE_ALIGN (TREE_TYPE (linner)),
|
||||
- TYPE_ALIGN (TREE_TYPE (rinner))),
|
||||
- word_mode, lvolatilep || rvolatilep);
|
||||
+ if (lvolatilep
|
||||
+ && GET_MODE_BITSIZE (lmode) > 0
|
||||
+ && flag_strict_volatile_bitfields > 0)
|
||||
+ nmode = lmode;
|
||||
+ else
|
||||
+ nmode = get_best_mode (lbitsize, lbitpos,
|
||||
+ const_p ? TYPE_ALIGN (TREE_TYPE (linner))
|
||||
+ : MIN (TYPE_ALIGN (TREE_TYPE (linner)),
|
||||
+ TYPE_ALIGN (TREE_TYPE (rinner))),
|
||||
+ word_mode, lvolatilep || rvolatilep);
|
||||
if (nmode == VOIDmode)
|
||||
return 0;
|
||||
|
||||
|
||||
=== modified file 'gcc/stmt.c'
|
||||
--- old/gcc/stmt.c 2010-08-13 11:53:46 +0000
|
||||
+++ new/gcc/stmt.c 2010-11-04 12:43:52 +0000
|
||||
@@ -1751,7 +1751,7 @@
|
||||
xbitpos for the destination store (right justified). */
|
||||
store_bit_field (dst, bitsize, xbitpos % BITS_PER_WORD, word_mode,
|
||||
extract_bit_field (src, bitsize,
|
||||
- bitpos % BITS_PER_WORD, 1,
|
||||
+ bitpos % BITS_PER_WORD, 1, false,
|
||||
NULL_RTX, word_mode, word_mode));
|
||||
}
|
||||
|
||||
|
||||
=== added file 'gcc/testsuite/gcc.target/i386/volatile-bitfields-1.c'
|
||||
--- old/gcc/testsuite/gcc.target/i386/volatile-bitfields-1.c 1970-01-01 00:00:00 +0000
|
||||
+++ new/gcc/testsuite/gcc.target/i386/volatile-bitfields-1.c 2010-11-04 12:43:52 +0000
|
||||
@@ -0,0 +1,17 @@
|
||||
+/* { dg-do compile } */
|
||||
+/* { dg-options "-O2 -fstrict-volatile-bitfields" } */
|
||||
+
|
||||
+typedef struct {
|
||||
+ char a:1;
|
||||
+ char b:7;
|
||||
+ int c;
|
||||
+} BitStruct;
|
||||
+
|
||||
+volatile BitStruct bits;
|
||||
+
|
||||
+int foo ()
|
||||
+{
|
||||
+ return bits.b;
|
||||
+}
|
||||
+
|
||||
+/* { dg-final { scan-assembler "mov(b|zbl).*bits" } } */
|
||||
|
||||
=== added file 'gcc/testsuite/gcc.target/i386/volatile-bitfields-2.c'
|
||||
--- old/gcc/testsuite/gcc.target/i386/volatile-bitfields-2.c 1970-01-01 00:00:00 +0000
|
||||
+++ new/gcc/testsuite/gcc.target/i386/volatile-bitfields-2.c 2010-11-04 12:43:52 +0000
|
||||
@@ -0,0 +1,17 @@
|
||||
+/* { dg-do compile } */
|
||||
+/* { dg-options "-O2 -fno-strict-volatile-bitfields" } */
|
||||
+
|
||||
+typedef struct {
|
||||
+ char a:1;
|
||||
+ char b:7;
|
||||
+ int c;
|
||||
+} BitStruct;
|
||||
+
|
||||
+volatile BitStruct bits;
|
||||
+
|
||||
+int foo ()
|
||||
+{
|
||||
+ return bits.b;
|
||||
+}
|
||||
+
|
||||
+/* { dg-final { scan-assembler "movl.*bits" } } */
|
||||
|
||||
128
recipes-devtools/gcc/gcc-4.5/linaro/gcc-4.5-linaro-r99425.patch
Normal file
128
recipes-devtools/gcc/gcc-4.5/linaro/gcc-4.5-linaro-r99425.patch
Normal file
|
|
@ -0,0 +1,128 @@
|
|||
2010-10-26 Jie Zhang <jie@codesourcery.com>
|
||||
|
||||
Issue #1259
|
||||
|
||||
Backport from mainline:
|
||||
|
||||
gcc/
|
||||
2010-10-26 Jie Zhang <jie@codesourcery.com>
|
||||
|
||||
* stor-layout.c (layout_decl): Use the field's type to
|
||||
determine the mode and keep DECL_BIT_FIELD for a volatile
|
||||
bit-field.
|
||||
* config/arm/arm.c (arm_override_options): Default to
|
||||
-fstrict-volatile-bitfields.
|
||||
|
||||
gcc/testsuite/
|
||||
2010-10-26 Jie Zhang <jie@codesourcery.com>
|
||||
|
||||
* gcc.target/arm/volatile-bitfields-1.c: New test.
|
||||
* gcc.target/arm/volatile-bitfields-2.c: New test.
|
||||
* gcc.target/arm/volatile-bitfields-3.c: New test.
|
||||
|
||||
=== modified file 'gcc/config/arm/arm.c'
|
||||
--- old/gcc/config/arm/arm.c 2010-11-04 10:45:05 +0000
|
||||
+++ new/gcc/config/arm/arm.c 2010-11-04 12:49:37 +0000
|
||||
@@ -1933,6 +1933,10 @@
|
||||
calculation, which is 2 instructions. */
|
||||
set_param_value ("gcse-unrestricted-cost", 2);
|
||||
|
||||
+ /* ARM EABI defaults to strict volatile bitfields. */
|
||||
+ if (TARGET_AAPCS_BASED && flag_strict_volatile_bitfields < 0)
|
||||
+ flag_strict_volatile_bitfields = 1;
|
||||
+
|
||||
/* Register global variables with the garbage collector. */
|
||||
arm_add_gc_roots ();
|
||||
|
||||
|
||||
=== modified file 'gcc/stor-layout.c'
|
||||
--- old/gcc/stor-layout.c 2010-04-02 18:54:46 +0000
|
||||
+++ new/gcc/stor-layout.c 2010-11-04 12:49:37 +0000
|
||||
@@ -593,11 +593,14 @@
|
||||
}
|
||||
|
||||
/* See if we can use an ordinary integer mode for a bit-field.
|
||||
- Conditions are: a fixed size that is correct for another mode
|
||||
- and occupying a complete byte or bytes on proper boundary. */
|
||||
+ Conditions are: a fixed size that is correct for another mode,
|
||||
+ occupying a complete byte or bytes on proper boundary,
|
||||
+ and not volatile or not -fstrict-volatile-bitfields. */
|
||||
if (TYPE_SIZE (type) != 0
|
||||
&& TREE_CODE (TYPE_SIZE (type)) == INTEGER_CST
|
||||
- && GET_MODE_CLASS (TYPE_MODE (type)) == MODE_INT)
|
||||
+ && GET_MODE_CLASS (TYPE_MODE (type)) == MODE_INT
|
||||
+ && !(TREE_THIS_VOLATILE (decl)
|
||||
+ && flag_strict_volatile_bitfields > 0))
|
||||
{
|
||||
enum machine_mode xmode
|
||||
= mode_for_size_tree (DECL_SIZE (decl), MODE_INT, 1);
|
||||
|
||||
=== added file 'gcc/testsuite/gcc.target/arm/volatile-bitfields-1.c'
|
||||
--- old/gcc/testsuite/gcc.target/arm/volatile-bitfields-1.c 1970-01-01 00:00:00 +0000
|
||||
+++ new/gcc/testsuite/gcc.target/arm/volatile-bitfields-1.c 2010-11-04 12:49:37 +0000
|
||||
@@ -0,0 +1,18 @@
|
||||
+/* { dg-require-effective-target arm_eabi } */
|
||||
+/* { dg-do compile } */
|
||||
+/* { dg-options "-O2" } */
|
||||
+
|
||||
+typedef struct {
|
||||
+ char a:1;
|
||||
+ char b:7;
|
||||
+ int c;
|
||||
+} BitStruct;
|
||||
+
|
||||
+volatile BitStruct bits;
|
||||
+
|
||||
+int foo ()
|
||||
+{
|
||||
+ return bits.b;
|
||||
+}
|
||||
+
|
||||
+/* { dg-final { scan-assembler "ldrb\[\\t \]+\[^\n\]*,\[\\t \]*\\\[\[^\n\]*\\\]" } } */
|
||||
|
||||
=== added file 'gcc/testsuite/gcc.target/arm/volatile-bitfields-2.c'
|
||||
--- old/gcc/testsuite/gcc.target/arm/volatile-bitfields-2.c 1970-01-01 00:00:00 +0000
|
||||
+++ new/gcc/testsuite/gcc.target/arm/volatile-bitfields-2.c 2010-11-04 12:49:37 +0000
|
||||
@@ -0,0 +1,18 @@
|
||||
+/* { dg-require-effective-target arm_eabi } */
|
||||
+/* { dg-do compile } */
|
||||
+/* { dg-options "-O2" } */
|
||||
+
|
||||
+typedef struct {
|
||||
+ volatile unsigned long a:8;
|
||||
+ volatile unsigned long b:8;
|
||||
+ volatile unsigned long c:16;
|
||||
+} BitStruct;
|
||||
+
|
||||
+BitStruct bits;
|
||||
+
|
||||
+unsigned long foo ()
|
||||
+{
|
||||
+ return bits.b;
|
||||
+}
|
||||
+
|
||||
+/* { dg-final { scan-assembler "ldr\[\\t \]+\[^\n\]*,\[\\t \]*\\\[\[^\n\]*\\\]" } } */
|
||||
|
||||
=== added file 'gcc/testsuite/gcc.target/arm/volatile-bitfields-3.c'
|
||||
--- old/gcc/testsuite/gcc.target/arm/volatile-bitfields-3.c 1970-01-01 00:00:00 +0000
|
||||
+++ new/gcc/testsuite/gcc.target/arm/volatile-bitfields-3.c 2010-11-04 12:49:37 +0000
|
||||
@@ -0,0 +1,18 @@
|
||||
+/* { dg-require-effective-target arm_eabi } */
|
||||
+/* { dg-do compile } */
|
||||
+/* { dg-options "-O2" } */
|
||||
+
|
||||
+typedef struct {
|
||||
+ volatile unsigned long a:8;
|
||||
+ volatile unsigned long b:8;
|
||||
+ volatile unsigned long c:16;
|
||||
+} BitStruct;
|
||||
+
|
||||
+BitStruct bits;
|
||||
+
|
||||
+unsigned long foo ()
|
||||
+{
|
||||
+ return bits.c;
|
||||
+}
|
||||
+
|
||||
+/* { dg-final { scan-assembler "ldr\[\\t \]+\[^\n\]*,\[\\t \]*\\\[\[^\n\]*\\\]" } } */
|
||||
|
||||
|
|
@ -0,0 +1,41 @@
|
|||
Backport from mainline:
|
||||
|
||||
gcc/
|
||||
2010-10-26 Jie Zhang <jie@codesourcery.com>
|
||||
|
||||
* doc/invoke.texi: Improve documentation of
|
||||
-fstrict-volatile-bitfields.
|
||||
|
||||
=== modified file 'gcc/doc/invoke.texi'
|
||||
--- old/gcc/doc/invoke.texi 2010-11-04 12:43:52 +0000
|
||||
+++ new/gcc/doc/invoke.texi 2010-11-04 14:29:09 +0000
|
||||
@@ -17633,8 +17633,8 @@
|
||||
@opindex fstrict-volatile-bitfields
|
||||
This option should be used if accesses to volatile bitfields (or other
|
||||
structure fields, although the compiler usually honors those types
|
||||
-anyway) should use a single access in a mode of the same size as the
|
||||
-container's type, aligned to a natural alignment if possible. For
|
||||
+anyway) should use a single access of the width of the
|
||||
+field's type, aligned to a natural alignment if possible. For
|
||||
example, targets with memory-mapped peripheral registers might require
|
||||
all such accesses to be 16 bits wide; with this flag the user could
|
||||
declare all peripheral bitfields as ``unsigned short'' (assuming short
|
||||
@@ -17647,11 +17647,13 @@
|
||||
any portion of the bitfield, or memory-mapped registers unrelated to
|
||||
the one being updated.
|
||||
|
||||
-If the target requires strict alignment, and honoring the container
|
||||
+If the target requires strict alignment, and honoring the field
|
||||
type would require violating this alignment, a warning is issued.
|
||||
-However, the access happens as the user requested, under the
|
||||
-assumption that the user knows something about the target hardware
|
||||
-that GCC is unaware of.
|
||||
+If the field has @code{packed} attribute, the access is done without
|
||||
+honoring the field type. If the field doesn't have @code{packed}
|
||||
+attribute, the access is done honoring the field type. In both cases,
|
||||
+GCC assumes that the user knows something about the target hardware
|
||||
+that it is unaware of.
|
||||
|
||||
The default value of this option is determined by the application binary
|
||||
interface for the target processor.
|
||||
|
||||
1257
recipes-devtools/gcc/gcc-4.5/linaro/gcc-4.5-linaro-r99429.patch
Normal file
1257
recipes-devtools/gcc/gcc-4.5/linaro/gcc-4.5-linaro-r99429.patch
Normal file
File diff suppressed because it is too large
Load Diff
|
|
@ -0,0 +1,70 @@
|
|||
2010-11-03 Nathan Froyd <froydnj@codesourcery.com>
|
||||
|
||||
Issue #10002
|
||||
|
||||
gcc/
|
||||
* config/arm/arm.c (arm_legitimate_index_p): Split
|
||||
VALID_NEON_QREG_MODE and VALID_NEON_DREG_MODE cases. Permit
|
||||
slightly larger constants in the latter case.
|
||||
(thumb2_legitimate_index_p): Likewise.
|
||||
|
||||
=== modified file 'gcc/config/arm/arm.c'
|
||||
--- old/gcc/config/arm/arm.c 2010-11-04 12:49:37 +0000
|
||||
+++ new/gcc/config/arm/arm.c 2010-11-11 11:00:53 +0000
|
||||
@@ -5611,13 +5611,25 @@
|
||||
&& INTVAL (index) > -1024
|
||||
&& (INTVAL (index) & 3) == 0);
|
||||
|
||||
- if (TARGET_NEON
|
||||
- && (VALID_NEON_DREG_MODE (mode) || VALID_NEON_QREG_MODE (mode)))
|
||||
+ /* For quad modes, we restrict the constant offset to be slightly less
|
||||
+ than what the instruction format permits. We do this because for
|
||||
+ quad mode moves, we will actually decompose them into two separate
|
||||
+ double-mode reads or writes. INDEX must therefore be a valid
|
||||
+ (double-mode) offset and so should INDEX+8. */
|
||||
+ if (TARGET_NEON && VALID_NEON_QREG_MODE (mode))
|
||||
return (code == CONST_INT
|
||||
&& INTVAL (index) < 1016
|
||||
&& INTVAL (index) > -1024
|
||||
&& (INTVAL (index) & 3) == 0);
|
||||
|
||||
+ /* We have no such constraint on double mode offsets, so we permit the
|
||||
+ full range of the instruction format. */
|
||||
+ if (TARGET_NEON && VALID_NEON_DREG_MODE (mode))
|
||||
+ return (code == CONST_INT
|
||||
+ && INTVAL (index) < 1024
|
||||
+ && INTVAL (index) > -1024
|
||||
+ && (INTVAL (index) & 3) == 0);
|
||||
+
|
||||
if (TARGET_REALLY_IWMMXT && VALID_IWMMXT_REG_MODE (mode))
|
||||
return (code == CONST_INT
|
||||
&& INTVAL (index) < 1024
|
||||
@@ -5731,13 +5743,25 @@
|
||||
&& (INTVAL (index) & 3) == 0);
|
||||
}
|
||||
|
||||
- if (TARGET_NEON
|
||||
- && (VALID_NEON_DREG_MODE (mode) || VALID_NEON_QREG_MODE (mode)))
|
||||
+ /* For quad modes, we restrict the constant offset to be slightly less
|
||||
+ than what the instruction format permits. We do this because for
|
||||
+ quad mode moves, we will actually decompose them into two separate
|
||||
+ double-mode reads or writes. INDEX must therefore be a valid
|
||||
+ (double-mode) offset and so should INDEX+8. */
|
||||
+ if (TARGET_NEON && VALID_NEON_QREG_MODE (mode))
|
||||
return (code == CONST_INT
|
||||
&& INTVAL (index) < 1016
|
||||
&& INTVAL (index) > -1024
|
||||
&& (INTVAL (index) & 3) == 0);
|
||||
|
||||
+ /* We have no such constraint on double mode offsets, so we permit the
|
||||
+ full range of the instruction format. */
|
||||
+ if (TARGET_NEON && VALID_NEON_DREG_MODE (mode))
|
||||
+ return (code == CONST_INT
|
||||
+ && INTVAL (index) < 1024
|
||||
+ && INTVAL (index) > -1024
|
||||
+ && (INTVAL (index) & 3) == 0);
|
||||
+
|
||||
if (arm_address_register_rtx_p (index, strict_p)
|
||||
&& (GET_MODE_SIZE (mode) <= 4))
|
||||
return 1;
|
||||
|
||||
|
|
@ -0,0 +1,40 @@
|
|||
2010-10-29 Julian Brown <julian@codesourcery.com>
|
||||
|
||||
Launchpad #629671
|
||||
|
||||
gcc/
|
||||
* config/arm/arm.h (REG_CLASS_CONTENTS): Remove soft frame pointer
|
||||
from CORE_REGS and GENERAL_REGS classes.
|
||||
* config/arm/arm.md (*thumb1_movsi_insn): Ignore all parts of final
|
||||
constraint for register preferencing.
|
||||
|
||||
=== modified file 'gcc/config/arm/arm.h'
|
||||
--- old/gcc/config/arm/arm.h 2010-11-04 10:45:05 +0000
|
||||
+++ new/gcc/config/arm/arm.h 2010-11-11 11:12:14 +0000
|
||||
@@ -1262,8 +1262,8 @@
|
||||
{ 0x0000DF00, 0x00000000, 0x00000000, 0x00000000 }, /* HI_REGS */ \
|
||||
{ 0x01000000, 0x00000000, 0x00000000, 0x00000000 }, /* CC_REG */ \
|
||||
{ 0x00000000, 0x00000000, 0x00000000, 0x80000000 }, /* VFPCC_REG */ \
|
||||
- { 0x0200DFFF, 0x00000000, 0x00000000, 0x00000000 }, /* GENERAL_REGS */ \
|
||||
- { 0x0200FFFF, 0x00000000, 0x00000000, 0x00000000 }, /* CORE_REGS */ \
|
||||
+ { 0x0000DFFF, 0x00000000, 0x00000000, 0x00000000 }, /* GENERAL_REGS */ \
|
||||
+ { 0x0000FFFF, 0x00000000, 0x00000000, 0x00000000 }, /* CORE_REGS */ \
|
||||
{ 0xFAFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x7FFFFFFF } /* ALL_REGS */ \
|
||||
}
|
||||
|
||||
|
||||
=== modified file 'gcc/config/arm/arm.md'
|
||||
--- old/gcc/config/arm/arm.md 2010-11-04 10:45:05 +0000
|
||||
+++ new/gcc/config/arm/arm.md 2010-11-11 11:12:14 +0000
|
||||
@@ -5160,8 +5160,8 @@
|
||||
})
|
||||
|
||||
(define_insn "*thumb1_movsi_insn"
|
||||
- [(set (match_operand:SI 0 "nonimmediate_operand" "=l,l,l,l,l,>,l, m,*lhk")
|
||||
- (match_operand:SI 1 "general_operand" "l, I,J,K,>,l,mi,l,*lhk"))]
|
||||
+ [(set (match_operand:SI 0 "nonimmediate_operand" "=l,l,l,l,l,>,l, m,*l*h*k")
|
||||
+ (match_operand:SI 1 "general_operand" "l, I,J,K,>,l,mi,l,*l*h*k"))]
|
||||
"TARGET_THUMB1
|
||||
&& ( register_operand (operands[0], SImode)
|
||||
|| register_operand (operands[1], SImode))"
|
||||
|
||||
|
|
@ -0,0 +1,30 @@
|
|||
2010-11-3 Chung-Lin Tang <cltang@codesourcery.com>
|
||||
|
||||
Backport from mainline:
|
||||
|
||||
2010-11-02 Chung-Lin Tang <cltang@codesourcery.com>
|
||||
|
||||
gcc/
|
||||
* Makefile.in (LIBGCC2_CFLAGS): Add -fno-stack-protector, to
|
||||
explicitly disable stack protection when building libgcc.
|
||||
(CRTSTUFF_CFLAGS): Same, for crtbegin/end.
|
||||
|
||||
--- old/gcc/Makefile.in 2010-11-08 22:08:43 +0000
|
||||
+++ new/gcc/Makefile.in 2010-11-11 11:34:59 +0000
|
||||
@@ -646,6 +646,7 @@
|
||||
LIBGCC2_CFLAGS = -O2 $(LIBGCC2_INCLUDES) $(GCC_CFLAGS) $(TARGET_LIBGCC2_CFLAGS) \
|
||||
$(LIBGCC2_DEBUG_CFLAGS) $(GTHREAD_FLAGS) \
|
||||
-DIN_LIBGCC2 -D__GCC_FLOAT_NOT_NEEDED \
|
||||
+ -fno-stack-protector \
|
||||
$(INHIBIT_LIBC_CFLAGS)
|
||||
|
||||
# Additional options to use when compiling libgcc2.a.
|
||||
@@ -659,6 +660,7 @@
|
||||
CRTSTUFF_CFLAGS = -O2 $(GCC_CFLAGS) $(INCLUDES) $(MULTILIB_CFLAGS) -g0 \
|
||||
-finhibit-size-directive -fno-inline -fno-exceptions \
|
||||
-fno-zero-initialized-in-bss -fno-toplevel-reorder -fno-tree-vectorize \
|
||||
+ -fno-stack-protector \
|
||||
$(INHIBIT_LIBC_CFLAGS)
|
||||
|
||||
# Additional sources to handle exceptions; overridden by targets as needed.
|
||||
|
||||
|
|
@ -0,0 +1,32 @@
|
|||
2010-11-08 Yao Qi <yao@codesourcery.com>
|
||||
|
||||
Backport from mainline:
|
||||
|
||||
gcc/
|
||||
2010-08-02 Bernd Schmidt <bernds@codesourcery.com>
|
||||
|
||||
* config/arm/arm.c (arm_rtx_costs_1): Remove second clause from the
|
||||
if statement which adds extra costs to frame-related
|
||||
expressions.
|
||||
|
||||
=== modified file 'gcc/config/arm/arm.c'
|
||||
--- old/gcc/config/arm/arm.c 2010-11-11 11:00:53 +0000
|
||||
+++ new/gcc/config/arm/arm.c 2010-11-11 11:50:33 +0000
|
||||
@@ -6805,12 +6805,10 @@
|
||||
since then they might not be moved outside of loops. As a compromise
|
||||
we allow integration with ops that have a constant as their second
|
||||
operand. */
|
||||
- if ((REG_OR_SUBREG_REG (XEXP (x, 0))
|
||||
- && ARM_FRAME_RTX (REG_OR_SUBREG_RTX (XEXP (x, 0)))
|
||||
- && GET_CODE (XEXP (x, 1)) != CONST_INT)
|
||||
- || (REG_OR_SUBREG_REG (XEXP (x, 0))
|
||||
- && ARM_FRAME_RTX (REG_OR_SUBREG_RTX (XEXP (x, 0)))))
|
||||
- *total = 4;
|
||||
+ if (REG_OR_SUBREG_REG (XEXP (x, 0))
|
||||
+ && ARM_FRAME_RTX (REG_OR_SUBREG_RTX (XEXP (x, 0)))
|
||||
+ && GET_CODE (XEXP (x, 1)) != CONST_INT)
|
||||
+ *total = COSTS_N_INSNS (1);
|
||||
|
||||
if (mode == DImode)
|
||||
{
|
||||
|
||||
209
recipes-devtools/gcc/gcc-4.5/linaro/gcc-4.5-linaro-r99436.patch
Normal file
209
recipes-devtools/gcc/gcc-4.5/linaro/gcc-4.5-linaro-r99436.patch
Normal file
|
|
@ -0,0 +1,209 @@
|
|||
2010-11-24 Maxim Kuvyrkov <maxim@codesourcery.com>
|
||||
|
||||
gcc/
|
||||
* combine.c (subst, combine_simlify_rtx): Add new argument, use it
|
||||
to track processing of conditionals. Update all callers.
|
||||
(try_combine, simplify_if_then_else): Update.
|
||||
|
||||
=== modified file 'gcc/combine.c'
|
||||
--- old/gcc/combine.c 2010-11-04 12:39:28 +0000
|
||||
+++ new/gcc/combine.c 2010-11-25 11:11:45 +0000
|
||||
@@ -392,8 +392,8 @@
|
||||
static void undo_all (void);
|
||||
static void undo_commit (void);
|
||||
static rtx *find_split_point (rtx *, rtx);
|
||||
-static rtx subst (rtx, rtx, rtx, int, int);
|
||||
-static rtx combine_simplify_rtx (rtx, enum machine_mode, int);
|
||||
+static rtx subst (rtx, rtx, rtx, int, int, int);
|
||||
+static rtx combine_simplify_rtx (rtx, enum machine_mode, int, int);
|
||||
static rtx simplify_if_then_else (rtx);
|
||||
static rtx simplify_set (rtx);
|
||||
static rtx simplify_logical (rtx);
|
||||
@@ -2944,12 +2944,12 @@
|
||||
if (i1)
|
||||
{
|
||||
subst_low_luid = DF_INSN_LUID (i1);
|
||||
- i1src = subst (i1src, pc_rtx, pc_rtx, 0, 0);
|
||||
+ i1src = subst (i1src, pc_rtx, pc_rtx, 0, 0, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
subst_low_luid = DF_INSN_LUID (i2);
|
||||
- i2src = subst (i2src, pc_rtx, pc_rtx, 0, 0);
|
||||
+ i2src = subst (i2src, pc_rtx, pc_rtx, 0, 0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2960,7 +2960,7 @@
|
||||
to avoid self-referential rtl. */
|
||||
|
||||
subst_low_luid = DF_INSN_LUID (i2);
|
||||
- newpat = subst (PATTERN (i3), i2dest, i2src, 0,
|
||||
+ newpat = subst (PATTERN (i3), i2dest, i2src, 0, 0,
|
||||
! i1_feeds_i3 && i1dest_in_i1src);
|
||||
substed_i2 = 1;
|
||||
|
||||
@@ -2991,7 +2991,7 @@
|
||||
|
||||
n_occurrences = 0;
|
||||
subst_low_luid = DF_INSN_LUID (i1);
|
||||
- newpat = subst (newpat, i1dest, i1src, 0, 0);
|
||||
+ newpat = subst (newpat, i1dest, i1src, 0, 0, 0);
|
||||
substed_i1 = 1;
|
||||
}
|
||||
|
||||
@@ -3053,7 +3053,7 @@
|
||||
else
|
||||
/* See comment where i2pat is assigned. */
|
||||
XVECEXP (newpat, 0, --total_sets)
|
||||
- = subst (i2pat, i1dest, i1src, 0, 0);
|
||||
+ = subst (i2pat, i1dest, i1src, 0, 0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4605,11 +4605,13 @@
|
||||
|
||||
IN_DEST is nonzero if we are processing the SET_DEST of a SET.
|
||||
|
||||
+ IN_COND is nonzero if we are on top level of the condition.
|
||||
+
|
||||
UNIQUE_COPY is nonzero if each substitution must be unique. We do this
|
||||
by copying if `n_occurrences' is nonzero. */
|
||||
|
||||
static rtx
|
||||
-subst (rtx x, rtx from, rtx to, int in_dest, int unique_copy)
|
||||
+subst (rtx x, rtx from, rtx to, int in_dest, int in_cond, int unique_copy)
|
||||
{
|
||||
enum rtx_code code = GET_CODE (x);
|
||||
enum machine_mode op0_mode = VOIDmode;
|
||||
@@ -4670,7 +4672,7 @@
|
||||
&& GET_CODE (XVECEXP (x, 0, 0)) == SET
|
||||
&& GET_CODE (SET_SRC (XVECEXP (x, 0, 0))) == ASM_OPERANDS)
|
||||
{
|
||||
- new_rtx = subst (XVECEXP (x, 0, 0), from, to, 0, unique_copy);
|
||||
+ new_rtx = subst (XVECEXP (x, 0, 0), from, to, 0, 0, unique_copy);
|
||||
|
||||
/* If this substitution failed, this whole thing fails. */
|
||||
if (GET_CODE (new_rtx) == CLOBBER
|
||||
@@ -4687,7 +4689,7 @@
|
||||
&& GET_CODE (dest) != CC0
|
||||
&& GET_CODE (dest) != PC)
|
||||
{
|
||||
- new_rtx = subst (dest, from, to, 0, unique_copy);
|
||||
+ new_rtx = subst (dest, from, to, 0, 0, unique_copy);
|
||||
|
||||
/* If this substitution failed, this whole thing fails. */
|
||||
if (GET_CODE (new_rtx) == CLOBBER
|
||||
@@ -4733,8 +4735,8 @@
|
||||
}
|
||||
else
|
||||
{
|
||||
- new_rtx = subst (XVECEXP (x, i, j), from, to, 0,
|
||||
- unique_copy);
|
||||
+ new_rtx = subst (XVECEXP (x, i, j), from, to, 0, 0,
|
||||
+ unique_copy);
|
||||
|
||||
/* If this substitution failed, this whole thing
|
||||
fails. */
|
||||
@@ -4811,7 +4813,9 @@
|
||||
&& (code == SUBREG || code == STRICT_LOW_PART
|
||||
|| code == ZERO_EXTRACT))
|
||||
|| code == SET)
|
||||
- && i == 0), unique_copy);
|
||||
+ && i == 0),
|
||||
+ code == IF_THEN_ELSE && i == 0,
|
||||
+ unique_copy);
|
||||
|
||||
/* If we found that we will have to reject this combination,
|
||||
indicate that by returning the CLOBBER ourselves, rather than
|
||||
@@ -4868,7 +4872,7 @@
|
||||
/* If X is sufficiently simple, don't bother trying to do anything
|
||||
with it. */
|
||||
if (code != CONST_INT && code != REG && code != CLOBBER)
|
||||
- x = combine_simplify_rtx (x, op0_mode, in_dest);
|
||||
+ x = combine_simplify_rtx (x, op0_mode, in_dest, in_cond);
|
||||
|
||||
if (GET_CODE (x) == code)
|
||||
break;
|
||||
@@ -4888,10 +4892,12 @@
|
||||
expression.
|
||||
|
||||
OP0_MODE is the original mode of XEXP (x, 0). IN_DEST is nonzero
|
||||
- if we are inside a SET_DEST. */
|
||||
+ if we are inside a SET_DEST. IN_COND is nonzero if we are on the top level
|
||||
+ of a condition. */
|
||||
|
||||
static rtx
|
||||
-combine_simplify_rtx (rtx x, enum machine_mode op0_mode, int in_dest)
|
||||
+combine_simplify_rtx (rtx x, enum machine_mode op0_mode, int in_dest,
|
||||
+ int in_cond)
|
||||
{
|
||||
enum rtx_code code = GET_CODE (x);
|
||||
enum machine_mode mode = GET_MODE (x);
|
||||
@@ -4946,8 +4952,8 @@
|
||||
false arms to store-flag values. Be careful to use copy_rtx
|
||||
here since true_rtx or false_rtx might share RTL with x as a
|
||||
result of the if_then_else_cond call above. */
|
||||
- true_rtx = subst (copy_rtx (true_rtx), pc_rtx, pc_rtx, 0, 0);
|
||||
- false_rtx = subst (copy_rtx (false_rtx), pc_rtx, pc_rtx, 0, 0);
|
||||
+ true_rtx = subst (copy_rtx (true_rtx), pc_rtx, pc_rtx, 0, 0, 0);
|
||||
+ false_rtx = subst (copy_rtx (false_rtx), pc_rtx, pc_rtx, 0, 0, 0);
|
||||
|
||||
/* If true_rtx and false_rtx are not general_operands, an if_then_else
|
||||
is unlikely to be simpler. */
|
||||
@@ -5291,7 +5297,7 @@
|
||||
{
|
||||
/* Try to simplify the expression further. */
|
||||
rtx tor = simplify_gen_binary (IOR, mode, XEXP (x, 0), XEXP (x, 1));
|
||||
- temp = combine_simplify_rtx (tor, mode, in_dest);
|
||||
+ temp = combine_simplify_rtx (tor, mode, in_dest, 0);
|
||||
|
||||
/* If we could, great. If not, do not go ahead with the IOR
|
||||
replacement, since PLUS appears in many special purpose
|
||||
@@ -5384,7 +5390,16 @@
|
||||
ZERO_EXTRACT is indeed appropriate, it will be placed back by
|
||||
the call to make_compound_operation in the SET case. */
|
||||
|
||||
- if (STORE_FLAG_VALUE == 1
|
||||
+ if (in_cond)
|
||||
+ /* Don't apply below optimizations if the caller would
|
||||
+ prefer a comparison rather than a value.
|
||||
+ E.g., for the condition in an IF_THEN_ELSE most targets need
|
||||
+ an explicit comparison. */
|
||||
+ {
|
||||
+ ;
|
||||
+ }
|
||||
+
|
||||
+ else if (STORE_FLAG_VALUE == 1
|
||||
&& new_code == NE && GET_MODE_CLASS (mode) == MODE_INT
|
||||
&& op1 == const0_rtx
|
||||
&& mode == GET_MODE (op0)
|
||||
@@ -5628,11 +5643,11 @@
|
||||
if (reg_mentioned_p (from, true_rtx))
|
||||
true_rtx = subst (known_cond (copy_rtx (true_rtx), true_code,
|
||||
from, true_val),
|
||||
- pc_rtx, pc_rtx, 0, 0);
|
||||
+ pc_rtx, pc_rtx, 0, 0, 0);
|
||||
if (reg_mentioned_p (from, false_rtx))
|
||||
false_rtx = subst (known_cond (copy_rtx (false_rtx), false_code,
|
||||
from, false_val),
|
||||
- pc_rtx, pc_rtx, 0, 0);
|
||||
+ pc_rtx, pc_rtx, 0, 0, 0);
|
||||
|
||||
SUBST (XEXP (x, 1), swapped ? false_rtx : true_rtx);
|
||||
SUBST (XEXP (x, 2), swapped ? true_rtx : false_rtx);
|
||||
@@ -5849,11 +5864,11 @@
|
||||
{
|
||||
temp = subst (simplify_gen_relational (true_code, m, VOIDmode,
|
||||
cond_op0, cond_op1),
|
||||
- pc_rtx, pc_rtx, 0, 0);
|
||||
+ pc_rtx, pc_rtx, 0, 0, 0);
|
||||
temp = simplify_gen_binary (MULT, m, temp,
|
||||
simplify_gen_binary (MULT, m, c1,
|
||||
const_true_rtx));
|
||||
- temp = subst (temp, pc_rtx, pc_rtx, 0, 0);
|
||||
+ temp = subst (temp, pc_rtx, pc_rtx, 0, 0, 0);
|
||||
temp = simplify_gen_binary (op, m, gen_lowpart (m, z), temp);
|
||||
|
||||
if (extend_op != UNKNOWN)
|
||||
|
||||
|
|
@ -0,0 +1,27 @@
|
|||
2010-11-24 Richard Sandiford <richard.sandiford@linaro.org>
|
||||
|
||||
Launchpad #618684
|
||||
|
||||
Backport from mainline:
|
||||
|
||||
2010-04-10 Bernd Schmidt <bernds@codesourcery.com>
|
||||
|
||||
* reload1.c (eliminate_regs_in_insn): Don't restore an operand
|
||||
if doing so would replace the entire pattern.
|
||||
|
||||
=== modified file 'gcc/reload1.c'
|
||||
--- old/gcc/reload1.c 2010-10-04 00:50:43 +0000
|
||||
+++ new/gcc/reload1.c 2010-11-24 13:40:23 +0000
|
||||
@@ -3567,7 +3567,10 @@
|
||||
{
|
||||
/* Restore the old body. */
|
||||
for (i = 0; i < recog_data.n_operands; i++)
|
||||
- *recog_data.operand_loc[i] = orig_operand[i];
|
||||
+ /* Restoring a top-level match_parallel would clobber the new_body
|
||||
+ we installed in the insn. */
|
||||
+ if (recog_data.operand_loc[i] != &PATTERN (insn))
|
||||
+ *recog_data.operand_loc[i] = orig_operand[i];
|
||||
for (i = 0; i < recog_data.n_dups; i++)
|
||||
*recog_data.dup_loc[i] = orig_operand[(int) recog_data.dup_num[i]];
|
||||
}
|
||||
|
||||
1500
recipes-devtools/gcc/gcc-4.5/linaro/gcc-4.5-linaro-r99439.patch
Normal file
1500
recipes-devtools/gcc/gcc-4.5/linaro/gcc-4.5-linaro-r99439.patch
Normal file
File diff suppressed because it is too large
Load Diff
|
|
@ -0,0 +1,78 @@
|
|||
2010-11-24 Chung-Lin Tang <cltang@codesourcery.com>
|
||||
|
||||
2010-07-08 Ramana Radhakrishnan <ramana.radhakrishnan@arm.com>
|
||||
|
||||
PR bootstrap/44768
|
||||
|
||||
* cfgexpand.c (estimated_stack_frame_size): Make self-contained
|
||||
with respect to current_function_decl. Pass decl of the function.
|
||||
* tree-inline.h (estimated_stack_frame_size): Adjust prototype.
|
||||
* ipa-inline.c (compute_inline_parameters): Pass decl to
|
||||
estimated_stack_frame_size.
|
||||
|
||||
=== modified file 'gcc/cfgexpand.c'
|
||||
--- old/gcc/cfgexpand.c 2010-10-04 00:50:43 +0000
|
||||
+++ new/gcc/cfgexpand.c 2010-11-24 08:43:48 +0000
|
||||
@@ -1248,8 +1248,8 @@
|
||||
stack_vars_alloc = stack_vars_num = 0;
|
||||
}
|
||||
|
||||
-/* Make a fair guess for the size of the stack frame of the current
|
||||
- function. This doesn't have to be exact, the result is only used
|
||||
+/* Make a fair guess for the size of the stack frame of the decl
|
||||
+ passed. This doesn't have to be exact, the result is only used
|
||||
in the inline heuristics. So we don't want to run the full stack
|
||||
var packing algorithm (which is quadratic in the number of stack
|
||||
vars). Instead, we calculate the total size of all stack vars.
|
||||
@@ -1257,11 +1257,14 @@
|
||||
vars doesn't happen very often. */
|
||||
|
||||
HOST_WIDE_INT
|
||||
-estimated_stack_frame_size (void)
|
||||
+estimated_stack_frame_size (tree decl)
|
||||
{
|
||||
HOST_WIDE_INT size = 0;
|
||||
size_t i;
|
||||
tree t, outer_block = DECL_INITIAL (current_function_decl);
|
||||
+ tree old_cur_fun_decl = current_function_decl;
|
||||
+ current_function_decl = decl;
|
||||
+ push_cfun (DECL_STRUCT_FUNCTION (decl));
|
||||
|
||||
init_vars_expansion ();
|
||||
|
||||
@@ -1284,7 +1287,8 @@
|
||||
size += account_stack_vars ();
|
||||
fini_vars_expansion ();
|
||||
}
|
||||
-
|
||||
+ pop_cfun ();
|
||||
+ current_function_decl = old_cur_fun_decl;
|
||||
return size;
|
||||
}
|
||||
|
||||
|
||||
=== modified file 'gcc/ipa-inline.c'
|
||||
--- old/gcc/ipa-inline.c 2010-06-30 21:30:12 +0000
|
||||
+++ new/gcc/ipa-inline.c 2010-11-24 08:43:48 +0000
|
||||
@@ -1967,7 +1967,7 @@
|
||||
|
||||
/* Estimate the stack size for the function. But not at -O0
|
||||
because estimated_stack_frame_size is a quadratic problem. */
|
||||
- self_stack_size = optimize ? estimated_stack_frame_size () : 0;
|
||||
+ self_stack_size = optimize ? estimated_stack_frame_size (node->decl) : 0;
|
||||
inline_summary (node)->estimated_self_stack_size = self_stack_size;
|
||||
node->global.estimated_stack_size = self_stack_size;
|
||||
node->global.stack_frame_offset = 0;
|
||||
|
||||
=== modified file 'gcc/tree-inline.h'
|
||||
--- old/gcc/tree-inline.h 2009-09-14 18:18:58 +0000
|
||||
+++ new/gcc/tree-inline.h 2010-11-24 08:43:48 +0000
|
||||
@@ -187,6 +187,6 @@
|
||||
extern tree remap_type (tree type, copy_body_data *id);
|
||||
extern gimple_seq copy_gimple_seq_and_replace_locals (gimple_seq seq);
|
||||
|
||||
-extern HOST_WIDE_INT estimated_stack_frame_size (void);
|
||||
+extern HOST_WIDE_INT estimated_stack_frame_size (tree);
|
||||
|
||||
#endif /* GCC_TREE_INLINE_H */
|
||||
|
||||
|
|
@ -0,0 +1,33 @@
|
|||
2010-11-25 Andrew Stubbs <ams@codesourcery.com>
|
||||
|
||||
Backport from mainline:
|
||||
|
||||
2010-10-28 Andrew Stubbs <ams@codesourcery.com>
|
||||
|
||||
gcc/
|
||||
* config/arm/arm.c (const_ok_for_arm): Support 0xXY00XY00 pattern
|
||||
constants in thumb2.
|
||||
|
||||
=== modified file 'gcc/config/arm/arm.c'
|
||||
--- old/gcc/config/arm/arm.c 2010-11-11 11:50:33 +0000
|
||||
+++ new/gcc/config/arm/arm.c 2010-12-10 15:30:47 +0000
|
||||
@@ -2340,11 +2340,17 @@
|
||||
{
|
||||
HOST_WIDE_INT v;
|
||||
|
||||
- /* Allow repeated pattern. */
|
||||
+ /* Allow repeated patterns 0x00XY00XY or 0xXYXYXYXY. */
|
||||
v = i & 0xff;
|
||||
v |= v << 16;
|
||||
if (i == v || i == (v | (v << 8)))
|
||||
return TRUE;
|
||||
+
|
||||
+ /* Allow repeated pattern 0xXY00XY00. */
|
||||
+ v = i & 0xff00;
|
||||
+ v |= v << 16;
|
||||
+ if (i == v)
|
||||
+ return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
2010-11-24 Maxim Kuvyrkov <maxim@codesourcery.com>
|
||||
|
||||
gcc/
|
||||
* loop-iv.c (get_biv_step): Workaround loop analysis ICE.
|
||||
|
||||
=== modified file 'gcc/loop-iv.c'
|
||||
--- old/gcc/loop-iv.c 2009-11-25 10:55:54 +0000
|
||||
+++ new/gcc/loop-iv.c 2010-12-10 15:32:04 +0000
|
||||
@@ -796,6 +796,13 @@
|
||||
outer_step))
|
||||
return false;
|
||||
|
||||
+ /* CSL local: workaround get_biv_step_1() inability to handle DU
|
||||
+ chains originating at sets of subregs. Such subregs are introduced
|
||||
+ by Tom's extension elimination pass. For upstream duscussion see
|
||||
+ http://gcc.gnu.org/ml/gcc/2010-11/msg00552.html . */
|
||||
+ if (!((*inner_mode == *outer_mode) != (*extend != UNKNOWN)))
|
||||
+ return false;
|
||||
+
|
||||
gcc_assert ((*inner_mode == *outer_mode) != (*extend != UNKNOWN));
|
||||
gcc_assert (*inner_mode != *outer_mode || *outer_step == const0_rtx);
|
||||
|
||||
|
||||
873
recipes-devtools/gcc/gcc-4.5/linaro/gcc-4.5-linaro-r99443.patch
Normal file
873
recipes-devtools/gcc/gcc-4.5/linaro/gcc-4.5-linaro-r99443.patch
Normal file
|
|
@ -0,0 +1,873 @@
|
|||
2010-11-26 Tom de Vries <tom@codesourcery.com>
|
||||
|
||||
gcc/
|
||||
* gcc/ee.c: New file.
|
||||
* gcc/tree-pass.h (pass_ee): Declare.
|
||||
* gcc/opts.c (decode_options): Set flag_ee at -O2.
|
||||
* gcc/timevar.def (TV_EE): New timevar.
|
||||
* gcc/common.opt (fextension-elimination): New option.
|
||||
* gcc/Makefile.in (ee.o): New rule.
|
||||
* gcc/passes.c (pass_ee): Add it.
|
||||
* gcc/testsuite/gcc.dg/extend-4.c: New test.
|
||||
* gcc/testsuite/gcc.dg/extend-1.c: New test.
|
||||
* gcc/testsuite/gcc.dg/extend-2.c: New test.
|
||||
* gcc/testsuite/gcc.dg/extend-2-64.c: New test.
|
||||
* gcc/testsuite/gcc.dg/extend-3.c: New test.
|
||||
|
||||
=== modified file 'gcc/Makefile.in'
|
||||
--- old/gcc/Makefile.in 2010-11-16 18:05:53 +0000
|
||||
+++ new/gcc/Makefile.in 2010-12-10 15:33:37 +0000
|
||||
@@ -1194,6 +1194,7 @@
|
||||
dse.o \
|
||||
dwarf2asm.o \
|
||||
dwarf2out.o \
|
||||
+ ee.o \
|
||||
ebitmap.o \
|
||||
emit-rtl.o \
|
||||
et-forest.o \
|
||||
@@ -2965,6 +2966,11 @@
|
||||
web.o : web.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \
|
||||
hard-reg-set.h $(FLAGS_H) $(BASIC_BLOCK_H) $(FUNCTION_H) output.h $(TOPLEV_H) \
|
||||
$(DF_H) $(OBSTACK_H) $(TIMEVAR_H) $(TREE_PASS_H)
|
||||
+ee.o : ee.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \
|
||||
+ hard-reg-set.h $(FLAGS_H) $(BASIC_BLOCK_H) $(FUNCTION_H) output.h \
|
||||
+ $(DF_H) $(TIMEVAR_H) tree-pass.h $(RECOG_H) $(EXPR_H) \
|
||||
+ $(REGS_H) $(TREE_H) $(TM_P_H) insn-config.h $(INSN_ATTR_H) $(TOPLEV_H) $(DIAGNOSTIC_CORE_H) \
|
||||
+ $(TARGET_H) $(OPTABS_H) insn-codes.h rtlhooks-def.h $(PARAMS_H) $(CGRAPH_H)
|
||||
gcse.o : gcse.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \
|
||||
$(REGS_H) hard-reg-set.h $(FLAGS_H) $(REAL_H) insn-config.h $(GGC_H) \
|
||||
$(RECOG_H) $(EXPR_H) $(BASIC_BLOCK_H) $(FUNCTION_H) output.h $(TOPLEV_H) \
|
||||
|
||||
=== modified file 'gcc/common.opt'
|
||||
--- old/gcc/common.opt 2010-11-04 12:43:52 +0000
|
||||
+++ new/gcc/common.opt 2010-12-10 15:33:37 +0000
|
||||
@@ -496,6 +496,10 @@
|
||||
Common Report Var(flag_early_inlining) Init(1) Optimization
|
||||
Perform early inlining
|
||||
|
||||
+fextension-elimination
|
||||
+Common Report Var(flag_ee) Init(0) Optimization
|
||||
+Perform extension elimination
|
||||
+
|
||||
feliminate-dwarf2-dups
|
||||
Common Report Var(flag_eliminate_dwarf2_dups)
|
||||
Perform DWARF2 duplicate elimination
|
||||
|
||||
=== added file 'gcc/ee.c'
|
||||
--- old/gcc/ee.c 1970-01-01 00:00:00 +0000
|
||||
+++ new/gcc/ee.c 2010-12-10 15:33:37 +0000
|
||||
@@ -0,0 +1,662 @@
|
||||
+/* Redundant extension elimination
|
||||
+ Copyright (C) 2010 Free Software Foundation, Inc.
|
||||
+ Contributed by Tom de Vries (tom@codesourcery.com)
|
||||
+
|
||||
+This file is part of GCC.
|
||||
+
|
||||
+GCC is free software; you can redistribute it and/or modify it under
|
||||
+the terms of the GNU General Public License as published by the Free
|
||||
+Software Foundation; either version 3, or (at your option) any later
|
||||
+version.
|
||||
+
|
||||
+GCC is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
+WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
+FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
+for more details.
|
||||
+
|
||||
+You should have received a copy of the GNU General Public License
|
||||
+along with GCC; see the file COPYING3. If not see
|
||||
+<http://www.gnu.org/licenses/>. */
|
||||
+
|
||||
+/*
|
||||
+
|
||||
+ MOTIVATING EXAMPLE
|
||||
+
|
||||
+ The motivating example for this pass is:
|
||||
+
|
||||
+ void f(unsigned char *p, short s, int c, int *z)
|
||||
+ {
|
||||
+ if (c)
|
||||
+ *z = 0;
|
||||
+ *p ^= (unsigned char)s;
|
||||
+ }
|
||||
+
|
||||
+ For MIPS, compilation results in the following insns.
|
||||
+
|
||||
+ (set (reg/v:SI 199)
|
||||
+ (sign_extend:SI (subreg:HI (reg:SI 200) 2)))
|
||||
+
|
||||
+ ...
|
||||
+
|
||||
+ (set (reg:QI 203)
|
||||
+ (subreg:QI (reg/v:SI 199) 3))
|
||||
+
|
||||
+ These insns are the only def and the only use of reg 199, each located in a
|
||||
+ different bb.
|
||||
+
|
||||
+ The sign-extension preserves the lower half of reg 200 and copies them to
|
||||
+ reg 199, and the subreg use of reg 199 only reads the least significant byte.
|
||||
+ The sign extension is therefore redundant (the extension part, not the copy
|
||||
+ part), and can safely be replaced with a regcopy from reg 200 to reg 199.
|
||||
+
|
||||
+
|
||||
+ OTHER SIGN/ZERO EXTENSION ELIMINATION PASSES
|
||||
+
|
||||
+ There are other passes which eliminate sign/zero-extension: combine and
|
||||
+ implicit_zee. Both attempt to eliminate extensions by combining them with
|
||||
+ other instructions. The combine pass does this at bb level,
|
||||
+ implicit_zee works at inter-bb level.
|
||||
+
|
||||
+ The combine pass combine an extension with either:
|
||||
+ - all uses of the extension, or
|
||||
+ - all defs of the operand of the extension.
|
||||
+ The implicit_zee pass only implements the latter.
|
||||
+
|
||||
+ For our motivating example, combine doesn't work since the def and the use of
|
||||
+ reg 199 are in a different bb.
|
||||
+
|
||||
+ Implicit_zee does not work since it only combines an extension with the defs
|
||||
+ of its operand.
|
||||
+
|
||||
+
|
||||
+ INTENDED EFFECT
|
||||
+
|
||||
+ This pass works by removing sign/zero-extensions, or replacing them with
|
||||
+ regcopies. The idea there is that the regcopy might be eliminated by a later
|
||||
+ pass. In case the regcopy cannot be eliminated, it might at least be cheaper
|
||||
+ than the extension.
|
||||
+
|
||||
+
|
||||
+ IMPLEMENTATION
|
||||
+
|
||||
+ The pass scans twice over all instructions.
|
||||
+
|
||||
+ The first scan registers all uses of a reg in the biggest_use array. After
|
||||
+ that first scan, the biggest_use array contains the size in bits of the
|
||||
+ biggest use of each reg.
|
||||
+
|
||||
+ The second scan finds extensions, determines whether they are redundant based
|
||||
+ on the biggest use, and deletes or replaces them.
|
||||
+
|
||||
+ In case that the src and dest reg of the replacement are not of the same size,
|
||||
+ we do not replace with a normal regcopy, but with a truncate or with the copy
|
||||
+ of a paradoxical subreg instead.
|
||||
+
|
||||
+
|
||||
+ LIMITATIONS
|
||||
+
|
||||
+ The scope of the analysis is limited to an extension and its uses. The other
|
||||
+ type of analysis (related to the defs of the operand of an extension) is not
|
||||
+ done.
|
||||
+
|
||||
+ Furthermore, we do the analysis of biggest use per reg. So when determining
|
||||
+ whether an extension is redundant, we take all uses of a the dest reg into
|
||||
+ account, also the ones that are not uses of the extension. This could be
|
||||
+ overcome by calculating the def-use chains and using those for analysis
|
||||
+ instead.
|
||||
+
|
||||
+ Finally, during the analysis each insn is looked at in isolation. There is no
|
||||
+ propagation of information during the analysis. To overcome this limitation,
|
||||
+ a backward iterative bit-level liveness analysis is needed. */
|
||||
+
|
||||
+
|
||||
+#include "config.h"
|
||||
+#include "system.h"
|
||||
+#include "coretypes.h"
|
||||
+#include "tm.h"
|
||||
+#include "rtl.h"
|
||||
+#include "tree.h"
|
||||
+#include "tm_p.h"
|
||||
+#include "flags.h"
|
||||
+#include "regs.h"
|
||||
+#include "hard-reg-set.h"
|
||||
+#include "basic-block.h"
|
||||
+#include "insn-config.h"
|
||||
+#include "function.h"
|
||||
+#include "expr.h"
|
||||
+#include "insn-attr.h"
|
||||
+#include "recog.h"
|
||||
+#include "toplev.h"
|
||||
+#include "target.h"
|
||||
+#include "timevar.h"
|
||||
+#include "optabs.h"
|
||||
+#include "insn-codes.h"
|
||||
+#include "rtlhooks-def.h"
|
||||
+#include "output.h"
|
||||
+#include "params.h"
|
||||
+#include "timevar.h"
|
||||
+#include "tree-pass.h"
|
||||
+#include "cgraph.h"
|
||||
+
|
||||
+#define SKIP_REG (-1)
|
||||
+
|
||||
+/* Array to register the biggest use of a reg, in bits. */
|
||||
+
|
||||
+static int *biggest_use;
|
||||
+
|
||||
+/* Forward declaration. */
|
||||
+
|
||||
+static void note_use (rtx *x, void *data);
|
||||
+
|
||||
+/* The following two functions are borrowed from trunk/gcc/toplev.c. They can be
|
||||
+ removed for a check-in into gcc trunk. */
|
||||
+
|
||||
+/* Given X, an unsigned number, return the number of least significant bits
|
||||
+ that are zero. When X == 0, the result is the word size. */
|
||||
+
|
||||
+static int
|
||||
+ctz_hwi (unsigned HOST_WIDE_INT x)
|
||||
+{
|
||||
+ return x ? floor_log2 (x & -x) : HOST_BITS_PER_WIDE_INT;
|
||||
+}
|
||||
+
|
||||
+/* Similarly for most significant bits. */
|
||||
+
|
||||
+static int
|
||||
+clz_hwi (unsigned HOST_WIDE_INT x)
|
||||
+{
|
||||
+ return HOST_BITS_PER_WIDE_INT - 1 - floor_log2(x);
|
||||
+}
|
||||
+
|
||||
+/* Check whether this is a paradoxical subreg. */
|
||||
+
|
||||
+static bool
|
||||
+paradoxical_subreg_p (rtx subreg)
|
||||
+{
|
||||
+ enum machine_mode subreg_mode, reg_mode;
|
||||
+
|
||||
+ if (GET_CODE (subreg) != SUBREG)
|
||||
+ return false;
|
||||
+
|
||||
+ subreg_mode = GET_MODE (subreg);
|
||||
+ reg_mode = GET_MODE (SUBREG_REG (subreg));
|
||||
+
|
||||
+ if (GET_MODE_SIZE (subreg_mode) > GET_MODE_SIZE (reg_mode))
|
||||
+ return true;
|
||||
+
|
||||
+ return false;
|
||||
+}
|
||||
+
|
||||
+/* Get the size and reg number of a REG or SUBREG use. */
|
||||
+
|
||||
+static bool
|
||||
+reg_use_p (rtx use, int *size, unsigned int *regno)
|
||||
+{
|
||||
+ rtx reg;
|
||||
+
|
||||
+ if (REG_P (use))
|
||||
+ {
|
||||
+ *regno = REGNO (use);
|
||||
+ *size = GET_MODE_BITSIZE (GET_MODE (use));
|
||||
+ return true;
|
||||
+ }
|
||||
+ else if (GET_CODE (use) == SUBREG)
|
||||
+ {
|
||||
+ reg = SUBREG_REG (use);
|
||||
+
|
||||
+ if (!REG_P (reg))
|
||||
+ return false;
|
||||
+
|
||||
+ *regno = REGNO (reg);
|
||||
+
|
||||
+ if (paradoxical_subreg_p (use))
|
||||
+ *size = GET_MODE_BITSIZE (GET_MODE (reg));
|
||||
+ else
|
||||
+ *size = subreg_lsb (use) + GET_MODE_BITSIZE (GET_MODE (use));
|
||||
+
|
||||
+ return true;
|
||||
+ }
|
||||
+
|
||||
+ return false;
|
||||
+}
|
||||
+
|
||||
+/* Register the use of a reg. */
|
||||
+
|
||||
+static void
|
||||
+register_use (int size, unsigned int regno)
|
||||
+{
|
||||
+ int *current = &biggest_use[regno];
|
||||
+
|
||||
+ if (*current == SKIP_REG)
|
||||
+ return;
|
||||
+
|
||||
+ *current = MAX (*current, size);
|
||||
+}
|
||||
+
|
||||
+/* Handle embedded uses. */
|
||||
+
|
||||
+static void
|
||||
+note_embedded_uses (rtx use, rtx pattern)
|
||||
+{
|
||||
+ const char *format_ptr;
|
||||
+ int i, j;
|
||||
+
|
||||
+ format_ptr = GET_RTX_FORMAT (GET_CODE (use));
|
||||
+ for (i = 0; i < GET_RTX_LENGTH (GET_CODE (use)); i++)
|
||||
+ if (format_ptr[i] == 'e')
|
||||
+ note_use (&XEXP (use, i), pattern);
|
||||
+ else if (format_ptr[i] == 'E')
|
||||
+ for (j = 0; j < XVECLEN (use, i); j++)
|
||||
+ note_use (&XVECEXP (use, i, j), pattern);
|
||||
+}
|
||||
+
|
||||
+/* Get the set that has use as its SRC operand. */
|
||||
+
|
||||
+static rtx
|
||||
+get_set (rtx use, rtx pattern)
|
||||
+{
|
||||
+ rtx sub;
|
||||
+ int i;
|
||||
+
|
||||
+ if (GET_CODE (pattern) == SET && SET_SRC (pattern) == use)
|
||||
+ return pattern;
|
||||
+
|
||||
+ if (GET_CODE (pattern) == PARALLEL)
|
||||
+ for (i = 0; i < XVECLEN (pattern, 0); ++i)
|
||||
+ {
|
||||
+ sub = XVECEXP (pattern, 0, i);
|
||||
+ if (GET_CODE (sub) == SET && SET_SRC (sub) == use)
|
||||
+ return sub;
|
||||
+ }
|
||||
+
|
||||
+ return NULL_RTX;
|
||||
+}
|
||||
+
|
||||
+/* Handle a restricted op use. In this context restricted means that a bit in an
|
||||
+ operand influences only the same bit or more significant bits in the result.
|
||||
+ The bitwise ops are a subclass, but PLUS is one as well. */
|
||||
+
|
||||
+static void
|
||||
+note_restricted_op_use (rtx use, unsigned int nr_operands, rtx pattern)
|
||||
+{
|
||||
+ unsigned int i, smallest;
|
||||
+ int operand_size[2];
|
||||
+ int used_size;
|
||||
+ unsigned int operand_regno[2];
|
||||
+ bool operand_reg[2];
|
||||
+ bool operand_ignore[2];
|
||||
+ rtx set;
|
||||
+
|
||||
+ /* Init operand_reg, operand_size, operand_regno and operand_ignore. */
|
||||
+ for (i = 0; i < nr_operands; ++i)
|
||||
+ {
|
||||
+ operand_reg[i] = reg_use_p (XEXP (use, i), &operand_size[i],
|
||||
+ &operand_regno[i]);
|
||||
+ operand_ignore[i] = false;
|
||||
+ }
|
||||
+
|
||||
+ /* Handle case of reg and-masked with const. */
|
||||
+ if (GET_CODE (use) == AND && CONST_INT_P (XEXP (use, 1)) && operand_reg[0])
|
||||
+ {
|
||||
+ used_size =
|
||||
+ HOST_BITS_PER_WIDE_INT - clz_hwi (UINTVAL (XEXP (use, 1)));
|
||||
+ operand_size[0] = MIN (operand_size[0], used_size);
|
||||
+ }
|
||||
+
|
||||
+ /* Handle case of reg or-masked with const. */
|
||||
+ if (GET_CODE (use) == IOR && CONST_INT_P (XEXP (use, 1)) && operand_reg[0])
|
||||
+ {
|
||||
+ used_size =
|
||||
+ HOST_BITS_PER_WIDE_INT - clz_hwi (~UINTVAL (XEXP (use, 1)));
|
||||
+ operand_size[0] = MIN (operand_size[0], used_size);
|
||||
+ }
|
||||
+
|
||||
+ /* Ignore the use of a in 'a = a + b'. */
|
||||
+ set = get_set (use, pattern);
|
||||
+ if (set != NULL_RTX && REG_P (SET_DEST (set)))
|
||||
+ for (i = 0; i < nr_operands; ++i)
|
||||
+ operand_ignore[i] = (operand_reg[i]
|
||||
+ && (REGNO (SET_DEST (set)) == operand_regno[i]));
|
||||
+
|
||||
+ /* Handle the case a reg is combined with don't care bits. */
|
||||
+ if (nr_operands == 2 && operand_reg[0] && operand_reg[1]
|
||||
+ && operand_size[0] != operand_size[1])
|
||||
+ {
|
||||
+ smallest = operand_size[0] > operand_size[1];
|
||||
+
|
||||
+ if (paradoxical_subreg_p (XEXP (use, smallest))
|
||||
+ && !SUBREG_PROMOTED_VAR_P (XEXP (use, smallest)))
|
||||
+ operand_size[1 - smallest] = operand_size[smallest];
|
||||
+ }
|
||||
+
|
||||
+ /* Register the operand use, if necessary. */
|
||||
+ for (i = 0; i < nr_operands; ++i)
|
||||
+ if (!operand_reg[i])
|
||||
+ note_use (&XEXP (use, i), pattern);
|
||||
+ else if (!operand_ignore[i])
|
||||
+ register_use (operand_size[i], operand_regno[i]);
|
||||
+}
|
||||
+
|
||||
+/* Handle all uses noted by note_uses. */
|
||||
+
|
||||
+static void
|
||||
+note_use (rtx *x, void *data)
|
||||
+{
|
||||
+ rtx use = *x;
|
||||
+ rtx pattern = (rtx)data;
|
||||
+ int use_size;
|
||||
+ unsigned int use_regno;
|
||||
+
|
||||
+ switch (GET_CODE (use))
|
||||
+ {
|
||||
+ case REG:
|
||||
+ case SUBREG:
|
||||
+ if (!reg_use_p (use, &use_size, &use_regno))
|
||||
+ {
|
||||
+ note_embedded_uses (use, pattern);
|
||||
+ return;
|
||||
+ }
|
||||
+ register_use (use_size, use_regno);
|
||||
+ return;
|
||||
+ case IOR:
|
||||
+ case AND:
|
||||
+ case XOR:
|
||||
+ case PLUS:
|
||||
+ case MINUS:
|
||||
+ note_restricted_op_use (use, 2, pattern);
|
||||
+ return;
|
||||
+ case NOT:
|
||||
+ case NEG:
|
||||
+ note_restricted_op_use (use, 1, pattern);
|
||||
+ return;
|
||||
+ case ASHIFT:
|
||||
+ if (!reg_use_p (XEXP (use, 0), &use_size, &use_regno)
|
||||
+ || !CONST_INT_P (XEXP (use, 1))
|
||||
+ || INTVAL (XEXP (use, 1)) <= 0
|
||||
+ || paradoxical_subreg_p (XEXP (use, 0)))
|
||||
+ {
|
||||
+ note_embedded_uses (use, pattern);
|
||||
+ return;
|
||||
+ }
|
||||
+ register_use (use_size - INTVAL (XEXP (use, 1)), use_regno);
|
||||
+ return;
|
||||
+ default:
|
||||
+ note_embedded_uses (use, pattern);
|
||||
+ return;
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+/* Check whether reg is implicitly used. */
|
||||
+
|
||||
+static bool
|
||||
+implicit_use_p (int regno)
|
||||
+{
|
||||
+#ifdef EPILOGUE_USES
|
||||
+ if (EPILOGUE_USES (regno))
|
||||
+ return true;
|
||||
+#endif
|
||||
+
|
||||
+#ifdef EH_USES
|
||||
+ if (EH_USES (regno))
|
||||
+ return true;
|
||||
+#endif
|
||||
+
|
||||
+ return false;
|
||||
+}
|
||||
+
|
||||
+/* Note the uses of argument registers in a call. */
|
||||
+
|
||||
+static void
|
||||
+note_call_uses (rtx insn)
|
||||
+{
|
||||
+ rtx link, link_expr;
|
||||
+
|
||||
+ if (!CALL_P (insn))
|
||||
+ return;
|
||||
+
|
||||
+ for (link = CALL_INSN_FUNCTION_USAGE (insn); link; link = XEXP (link, 1))
|
||||
+ {
|
||||
+ link_expr = XEXP (link, 0);
|
||||
+
|
||||
+ if (GET_CODE (link_expr) == USE)
|
||||
+ note_use (&XEXP (link_expr, 0), link);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+/* Calculate the biggest use mode for all regs. */
|
||||
+
|
||||
+static void
|
||||
+calculate_biggest_use (void)
|
||||
+{
|
||||
+ int i;
|
||||
+ basic_block bb;
|
||||
+ rtx insn;
|
||||
+
|
||||
+ /* Initialize biggest_use for all regs to 0. If a reg is used implicitly, we
|
||||
+ handle that reg conservatively and set it to SKIP_REG instead. */
|
||||
+ for (i = 0; i < max_reg_num (); i++)
|
||||
+ biggest_use[i] = ((implicit_use_p (i) || HARD_REGISTER_NUM_P (i))
|
||||
+ ? SKIP_REG : 0);
|
||||
+
|
||||
+ /* For all insns, call note_use for each use in insn. */
|
||||
+ FOR_EACH_BB (bb)
|
||||
+ FOR_BB_INSNS (bb, insn)
|
||||
+ {
|
||||
+ if (!NONDEBUG_INSN_P (insn))
|
||||
+ continue;
|
||||
+
|
||||
+ note_uses (&PATTERN (insn), note_use, PATTERN (insn));
|
||||
+
|
||||
+ if (CALL_P (insn))
|
||||
+ note_call_uses (insn);
|
||||
+ }
|
||||
+
|
||||
+ /* Dump the biggest uses found. */
|
||||
+ if (dump_file)
|
||||
+ for (i = 0; i < max_reg_num (); i++)
|
||||
+ if (biggest_use[i] > 0)
|
||||
+ fprintf (dump_file, "reg %d: size %d\n", i, biggest_use[i]);
|
||||
+}
|
||||
+
|
||||
+/* Check whether this is a sign/zero extension. */
|
||||
+
|
||||
+static bool
|
||||
+extension_p (rtx insn, rtx *dest, rtx *inner, int *preserved_size)
|
||||
+{
|
||||
+ rtx src, op0;
|
||||
+
|
||||
+ /* Detect set of reg. */
|
||||
+ if (GET_CODE (PATTERN (insn)) != SET)
|
||||
+ return false;
|
||||
+
|
||||
+ src = SET_SRC (PATTERN (insn));
|
||||
+ *dest = SET_DEST (PATTERN (insn));
|
||||
+
|
||||
+ if (!REG_P (*dest))
|
||||
+ return false;
|
||||
+
|
||||
+ /* Detect sign or zero extension. */
|
||||
+ if (GET_CODE (src) == ZERO_EXTEND || GET_CODE (src) == SIGN_EXTEND
|
||||
+ || (GET_CODE (src) == AND && CONST_INT_P (XEXP (src, 1))))
|
||||
+ {
|
||||
+ op0 = XEXP (src, 0);
|
||||
+
|
||||
+ /* Determine amount of least significant bits preserved by operation. */
|
||||
+ if (GET_CODE (src) == AND)
|
||||
+ *preserved_size = ctz_hwi (~UINTVAL (XEXP (src, 1)));
|
||||
+ else
|
||||
+ *preserved_size = GET_MODE_BITSIZE (GET_MODE (op0));
|
||||
+
|
||||
+ if (GET_CODE (op0) == SUBREG)
|
||||
+ {
|
||||
+ if (subreg_lsb (op0) != 0)
|
||||
+ return false;
|
||||
+
|
||||
+ *inner = SUBREG_REG (op0);
|
||||
+ return true;
|
||||
+ }
|
||||
+ else if (REG_P (op0))
|
||||
+ {
|
||||
+ *inner = op0;
|
||||
+ return true;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ return false;
|
||||
+}
|
||||
+
|
||||
+/* Check whether this is a redundant sign/zero extension. */
|
||||
+
|
||||
+static bool
|
||||
+redundant_extension_p (rtx insn, rtx *dest, rtx *inner)
|
||||
+{
|
||||
+ int biggest_dest_use;
|
||||
+ int preserved_size;
|
||||
+
|
||||
+ if (!extension_p (insn, dest, inner, &preserved_size))
|
||||
+ return false;
|
||||
+
|
||||
+ if (dump_file)
|
||||
+ fprintf (dump_file, "considering extension %u with preserved size %d\n",
|
||||
+ INSN_UID (insn), preserved_size);
|
||||
+
|
||||
+ biggest_dest_use = biggest_use[REGNO (*dest)];
|
||||
+
|
||||
+ if (biggest_dest_use == SKIP_REG)
|
||||
+ return false;
|
||||
+
|
||||
+ if (preserved_size < biggest_dest_use)
|
||||
+ return false;
|
||||
+
|
||||
+ if (dump_file)
|
||||
+ fprintf (dump_file, "found superfluous extension %u\n", INSN_UID (insn));
|
||||
+
|
||||
+ return true;
|
||||
+}
|
||||
+
|
||||
+/* Try to remove or replace the redundant extension. */
|
||||
+
|
||||
+static void
|
||||
+try_remove_or_replace_extension (rtx insn, rtx dest, rtx inner)
|
||||
+{
|
||||
+ rtx cp_src, cp_dest, seq, one;
|
||||
+
|
||||
+ if (GET_MODE_CLASS (GET_MODE (dest)) != GET_MODE_CLASS (GET_MODE (inner)))
|
||||
+ return;
|
||||
+
|
||||
+ /* Check whether replacement is needed. */
|
||||
+ if (dest != inner)
|
||||
+ {
|
||||
+ start_sequence ();
|
||||
+
|
||||
+ /* Determine the proper replacement operation. */
|
||||
+ if (GET_MODE (dest) == GET_MODE (inner))
|
||||
+ {
|
||||
+ cp_src = inner;
|
||||
+ cp_dest = dest;
|
||||
+ }
|
||||
+ else if (GET_MODE_SIZE (GET_MODE (dest))
|
||||
+ > GET_MODE_SIZE (GET_MODE (inner)))
|
||||
+ {
|
||||
+ emit_clobber (dest);
|
||||
+ cp_src = inner;
|
||||
+ cp_dest = gen_lowpart_SUBREG (GET_MODE (inner), dest);
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ cp_src = gen_rtx_TRUNCATE (GET_MODE (dest), inner);
|
||||
+ cp_dest = dest;
|
||||
+ }
|
||||
+
|
||||
+ emit_move_insn (cp_dest, cp_src);
|
||||
+
|
||||
+ seq = get_insns ();
|
||||
+ end_sequence ();
|
||||
+
|
||||
+ /* If the replacement is not supported, bail out. */
|
||||
+ for (one = seq; one != NULL_RTX; one = NEXT_INSN (one))
|
||||
+ if (recog_memoized (one) < 0 && GET_CODE (PATTERN (one)) != CLOBBER)
|
||||
+ return;
|
||||
+
|
||||
+ /* Insert the replacement. */
|
||||
+ emit_insn_before (seq, insn);
|
||||
+ }
|
||||
+
|
||||
+ /* Note replacement/removal in the dump. */
|
||||
+ if (dump_file)
|
||||
+ {
|
||||
+ fprintf (dump_file, "superfluous extension %u ", INSN_UID (insn));
|
||||
+ if (dest != inner)
|
||||
+ fprintf (dump_file, "replaced by %u\n", INSN_UID (seq));
|
||||
+ else
|
||||
+ fprintf (dump_file, "removed\n");
|
||||
+ }
|
||||
+
|
||||
+ /* Remove the extension. */
|
||||
+ delete_insn (insn);
|
||||
+}
|
||||
+
|
||||
+/* Find redundant extensions and remove or replace them if possible. */
|
||||
+
|
||||
+static void
|
||||
+remove_redundant_extensions (void)
|
||||
+{
|
||||
+ basic_block bb;
|
||||
+ rtx insn, next, dest, inner;
|
||||
+
|
||||
+ biggest_use = XNEWVEC (int, max_reg_num ());
|
||||
+ calculate_biggest_use ();
|
||||
+
|
||||
+ /* Remove redundant extensions. */
|
||||
+ FOR_EACH_BB (bb)
|
||||
+ FOR_BB_INSNS_SAFE (bb, insn, next)
|
||||
+ {
|
||||
+ if (!NONDEBUG_INSN_P (insn))
|
||||
+ continue;
|
||||
+
|
||||
+ if (!redundant_extension_p (insn, &dest, &inner))
|
||||
+ continue;
|
||||
+
|
||||
+ try_remove_or_replace_extension (insn, dest, inner);
|
||||
+ }
|
||||
+
|
||||
+ free (biggest_use);
|
||||
+}
|
||||
+
|
||||
+/* Remove redundant extensions. */
|
||||
+
|
||||
+static unsigned int
|
||||
+rest_of_handle_ee (void)
|
||||
+{
|
||||
+ remove_redundant_extensions ();
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+/* Run ee pass when flag_ee is set at optimization level > 0. */
|
||||
+
|
||||
+static bool
|
||||
+gate_handle_ee (void)
|
||||
+{
|
||||
+ return (optimize > 0 && flag_ee);
|
||||
+}
|
||||
+
|
||||
+struct rtl_opt_pass pass_ee =
|
||||
+{
|
||||
+ {
|
||||
+ RTL_PASS,
|
||||
+ "ee", /* name */
|
||||
+ gate_handle_ee, /* gate */
|
||||
+ rest_of_handle_ee, /* execute */
|
||||
+ NULL, /* sub */
|
||||
+ NULL, /* next */
|
||||
+ 0, /* static_pass_number */
|
||||
+ TV_EE, /* tv_id */
|
||||
+ 0, /* properties_required */
|
||||
+ 0, /* properties_provided */
|
||||
+ 0, /* properties_destroyed */
|
||||
+ 0, /* todo_flags_start */
|
||||
+ TODO_ggc_collect |
|
||||
+ TODO_dump_func |
|
||||
+ TODO_verify_rtl_sharing, /* todo_flags_finish */
|
||||
+ }
|
||||
+};
|
||||
|
||||
=== modified file 'gcc/opts.c'
|
||||
--- old/gcc/opts.c 2010-05-17 09:13:28 +0000
|
||||
+++ new/gcc/opts.c 2010-12-10 15:33:37 +0000
|
||||
@@ -907,6 +907,7 @@
|
||||
flag_tree_switch_conversion = opt2;
|
||||
flag_ipa_cp = opt2;
|
||||
flag_ipa_sra = opt2;
|
||||
+ flag_ee = opt2;
|
||||
|
||||
/* Track fields in field-sensitive alias analysis. */
|
||||
set_param_value ("max-fields-for-field-sensitive",
|
||||
|
||||
=== modified file 'gcc/passes.c'
|
||||
--- old/gcc/passes.c 2010-09-01 13:29:58 +0000
|
||||
+++ new/gcc/passes.c 2010-12-10 15:33:37 +0000
|
||||
@@ -974,6 +974,7 @@
|
||||
NEXT_PASS (pass_lower_subreg);
|
||||
NEXT_PASS (pass_df_initialize_opt);
|
||||
NEXT_PASS (pass_cse);
|
||||
+ NEXT_PASS (pass_ee);
|
||||
NEXT_PASS (pass_rtl_fwprop);
|
||||
NEXT_PASS (pass_rtl_cprop);
|
||||
NEXT_PASS (pass_rtl_pre);
|
||||
|
||||
=== added file 'gcc/testsuite/gcc.dg/extend-1.c'
|
||||
--- old/gcc/testsuite/gcc.dg/extend-1.c 1970-01-01 00:00:00 +0000
|
||||
+++ new/gcc/testsuite/gcc.dg/extend-1.c 2010-12-10 15:33:37 +0000
|
||||
@@ -0,0 +1,13 @@
|
||||
+/* { dg-do compile } */
|
||||
+/* { dg-options "-O2 -fdump-rtl-ee" } */
|
||||
+
|
||||
+void f(unsigned char * p, short s, int c, int *z)
|
||||
+{
|
||||
+ if (c)
|
||||
+ *z = 0;
|
||||
+ *p ^= (unsigned char)s;
|
||||
+}
|
||||
+
|
||||
+/* { dg-final { scan-rtl-dump-times "sign_extend:" 0 "ee" { target mips*-*-* } } } */
|
||||
+/* { dg-final { scan-rtl-dump-times "superfluous extension \[0-9\]+ replaced" 1 "ee" { target mips*-*-* } } } */
|
||||
+/* { dg-final { cleanup-rtl-dump "ee" } } */
|
||||
|
||||
=== added file 'gcc/testsuite/gcc.dg/extend-2-64.c'
|
||||
--- old/gcc/testsuite/gcc.dg/extend-2-64.c 1970-01-01 00:00:00 +0000
|
||||
+++ new/gcc/testsuite/gcc.dg/extend-2-64.c 2010-12-10 15:33:37 +0000
|
||||
@@ -0,0 +1,20 @@
|
||||
+/* { dg-do compile } */
|
||||
+/* { dg-options "-O2 -fdump-rtl-ee" } */
|
||||
+/* { dg-require-effective-target mips64 } */
|
||||
+
|
||||
+void f(unsigned char * p, short *s, int c)
|
||||
+{
|
||||
+ short or = 0;
|
||||
+ while (c)
|
||||
+ {
|
||||
+ or = or | s[c];
|
||||
+ c --;
|
||||
+ }
|
||||
+ *p = (unsigned char)or;
|
||||
+}
|
||||
+
|
||||
+/* { dg-final { scan-rtl-dump-times "zero_extend:" 1 "ee" { target mips*-*-* } } } */
|
||||
+/* { dg-final { scan-rtl-dump-times "sign_extend:" 0 "ee" { target mips*-*-* } } } */
|
||||
+/* { dg-final { scan-rtl-dump-times "superfluous extension \[0-9\]+ replaced" 3 "ee" { target mips*-*-* } } } */
|
||||
+/* { dg-final { cleanup-rtl-dump "ee" } } */
|
||||
+
|
||||
|
||||
=== added file 'gcc/testsuite/gcc.dg/extend-2.c'
|
||||
--- old/gcc/testsuite/gcc.dg/extend-2.c 1970-01-01 00:00:00 +0000
|
||||
+++ new/gcc/testsuite/gcc.dg/extend-2.c 2010-12-10 15:33:37 +0000
|
||||
@@ -0,0 +1,20 @@
|
||||
+/* { dg-do compile } */
|
||||
+/* { dg-options "-O2 -fdump-rtl-ee" } */
|
||||
+/* { dg-require-effective-target ilp32 } */
|
||||
+
|
||||
+void f(unsigned char * p, short *s, int c)
|
||||
+{
|
||||
+ short or = 0;
|
||||
+ while (c)
|
||||
+ {
|
||||
+ or = or | s[c];
|
||||
+ c --;
|
||||
+ }
|
||||
+ *p = (unsigned char)or;
|
||||
+}
|
||||
+
|
||||
+/* { dg-final { scan-rtl-dump-times "zero_extend" 0 "ee" { target mips*-*-* } } } */
|
||||
+/* { dg-final { scan-rtl-dump-times "sign_extend" 0 "ee" { target mips*-*-* } } } */
|
||||
+/* { dg-final { scan-rtl-dump-times "superfluous extension \[0-9\]+ replaced" 2 "ee" { target mips*-*-* } } } */
|
||||
+/* { dg-final { cleanup-rtl-dump "ee" } } */
|
||||
+
|
||||
|
||||
=== added file 'gcc/testsuite/gcc.dg/extend-3.c'
|
||||
--- old/gcc/testsuite/gcc.dg/extend-3.c 1970-01-01 00:00:00 +0000
|
||||
+++ new/gcc/testsuite/gcc.dg/extend-3.c 2010-12-10 15:33:37 +0000
|
||||
@@ -0,0 +1,12 @@
|
||||
+/* { dg-do compile } */
|
||||
+/* { dg-options "-O2 -fdump-rtl-ee" } */
|
||||
+
|
||||
+unsigned int f(unsigned char byte)
|
||||
+{
|
||||
+ return byte << 25;
|
||||
+}
|
||||
+
|
||||
+/* { dg-final { scan-rtl-dump-times "zero_extend:" 0 "ee" { target mips*-*-* } } } */
|
||||
+/* { dg-final { scan-rtl-dump "superfluous extension \[0-9\]+ replaced" "ee" { target mips*-*-* } } } */
|
||||
+/* { dg-final { cleanup-rtl-dump "ee" } } */
|
||||
+
|
||||
|
||||
=== added file 'gcc/testsuite/gcc.dg/extend-4.c'
|
||||
--- old/gcc/testsuite/gcc.dg/extend-4.c 1970-01-01 00:00:00 +0000
|
||||
+++ new/gcc/testsuite/gcc.dg/extend-4.c 2010-12-10 15:33:37 +0000
|
||||
@@ -0,0 +1,13 @@
|
||||
+/* { dg-do compile } */
|
||||
+/* { dg-options "-O2 -fdump-rtl-ee" } */
|
||||
+
|
||||
+unsigned char f(unsigned int a)
|
||||
+{
|
||||
+ unsigned int b = a & 0x10ff;
|
||||
+ return b;
|
||||
+}
|
||||
+
|
||||
+/* { dg-final { scan-rtl-dump-times "and:" 0 "ee" { target mips*-*-* } } } */
|
||||
+/* { dg-final { scan-rtl-dump-times "superfluous extension \[0-9\]+ replaced" 1 "ee" { target mips*-*-* } } } */
|
||||
+/* { dg-final { cleanup-rtl-dump "ee" } } */
|
||||
+
|
||||
|
||||
=== modified file 'gcc/timevar.def'
|
||||
--- old/gcc/timevar.def 2009-11-27 12:43:08 +0000
|
||||
+++ new/gcc/timevar.def 2010-12-10 15:33:37 +0000
|
||||
@@ -162,6 +162,7 @@
|
||||
DEFTIMEVAR (TV_VARCONST , "varconst")
|
||||
DEFTIMEVAR (TV_LOWER_SUBREG , "lower subreg")
|
||||
DEFTIMEVAR (TV_JUMP , "jump")
|
||||
+DEFTIMEVAR (TV_EE , "extension elimination")
|
||||
DEFTIMEVAR (TV_FWPROP , "forward prop")
|
||||
DEFTIMEVAR (TV_CSE , "CSE")
|
||||
DEFTIMEVAR (TV_DCE , "dead code elimination")
|
||||
|
||||
=== modified file 'gcc/tree-pass.h'
|
||||
--- old/gcc/tree-pass.h 2010-09-01 13:29:58 +0000
|
||||
+++ new/gcc/tree-pass.h 2010-12-10 15:33:37 +0000
|
||||
@@ -468,6 +468,7 @@
|
||||
extern struct rtl_opt_pass pass_initial_value_sets;
|
||||
extern struct rtl_opt_pass pass_unshare_all_rtl;
|
||||
extern struct rtl_opt_pass pass_instantiate_virtual_regs;
|
||||
+extern struct rtl_opt_pass pass_ee;
|
||||
extern struct rtl_opt_pass pass_rtl_fwprop;
|
||||
extern struct rtl_opt_pass pass_rtl_fwprop_addr;
|
||||
extern struct rtl_opt_pass pass_jump2;
|
||||
|
||||
183
recipes-devtools/gcc/gcc-4.5/linaro/gcc-4.5-linaro-r99444.patch
Normal file
183
recipes-devtools/gcc/gcc-4.5/linaro/gcc-4.5-linaro-r99444.patch
Normal file
|
|
@ -0,0 +1,183 @@
|
|||
2010-12-02 Bernd Schmidt <bernds@codesourcery.com>
|
||||
|
||||
Issue #10089
|
||||
|
||||
gcc/
|
||||
* expr.c (store_field): Avoid a direct store if the mode is larger
|
||||
than the size of the bit field.
|
||||
* stor-layout.c (layout_decl): If flag_strict_volatile_bitfields,
|
||||
treat non-volatile bit fields like volatile ones.
|
||||
* toplev.c (process_options): Disallow combination of
|
||||
-fstrict-volatile-bitfields and ABI versions less than 2.
|
||||
* config/arm/arm.c (arm_option_override): Don't enable
|
||||
flag_strict_volatile_bitfields if the ABI version is less than 2.
|
||||
* config/h8300/h8300.c (h8300_option_override): Likewise.
|
||||
* config/rx/rx.c (rx_option_override): Likewise.
|
||||
* config/m32c/m32c.c (m32c_option_override): Likewise.
|
||||
* config/sh/sh.c (sh_option_override): Likewise.
|
||||
|
||||
gcc/testsuite/
|
||||
* gcc.target/arm/volatile-bitfields-4.c: New test.
|
||||
* c-c++-common/abi-bf.c: New test.
|
||||
|
||||
=== modified file 'gcc/config/arm/arm.c'
|
||||
--- old/gcc/config/arm/arm.c 2010-12-10 15:30:47 +0000
|
||||
+++ new/gcc/config/arm/arm.c 2010-12-10 15:34:19 +0000
|
||||
@@ -1934,7 +1934,8 @@
|
||||
set_param_value ("gcse-unrestricted-cost", 2);
|
||||
|
||||
/* ARM EABI defaults to strict volatile bitfields. */
|
||||
- if (TARGET_AAPCS_BASED && flag_strict_volatile_bitfields < 0)
|
||||
+ if (TARGET_AAPCS_BASED && flag_strict_volatile_bitfields < 0
|
||||
+ && abi_version_at_least(2))
|
||||
flag_strict_volatile_bitfields = 1;
|
||||
|
||||
/* Register global variables with the garbage collector. */
|
||||
|
||||
=== modified file 'gcc/config/h8300/h8300.c'
|
||||
--- old/gcc/config/h8300/h8300.c 2010-11-04 12:43:52 +0000
|
||||
+++ new/gcc/config/h8300/h8300.c 2010-12-10 15:34:19 +0000
|
||||
@@ -405,7 +405,7 @@
|
||||
}
|
||||
|
||||
/* This target defaults to strict volatile bitfields. */
|
||||
- if (flag_strict_volatile_bitfields < 0)
|
||||
+ if (flag_strict_volatile_bitfields < 0 && abi_version_at_least(2))
|
||||
flag_strict_volatile_bitfields = 1;
|
||||
}
|
||||
|
||||
|
||||
=== modified file 'gcc/config/m32c/m32c.c'
|
||||
--- old/gcc/config/m32c/m32c.c 2010-11-04 12:43:52 +0000
|
||||
+++ new/gcc/config/m32c/m32c.c 2010-12-10 15:34:19 +0000
|
||||
@@ -430,7 +430,7 @@
|
||||
flag_ivopts = 0;
|
||||
|
||||
/* This target defaults to strict volatile bitfields. */
|
||||
- if (flag_strict_volatile_bitfields < 0)
|
||||
+ if (flag_strict_volatile_bitfields < 0 && abi_version_at_least(2))
|
||||
flag_strict_volatile_bitfields = 1;
|
||||
}
|
||||
|
||||
|
||||
=== modified file 'gcc/config/rx/rx.c'
|
||||
--- old/gcc/config/rx/rx.c 2010-11-04 12:43:52 +0000
|
||||
+++ new/gcc/config/rx/rx.c 2010-12-10 15:34:19 +0000
|
||||
@@ -2191,7 +2191,7 @@
|
||||
rx_option_override (void)
|
||||
{
|
||||
/* This target defaults to strict volatile bitfields. */
|
||||
- if (flag_strict_volatile_bitfields < 0)
|
||||
+ if (flag_strict_volatile_bitfields < 0 && abi_version_at_least(2))
|
||||
flag_strict_volatile_bitfields = 1;
|
||||
}
|
||||
|
||||
|
||||
=== modified file 'gcc/config/sh/sh.c'
|
||||
--- old/gcc/config/sh/sh.c 2010-11-04 12:43:52 +0000
|
||||
+++ new/gcc/config/sh/sh.c 2010-12-10 15:34:19 +0000
|
||||
@@ -952,7 +952,7 @@
|
||||
sh_fix_range (sh_fixed_range_str);
|
||||
|
||||
/* This target defaults to strict volatile bitfields. */
|
||||
- if (flag_strict_volatile_bitfields < 0)
|
||||
+ if (flag_strict_volatile_bitfields < 0 && abi_version_at_least(2))
|
||||
flag_strict_volatile_bitfields = 1;
|
||||
}
|
||||
|
||||
|
||||
=== modified file 'gcc/expr.c'
|
||||
--- old/gcc/expr.c 2010-11-04 12:43:52 +0000
|
||||
+++ new/gcc/expr.c 2010-12-10 15:34:19 +0000
|
||||
@@ -5848,6 +5848,8 @@
|
||||
|| bitpos % GET_MODE_ALIGNMENT (mode))
|
||||
&& SLOW_UNALIGNED_ACCESS (mode, MEM_ALIGN (target)))
|
||||
|| (bitpos % BITS_PER_UNIT != 0)))
|
||||
+ || (bitsize >= 0 && mode != BLKmode
|
||||
+ && GET_MODE_BITSIZE (mode) > bitsize)
|
||||
/* If the RHS and field are a constant size and the size of the
|
||||
RHS isn't the same size as the bitfield, we must use bitfield
|
||||
operations. */
|
||||
|
||||
=== modified file 'gcc/stor-layout.c'
|
||||
--- old/gcc/stor-layout.c 2010-11-26 12:03:32 +0000
|
||||
+++ new/gcc/stor-layout.c 2010-12-10 15:34:19 +0000
|
||||
@@ -621,12 +621,13 @@
|
||||
/* See if we can use an ordinary integer mode for a bit-field.
|
||||
Conditions are: a fixed size that is correct for another mode,
|
||||
occupying a complete byte or bytes on proper boundary,
|
||||
- and not volatile or not -fstrict-volatile-bitfields. */
|
||||
+ and not -fstrict-volatile-bitfields. If the latter is set,
|
||||
+ we unfortunately can't check TREE_THIS_VOLATILE, as a cast
|
||||
+ may make a volatile object later. */
|
||||
if (TYPE_SIZE (type) != 0
|
||||
&& TREE_CODE (TYPE_SIZE (type)) == INTEGER_CST
|
||||
&& GET_MODE_CLASS (TYPE_MODE (type)) == MODE_INT
|
||||
- && !(TREE_THIS_VOLATILE (decl)
|
||||
- && flag_strict_volatile_bitfields > 0))
|
||||
+ && flag_strict_volatile_bitfields <= 0)
|
||||
{
|
||||
enum machine_mode xmode
|
||||
= mode_for_size_tree (DECL_SIZE (decl), MODE_INT, 1);
|
||||
|
||||
=== added file 'gcc/testsuite/c-c++-common/abi-bf.c'
|
||||
--- old/gcc/testsuite/c-c++-common/abi-bf.c 1970-01-01 00:00:00 +0000
|
||||
+++ new/gcc/testsuite/c-c++-common/abi-bf.c 2010-12-10 15:34:19 +0000
|
||||
@@ -0,0 +1,3 @@
|
||||
+/* { dg-warning "incompatible" } */
|
||||
+/* { dg-do compile } */
|
||||
+/* { dg-options "-fstrict-volatile-bitfields -fabi-version=1" } */
|
||||
|
||||
=== added file 'gcc/testsuite/gcc.target/arm/volatile-bitfields-4.c'
|
||||
--- old/gcc/testsuite/gcc.target/arm/volatile-bitfields-4.c 1970-01-01 00:00:00 +0000
|
||||
+++ new/gcc/testsuite/gcc.target/arm/volatile-bitfields-4.c 2010-12-10 15:34:19 +0000
|
||||
@@ -0,0 +1,30 @@
|
||||
+/* { dg-require-effective-target arm_eabi } */
|
||||
+/* { dg-do compile } */
|
||||
+/* { dg-options "-O2" } */
|
||||
+/* { dg-final { scan-assembler-times "ldr\[\\t \]+\[^\n\]*,\[\\t \]*\\\[\[^\n\]*\\\]" 2 } } */
|
||||
+/* { dg-final { scan-assembler-times "str\[\\t \]+\[^\n\]*,\[\\t \]*\\\[\[^\n\]*\\\]" 2 } } */
|
||||
+/* { dg-final { scan-assembler-not "strb" } } */
|
||||
+
|
||||
+struct thing {
|
||||
+ unsigned a: 8;
|
||||
+ unsigned b: 8;
|
||||
+ unsigned c: 8;
|
||||
+ unsigned d: 8;
|
||||
+};
|
||||
+
|
||||
+struct thing2 {
|
||||
+ volatile unsigned a: 8;
|
||||
+ volatile unsigned b: 8;
|
||||
+ volatile unsigned c: 8;
|
||||
+ volatile unsigned d: 8;
|
||||
+};
|
||||
+
|
||||
+void test1(volatile struct thing *t)
|
||||
+{
|
||||
+ t->a = 5;
|
||||
+}
|
||||
+
|
||||
+void test2(struct thing2 *t)
|
||||
+{
|
||||
+ t->a = 5;
|
||||
+}
|
||||
|
||||
=== modified file 'gcc/toplev.c'
|
||||
--- old/gcc/toplev.c 2010-03-31 01:44:10 +0000
|
||||
+++ new/gcc/toplev.c 2010-12-10 15:34:19 +0000
|
||||
@@ -1851,6 +1851,13 @@
|
||||
sorry ("Graphite loop optimizations cannot be used");
|
||||
#endif
|
||||
|
||||
+ if (flag_strict_volatile_bitfields > 0 && !abi_version_at_least (2))
|
||||
+ {
|
||||
+ warning (0, "-fstrict-volatile-bitfield disabled; "
|
||||
+ "it is incompatible with ABI versions < 2");
|
||||
+ flag_strict_volatile_bitfields = 0;
|
||||
+ }
|
||||
+
|
||||
/* Unrolling all loops implies that standard loop unrolling must also
|
||||
be done. */
|
||||
if (flag_unroll_all_loops)
|
||||
|
||||
Loading…
Reference in New Issue
Block a user