diff mbox

[PR,target/59946] Avoid problems with addressing modes with -mpcrel

Message ID 54BF44AD.1090002@redhat.com
State New
Headers show

Commit Message

Jeff Law Jan. 21, 2015, 6:18 a.m. UTC
Well, I've got a m68k tree handy, so might as well continue pushing 
through these low priority bugs.

The problem here is the m68k doesn't support pc-rel addressing modes in 
both slots of a comparison instruction.   And while the operand 
predicates and constraints try to do the right thing, it's a rather 
convoluted mess because in some circumstances the output template with 
use %1,%0 and in others %0,%1.

It seems *far* easier to just punt this.  -mpcrel isn't that critical 
for the m68k.  And the m68k certainly isn't a priority these days.

I reviewed the other uses of pc-relative addressing and I think we're 
OK.  This is really an issue that just affects the comparison patterns.

I built the stage1-stage3 compilers with this change.  The stage3 
library build isn't complete, but I don't expect any issues.  I 
confirmed that with -mpcrel -m68000 that we'll load the address of the 
object into a temporary, then indirect through that for the comparison. 
  So the right things are happening here.

Installed on the trunk.  No plans to backport.
commit db4a2c00a2dfaeb2ee5ed02e7dcdbd20479ebfa1
Author: law <law@138bc75d-0d04-0410-961f-82ee72b054a4>
Date:   Wed Jan 21 06:17:50 2015 +0000

    2015-01-20  Jeff Law  <law@redhat.com>
    
    	PR target/59946
    	* config/m68k/m68k.md (Comparison expanders and patterns): Do not
    	allow pc-relative addresses in operand predicates or constraints.
    
    	PR target/59946
    	* gcc.target/m68k/pr59946.c: New test.
    
    git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@219927 138bc75d-0d04-0410-961f-82ee72b054a4
diff mbox

Patch

diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index ded76c4..9e4ad22 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,9 @@ 
+2015-01-20  Jeff Law  <law@redhat.com>
+
+	PR target/59946
+	* config/m68k/m68k.md (Comparison expanders and patterns): Do not
+	allow pc-relative addresses in operand predicates or constraints.
+
 2015-01-21  Bin Cheng  <bin.cheng@arm.com>
 
 	* config/arm/arm.c (arm_cortex_a53_tune, arm_cortex_a57_tune): Prefer
diff --git a/gcc/config/m68k/m68k.md b/gcc/config/m68k/m68k.md
index 2a314c3..d34ad1d 100644
--- a/gcc/config/m68k/m68k.md
+++ b/gcc/config/m68k/m68k.md
@@ -489,10 +489,19 @@ 
 
 
 ;; A composite of the cmp, cmpa, cmpi & cmpm m68000 op codes.
+;;
+;; In theory we ought to be able to use some 'S' constraints and
+;; operand predicates that allow PC-rel addressing modes in the
+;; comparison patterns and expanders below.   But we would have to be
+;; cognizant of the fact that PC-rel addresses are not allowed for
+;; both operands and determining whether or not we emit the operands in
+;; order or reversed is not trivial to do just based on the constraints
+;; and operand predicates.  So to be safe, just don't allow the PC-rel
+;; versions in the various comparison expanders, patterns, for comparisons.
 (define_insn ""
   [(set (cc0)
-        (compare (match_operand:SI 0 "nonimmediate_operand" "rKT,rKs,mSr,mSa,>")
-                 (match_operand:SI 1 "general_src_operand" "mSr,mSa,KTr,Ksr,>")))]
+        (compare (match_operand:SI 0 "nonimmediate_operand" "rKT,rKs,mr,ma,>")
+                 (match_operand:SI 1 "general_operand" "mr,ma,KTr,Ksr,>")))]
   "!TARGET_COLDFIRE"
 {
   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
@@ -529,7 +538,7 @@ 
 
 (define_expand "cbranchhi4"
   [(set (cc0)
-	(compare (match_operand:HI 1 "nonimmediate_src_operand" "")
+	(compare (match_operand:HI 1 "nonimmediate_operand" "")
 		 (match_operand:HI 2 "m68k_subword_comparison_operand" "")))
    (set (pc)
 	(if_then_else (match_operator 0 "ordered_comparison_operator"
@@ -551,8 +560,8 @@ 
 
 (define_insn ""
   [(set (cc0)
-        (compare (match_operand:HI 0 "nonimmediate_src_operand" "rnmS,d,n,mS,>")
-                 (match_operand:HI 1 "general_src_operand" "d,rnmS,mS,n,>")))]
+        (compare (match_operand:HI 0 "nonimmediate_operand" "rnm,d,n,m,>")
+                 (match_operand:HI 1 "general_operand" "d,rnm,m,n,>")))]
   "!TARGET_COLDFIRE"
 {
   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
@@ -568,7 +577,7 @@ 
 
 (define_expand "cbranchqi4"
   [(set (cc0)
-	(compare (match_operand:QI 1 "nonimmediate_src_operand" "")
+	(compare (match_operand:QI 1 "nonimmediate_operand" "")
 		 (match_operand:QI 2 "m68k_subword_comparison_operand" "")))
    (set (pc)
 	(if_then_else (match_operator 0 "ordered_comparison_operator"
@@ -580,7 +589,7 @@ 
 
 (define_expand "cstoreqi4"
   [(set (cc0)
-	(compare (match_operand:QI 2 "nonimmediate_src_operand" "")
+	(compare (match_operand:QI 2 "nonimmediate_operand" "")
 		 (match_operand:QI 3 "m68k_subword_comparison_operand" "")))
    (set (match_operand:QI 0 "register_operand")
 	(match_operator:QI 1 "ordered_comparison_operator"
@@ -590,8 +599,8 @@ 
 
 (define_insn ""
   [(set (cc0)
-        (compare (match_operand:QI 0 "nonimmediate_src_operand" "dn,dmS,>")
-                 (match_operand:QI 1 "general_src_operand" "dmS,nd,>")))]
+        (compare (match_operand:QI 0 "nonimmediate_operand" "dn,dm,>")
+                 (match_operand:QI 1 "general_operand" "dm,nd,>")))]
   "!TARGET_COLDFIRE"
 {
   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 3157bc0..006f67c 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@ 
+2015-01-20  Jeff Law  <law@redhat.com>
+
+	PR target/59946
+	* gcc.target/m68k/pr59946.c: New test.
+
 2015-01-20  Christophe Lyon  <christophe.lyon@linaro.org>
 
 	* gcc.target/aarch64/advsimd-intrinsics/vmlXl_n.inc: New file.
diff --git a/gcc/testsuite/gcc.target/m68k/pr59946.c b/gcc/testsuite/gcc.target/m68k/pr59946.c
new file mode 100644
index 0000000..c58083c
--- /dev/null
+++ b/gcc/testsuite/gcc.target/m68k/pr59946.c
@@ -0,0 +1,21 @@ 
+/* { dg-do compile } */
+/* { dg-options "-O2 -mpcrel -m68000" } */
+
+
+int copyNextDtaToAtari(void);
+char fsnextIsForUs;
+
+int custom_fsnext( void *sp )
+{
+        int res;
+
+        if(!fsnextIsForUs) {
+            return 0;
+        }
+
+        res = copyNextDtaToAtari();
+        return res;
+}
+
+
+