In PIC mode, make sure that a constant source address is legitimate.
authorScott Bambrough <scottb@netwinder.org>
Wed, 9 Feb 2000 20:53:35 +0000 (20:53 +0000)
committerNick Clifton <nickc@gcc.gnu.org>
Wed, 9 Feb 2000 20:53:35 +0000 (20:53 +0000)
From-SVN: r31873

gcc/ChangeLog
gcc/config/arm/arm.md

index 2e17b20..8c9a4a9 100644 (file)
@@ -1,3 +1,8 @@
+2000-02-09  Scott Bambrough  <scottb@netwinder.org>
+
+        * config/arm/arm.md (movsi): In PIC mode, make sure that a
+        constant source address is legitimate.
+
 2000-02-09  Philip Blundell  <pb@futuretv.com>
 
         * config/arm/arm.c (legitimize_pic_address): Handle LABEL_REF
index ed49d70..b1bd09e 100644 (file)
                           : preserve_subexpressions_p ()));
       DONE;
     }
-  if (CONSTANT_P (operands[1]) && flag_pic)
+  if (flag_pic
+      && (CONSTANT_P (operands[1])
+        || symbol_mentioned_p (operands[1])
+        || label_mentioned_p (operands[1])))
     operands[1] = legitimize_pic_address (operands[1], SImode,
                                          ((reload_in_progress
                                            || reload_completed)
 (define_expand "call"
   [(parallel [(call (match_operand 0 "memory_operand" "")
                    (match_operand 1 "general_operand" ""))
+             (use (match_operand 2 "" ""))
              (clobber (reg:SI 14))])]
   ""
   "
   {
-    if (TARGET_LONG_CALLS && GET_CODE (XEXP (operands[0], 0)) != REG)
-      XEXP (operands[0], 0) = force_reg (Pmode, XEXP (operands[0], 0));
+    rtx callee = XEXP (operands[0], 0);
+    
+    /* Decide if we need to generate an indirect call by loading the 32 bit
+       address of the callee into a register and then jumping to the contents
+       of that register.  operands[2] contains the long_call / short_call
+       attribute.  The third parameter to arm_is_longcall_p tells it that it
+       is being passed a (MEM) and not a SYMREF().  */
+     
+    /* In an untyped call, we can get NULL for operand 2.  */
+    if (operands[2] == NULL_RTX)
+      operands[2] = const0_rtx;
+      
+    if (GET_CODE (callee) != REG
+       && arm_is_longcall_p (operands[0], INTVAL (operands[2]), 0))
+      XEXP (operands[0], 0) = force_reg (Pmode, callee);
   }"
 )
 
 (define_insn "*call_reg"
   [(call (mem:SI (match_operand:SI 0 "s_register_operand" "r"))
          (match_operand 1 "" "g"))
+   (use (match_operand:SI 2 "immediate_operand" "n"))
    (clobber (reg:SI 14))]
   ""
   "*
 (define_insn "*call_mem"
   [(call (mem:SI (match_operand:SI 0 "memory_operand" "m"))
         (match_operand 1 "general_operand" "g"))
+   (use (match_operand:SI 2 "" ""))
    (clobber (reg:SI 14))]
   ""
   "*
   [(parallel [(set (match_operand 0 "" "=rf")
                   (call (match_operand 1 "memory_operand" "m")
                         (match_operand 2 "general_operand" "g")))
+             (use (match_operand:SI 3 "" ""))
              (clobber (reg:SI 14))])]
   ""
   "
   {
-    if (TARGET_LONG_CALLS && GET_CODE (XEXP (operands[1], 0)) != REG)
-      XEXP (operands[1], 0) = force_reg (Pmode, XEXP (operands[1], 0));
+    rtx callee = XEXP (operands[1], 0);
+    
+    /* In an untyped call, we can get NULL for operand 2.  */
+    if (operands[3] == 0)
+      operands[3] = const0_rtx;
+      
+    /* See the comment in define_expand \"call\".  */
+    if (GET_CODE (callee) != REG
+       && arm_is_longcall_p (operands[1], INTVAL (operands[3]), 0))
+       XEXP (operands[1], 0) = force_reg (Pmode, callee);
   }"
 )
 
   [(set (match_operand 0 "" "=rf")
         (call (mem:SI (match_operand:SI 1 "s_register_operand" "r"))
              (match_operand 2 "general_operand" "g")))
+   (use (match_operand 3 "" ""))
    (clobber (reg:SI 14))]
   ""
   "*
   [(set (match_operand 0 "" "=rf")
        (call (mem:SI (match_operand 1 "memory_operand" "m"))
        (match_operand 2 "general_operand" "g")))
+   (use (match_operand 3 "" ""))
    (clobber (reg:SI 14))]
   "! CONSTANT_ADDRESS_P (XEXP (operands[1], 0))"
   "*
 (define_insn "*call_symbol"
   [(call (mem:SI (match_operand:SI 0 "" "X"))
         (match_operand:SI 1 "general_operand" "g"))
+   (use (match_operand 2 "" ""))
    (clobber (reg:SI 14))]
-  "! TARGET_LONG_CALLS && GET_CODE (operands[0]) == SYMBOL_REF"
+  "! arm_is_longcall_p (operands[0], INTVAL (operands[2]), 1)
+   && GET_CODE (operands[0]) == SYMBOL_REF"
   "*
   {
     return NEED_PLT_RELOC ? \"bl%?\\t%a0(PLT)\" : \"bl%?\\t%a0\";
   [(set (match_operand 0 "s_register_operand" "=rf")
        (call (mem:SI (match_operand:SI 1 "" "X"))
        (match_operand:SI 2 "general_operand" "g")))
+   (use (match_operand 3 "" ""))
    (clobber (reg:SI 14))]
-  "! TARGET_LONG_CALLS && GET_CODE(operands[1]) == SYMBOL_REF"
+  "! arm_is_longcall_p (operands[1], INTVAL (operands[3]), 1)
+   && GET_CODE (operands[1]) == SYMBOL_REF"
   "*
   {
     return NEED_PLT_RELOC ? \"bl%?\\t%a1(PLT)\" : \"bl%?\\t%a1\";