* config/rx/rx.h (LIBCALL_VALUE): Do not promote complex types.
authornickc <nickc@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 25 Jan 2011 14:32:52 +0000 (14:32 +0000)
committernickc <nickc@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 25 Jan 2011 14:32:52 +0000 (14:32 +0000)
* config/rx/rx.c (rx_function_value): Likewise.
(rx_promote_function_mode): Likewise.
(gen_safe_add): Place an outsized immediate value inside an UNSPEC
in order to make it legitimate.
* config/rx/rx.md (adddi3_internal): If the second operand is a
MEM make sure that the first operand is the same as the result
register.
(addsi3_unspec): Delete.
(subdi3): Do not accept immediate operands.
(subdi3_internal): Likewise.

* gcc.target/rx/builtins.c: Allow -fipa-cp-clone.
(saturate_add): Delete.
(exchange): Delete.
(main): Do not run saturate_add.
(set_interrupts): Delete.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@169232 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/config/rx/rx.c
gcc/config/rx/rx.h
gcc/config/rx/rx.md
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.target/rx/builtins.c

index 6e8a528..18f0f5f 100644 (file)
@@ -1,3 +1,17 @@
+2011-01-25  Nick Clifton  <nickc@redhat.com>
+
+       * config/rx/rx.h (LIBCALL_VALUE): Do not promote complex types.
+       * config/rx/rx.c (rx_function_value): Likewise.
+       (rx_promote_function_mode): Likewise.
+       (gen_safe_add): Place an outsized immediate value inside an UNSPEC
+       in order to make it legitimate.
+       * config/rx/rx.md (adddi3_internal): If the second operand is a
+       MEM make sure that the first operand is the same as the result
+       register.
+       (addsi3_unspec): Delete.
+       (subdi3): Do not accept immediate operands.
+       (subdi3_internal): Likewise.
+
 2011-01-25  Jeff Law  <law@redhat.com>
 
        PR rtl-optimization/37273
index f2429b7..8fa48a3 100644 (file)
@@ -874,7 +874,10 @@ rx_function_value (const_tree ret_type,
 
   /* RX ABI specifies that small integer types are
      promoted to int when returned by a function.  */
-  if (GET_MODE_SIZE (mode) > 0 && GET_MODE_SIZE (mode) < 4)
+  if (GET_MODE_SIZE (mode) > 0
+      && GET_MODE_SIZE (mode) < 4
+      && ! COMPLEX_MODE_P (mode)
+      )
     return gen_rtx_REG (SImode, FUNC_RETURN_REGNUM);
     
   return gen_rtx_REG (mode, FUNC_RETURN_REGNUM);
@@ -892,6 +895,7 @@ rx_promote_function_mode (const_tree type ATTRIBUTE_UNUSED,
 {
   if (for_return != 1
       || GET_MODE_SIZE (mode) >= 4
+      || COMPLEX_MODE_P (mode)
       || GET_MODE_SIZE (mode) < 1)
     return mode;
 
@@ -1324,7 +1328,10 @@ gen_safe_add (rtx dest, rtx src, rtx val, bool is_frame_related)
     insn = emit_insn (gen_addsi3 (dest, src, val));
   else
     {
-      insn = emit_insn (gen_addsi3_unspec (dest, src, val));
+      /* Wrap VAL in an UNSPEC so that rx_is_legitimate_constant
+        will not reject it.  */
+      val = gen_rtx_CONST (SImode, gen_rtx_UNSPEC (SImode, gen_rtvec (1, val), UNSPEC_CONST));
+      insn = emit_insn (gen_addsi3 (dest, src, val));
 
       if (is_frame_related)
        /* We have to provide our own frame related note here
index e2c8641..7acd3ce 100644 (file)
@@ -251,6 +251,7 @@ enum reg_class
 
 #define LIBCALL_VALUE(MODE)                            \
   gen_rtx_REG (((GET_MODE_CLASS (MODE) != MODE_INT     \
+                 || COMPLEX_MODE_P (MODE)              \
                 || GET_MODE_SIZE (MODE) >= 4)          \
                ? (MODE)                                \
                : SImode),                              \
index 9ab5f17..99b46b5 100644 (file)
 )
 
 (define_expand "adddi3"
-  [(set (match_operand:DI          0 "register_operand" "")
-       (plus:DI (match_operand:DI 1 "register_operand" "")
-                (match_operand:DI 2 "rx_source_operand" "")))]
+  [(set (match_operand:DI          0 "register_operand")
+       (plus:DI (match_operand:DI 1 "register_operand")
+                (match_operand:DI 2 "rx_source_operand")))]
   ""
 {
   rtx op0l, op0h, op1l, op1h, op2l, op2h;
 
   if (rtx_equal_p (op0l, op1l))
     ;
+  /* It is preferable that op0l == op1l...  */
   else if (rtx_equal_p (op0l, op2l))
     x = op1l, op1l = op2l, op2l = x;
+  /* ... but it is only a requirement if op2l == MEM.  */
+  else if (MEM_P (op2l))
+    {
+      /* Let's hope that we still have a scratch register free.  */
+      gcc_assert (op1h != scratch);
+      emit_move_insn (scratch, op2l);
+      op2l = scratch;
+    }
+
   emit_insn (gen_addsi3_flags (op0l, op1l, op2l));
 
   if (rtx_equal_p (op0h, op1h))
   DONE;
 })
 
-;; A pattern to add an integer to a register, regardless of the
-;; setting of the -mmax-constant-size command line switch.
-;; See rx.c:gen_safe_add() for more details.
-(define_insn "addsi3_unspec"
-  [(set (match_operand:SI          0 "register_operand"  "=r,r")
-       (plus:SI (match_operand:SI 1 "register_operand"  "%0,r")
-                (const:SI (unspec:SI [(match_operand 2 "const_int_operand" "n,n")] UNSPEC_CONST))))
-   (clobber (reg:CC CC_REG))]
-  ""
-  "@
-  add\t%2, %0
-  add\t%2, %1, %0"
-  [(set_attr "timings" "11")
-   (set_attr "length"   "6")]
-)
-
 (define_insn "andsi3"
   [(set (match_operand:SI         0 "register_operand"  "=r,r,r,r,r,r,r,r,r")
        (and:SI (match_operand:SI 1 "register_operand"  "%0,0,0,0,0,0,r,r,0")
 )
 
 (define_expand "subdi3"
-  [(set (match_operand:DI           0 "register_operand" "")
-       (minus:DI (match_operand:DI 1 "register_operand" "")
-                 (match_operand:DI 2 "rx_source_operand" "")))]
+  [(set (match_operand:DI           0 "register_operand")
+       (minus:DI (match_operand:DI 1 "register_operand")
+                 (match_operand:DI 2 "rx_compare_operand")))]
   ""
 {
   rtx op0l, op0h, op1l, op1h, op2l, op2h;
 (define_insn_and_split "subdi3_internal"
   [(set (match_operand:SI          0 "register_operand"   "=&r,&r")
        (minus:SI (match_operand:SI 2 "register_operand"  "  0, r")
-                 (match_operand:SI 3 "rx_source_operand" "rnQ, r")))
+                 (match_operand:SI 3 "rx_compare_operand" "rQ, r")))
    (set (match_operand:SI          1 "register_operand"   "= r, r")
        (minus:SI
          (minus:SI
index 4977ae6..edce298 100644 (file)
@@ -1,3 +1,11 @@
+2011-01-25  Nick Clifton  <nickc@redhat.com>
+
+       * gcc.target/rx/builtins.c: Allow -fipa-cp-clone.
+       (saturate_add): Delete.
+       (exchange): Delete.
+       (main): Do not run saturate_add.
+       (set_interrupts): Delete.
+
 2011-01-25  Tobias Burnus  <burnus@net-b.de>
 
        PR fortran/47448
index 2a6241d..d503ed3 100644 (file)
@@ -1,12 +1,6 @@
 /* { dg-do run } */
-/* { dg-options "-fno-ipa-cp-clone" } */
 
 /* Verify that the RX specific builtin functions work.  */
-
-/* IPA CP cloning is disabled because the constant propagation
-   has no understanding of the saturation behaviour of the
-   __builtin_rx_sat function and so it will optimize away the
-   saturation addition test.  */
    
 #include <stdlib.h>
 #include <stdio.h>
@@ -25,20 +19,6 @@ half_word_swap (int arg)
   return __builtin_rx_revw (arg);
 }
 
-int
-saturate_add (int arg1, int arg2)
-{
-  arg1 += arg2;
-  return __builtin_rx_sat (arg1);
-}
-
-int
-exchange (int arg1, int arg2)
-{
-  arg1 = __builtin_rx_xchg (arg2);
-  return arg1;
-}
-
 long
 multiply_and_accumulate (long arg1, long arg2, long arg3)
 {
@@ -118,7 +98,6 @@ int
 main (void)
 {
   CHECK_1ARG (half_word_swap, 0x12345678, 0x34127856);
-  CHECK_2ARG (saturate_add, 0x80000000, 0x80000000, 0x80000000);
   CHECK_3ARG (multiply_and_accumulate, 0x111, 0x222, 0x333, 0x70007);
   CHECK_1ARG (rxround, 0.5, 1);
   return 0;
@@ -163,9 +142,3 @@ rmpa (int * multiplicand, int * multiplier, int num)
 {
   __builtin_rx_rmpa ();
 }
-
-void
-set_interrupts (void)
-{
-  __builtin_mvtipl (3);
-}