]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
re PR target/56351 (ARM Big-Endian: storing local double to packed variable causes...
authorSeth LaForge <sethml@google.com>
Thu, 14 Mar 2013 18:52:18 +0000 (18:52 +0000)
committerEric Botcazou <ebotcazou@gcc.gnu.org>
Thu, 14 Mar 2013 18:52:18 +0000 (18:52 +0000)
PR target/56351
Backport from mainline
2012-10-22  Julian Brown  <julian@codesourcery.com>

* config/arm/arm.h (CANNOT_CHANGE_MODE_CLASS): Avoid subreg'ing
VFP D registers in big-endian mode.

From-SVN: r196664

gcc/ChangeLog
gcc/config/arm/arm.h

index 9c68a7e1aad877b8f7c6b6c5163d4ce184b0894e..0743138f770f72e46527b8d110c5560f29fdc53d 100644 (file)
@@ -1,3 +1,12 @@
+2013-03-14  Seth LaForge  <sethml@google.com>
+
+       PR target/56351
+       Backport from mainline
+       2012-10-22  Julian Brown  <julian@codesourcery.com>
+
+       * config/arm/arm.h (CANNOT_CHANGE_MODE_CLASS): Avoid subreg'ing
+       VFP D registers in big-endian mode.
+
 2013-03-08  Joey Ye  <joey.ye@arm.com>
 
        Backport from mainline
index a3db5c4d60086f2e1dad31a3b23946179068b3f3..fbbf041a4fb3602c5d28df68cb3fe97c6e972625 100644 (file)
@@ -1126,11 +1126,18 @@ enum reg_class
 /* FPA registers can't do subreg as all values are reformatted to internal
    precision.  In VFPv1, VFP registers could only be accessed in the mode
    they were set, so subregs would be invalid there too.  However, we don't
-   support VFPv1 at the moment, and the restriction was lifted in VFPv2.  */
+   support VFPv1 at the moment, and the restriction was lifted in VFPv2.
+   In big-endian mode, modes greater than word size (i.e. DFmode) are stored in
+   VFP registers in little-endian order.  We can't describe that accurately to
+   GCC, so avoid taking subregs of such values.  */
 #define CANNOT_CHANGE_MODE_CLASS(FROM, TO, CLASS)              \
-  (GET_MODE_SIZE (FROM) != GET_MODE_SIZE (TO)                  \
-   ? reg_classes_intersect_p (FPA_REGS, (CLASS))               \
-   : 0)
+  (TARGET_VFP                                                  \
+  ? TARGET_BIG_END                                             \
+    && (GET_MODE_SIZE (FROM) > UNITS_PER_WORD                  \
+       || GET_MODE_SIZE (TO) > UNITS_PER_WORD)                 \
+    && reg_classes_intersect_p (VFP_REGS, (CLASS))             \
+  : GET_MODE_SIZE (FROM) != GET_MODE_SIZE (TO)                 \
+    && reg_classes_intersect_p (FPA_REGS, (CLASS)))
 
 /* The class value for index registers, and the one for base regs.  */
 #define INDEX_REG_CLASS  (TARGET_THUMB1 ? LO_REGS : GENERAL_REGS)