c4x.md (storeqf_int, [...]): Add new patterns with corresponding splitters to handle...
authorMichael Hayes <m.hayes@elec.canterbury.ac.nz>
Tue, 13 Apr 1999 15:38:12 +0000 (15:38 +0000)
committerMichael Hayes <m.hayes@gcc.gnu.org>
Tue, 13 Apr 1999 15:38:12 +0000 (15:38 +0000)
* config/c4x/c4x.md (storeqf_int, storeqf_int_clobber, loadqf_int,
  loadqf_int_clobber): Add new patterns with corresponding splitters
  to handle moves of floating point values into and out of intager
  registers by using memory.
* config/c4x/c4x.c (c4x_check_legit_addr): Disallow PRE_INC for modes
other than QFmode and QImode.
(mixed_subreg_operand): New function.
(c4x_emit_move_sequence): If moving a floating point value into or
out of an integer register, use the new patterns storeqf_int_clobber
or loadqf_int_clobber.
(reg_imm_operand, *_reg_operand): Call reg_operand instead of
register_operand.
(reg_operand, src_operand): Disallow operand if it satisifes
mixed_subreg_operand.
* config/c4x/c4x.h (mixed_subreg_operand): Add prototype.

From-SVN: r26413

gcc/ChangeLog
gcc/config/c4x/c4x.c
gcc/config/c4x/c4x.h
gcc/config/c4x/c4x.md

index 57a182508250a32e4406fd5fa7ac8976099203bd..929a5700afdf3cdf5be7d7b35290d54acfb7638b 100644 (file)
@@ -1,3 +1,23 @@
+Wed Apr 14 10:04:27 1999  Michael Hayes  <m.hayes@elec.canterbury.ac.nz>
+
+       * config/c4x/c4x.md (storeqf_int, storeqf_int_clobber, loadqf_int,
+       loadqf_int_clobber): Add new patterns with corresponding splitters
+       to handle moves of floating point values into and out of intager
+       registers by using memory.
+
+       * config/c4x/c4x.c (c4x_check_legit_addr): Disallow PRE_INC for modes
+       other than QFmode and QImode.
+       (mixed_subreg_operand): New function.
+       (c4x_emit_move_sequence): If moving a floating point value into or
+       out of an integer register, use the new patterns storeqf_int_clobber
+       or loadqf_int_clobber.
+       (reg_imm_operand, *_reg_operand): Call reg_operand instead of 
+       register_operand.
+       (reg_operand, src_operand): Disallow operand if it satisifes
+       mixed_subreg_operand.
+
+       * config/c4x/c4x.h (mixed_subreg_operand): Add prototype.
+
 Tue Apr 13 14:49:13 1999  Jan Hubicka <hubicka@freesoft.cz>
 
        * i386.c (agi_dependent): Handle push operation more correctly.
index e8cee04cf403afa6f3076a5a4912e99967bf40f9..61cf7b70505fe9c35f7bf03822c630e9764f260a 100644 (file)
@@ -1099,6 +1099,56 @@ c4x_emit_move_sequence (operands, mode)
                            gen_rtx_LO_SUM (Pmode, dp_reg, XEXP (op0, 0)));
     }
 
+  if (GET_CODE (op0) == SUBREG
+      && mixed_subreg_operand (op0, mode))
+    {
+      /* We should only generate these mixed mode patterns
+        during RTL generation.  If we need do it later on
+        then we'll have to emit patterns that won't clobber CC.  */
+      if (reload_in_progress || reload_completed)
+       abort ();
+      if (GET_MODE (SUBREG_REG (op0)) == QImode)
+       op0 = SUBREG_REG (op0);
+      else if (GET_MODE (SUBREG_REG (op0)) == HImode)
+       {
+         op0 = copy_rtx (op0);
+         PUT_MODE (op0, QImode);
+       }
+      else
+       abort ();
+
+      if (mode == QFmode)
+       emit_insn (gen_storeqf_int_clobber (op0, op1));
+      else
+       abort ();
+      return 1;
+    }
+
+  if (GET_CODE (op1) == SUBREG
+      && mixed_subreg_operand (op1, mode))
+    {
+      /* We should only generate these mixed mode patterns
+        during RTL generation.  If we need do it later on
+        then we'll have to emit patterns that won't clobber CC.  */
+      if (reload_in_progress || reload_completed)
+       abort ();
+      if (GET_MODE (SUBREG_REG (op1)) == QImode)
+       op1 = SUBREG_REG (op1);
+      else if (GET_MODE (SUBREG_REG (op1)) == HImode)
+       {
+         op1 = copy_rtx (op1);
+         PUT_MODE (op1, QImode);
+       }
+      else
+       abort ();
+
+      if (mode == QFmode)
+       emit_insn (gen_loadqf_int_clobber (op0, op1));
+      else
+       abort ();
+      return 1;
+    }
+
   /* Adjust operands in case we have modified them.  */
   operands[0] = op0;
   operands[1] = op1;
@@ -1250,10 +1300,11 @@ c4x_check_legit_addr (mode, addr, strict)
         being pushed on the stack.  */
 
     case PRE_DEC:
+    case PRE_INC:
     case POST_DEC:
       if (mode != QImode && mode != QFmode)
        return 0;
-    case PRE_INC:
+
     case POST_INC:
       base = XEXP (addr, 0);
       if (! REG_P (base))
@@ -2653,10 +2704,29 @@ reg_operand (op, mode)
      rtx op;
      enum machine_mode mode;
 {
+  if (GET_CODE (op) == SUBREG
+      && GET_MODE (op) == QFmode)
+    return 0;
   return register_operand (op, mode);
 }
 
 
+int
+mixed_subreg_operand (op, mode)
+     rtx op;
+     enum machine_mode mode;
+{
+  /* Allow (subreg:HF (reg:HI)) that be generated for a union of an
+     int and a long double.  */
+  if (GET_CODE (op) == SUBREG
+      && (GET_MODE (op) == QFmode)
+      && (GET_MODE (SUBREG_REG (op)) == QImode
+         || GET_MODE (SUBREG_REG (op)) == HImode))
+    return 1;
+  return 0;
+}
+
+
 int
 reg_imm_operand (op, mode)
      rtx op;
@@ -2733,7 +2803,7 @@ r0r1_reg_operand (op, mode)
      rtx op;
      enum machine_mode mode;
 {
-  if (! register_operand (op, mode))
+  if (! reg_operand (op, mode))
     return 0;
   if (GET_CODE (op) == SUBREG)
     op = SUBREG_REG (op);
@@ -2748,7 +2818,7 @@ r2r3_reg_operand (op, mode)
      rtx op;
      enum machine_mode mode;
 {
-  if (! register_operand (op, mode))
+  if (! reg_operand (op, mode))
     return 0;
   if (GET_CODE (op) == SUBREG)
     op = SUBREG_REG (op);
@@ -2763,7 +2833,7 @@ ext_low_reg_operand (op, mode)
      rtx op;
      enum machine_mode mode;
 {
-  if (! register_operand (op, mode))
+  if (! reg_operand (op, mode))
     return 0;
   if (GET_CODE (op) == SUBREG)
     op = SUBREG_REG (op);
@@ -2778,7 +2848,7 @@ ext_reg_operand (op, mode)
      rtx op;
      enum machine_mode mode;
 {
-  if (! register_operand (op, mode))
+  if (! reg_operand (op, mode))
     return 0;
   if (GET_CODE (op) == SUBREG)
     op = SUBREG_REG (op);
@@ -2795,7 +2865,7 @@ std_reg_operand (op, mode)
      rtx op;
      enum machine_mode mode;
 {
-  if (! register_operand (op, mode))
+  if (! reg_operand (op, mode))
     return 0;
   if (GET_CODE (op) == SUBREG)
     op = SUBREG_REG (op);
@@ -2810,7 +2880,7 @@ addr_reg_operand (op, mode)
      rtx op;
      enum machine_mode mode;
 {
-  if (! register_operand (op, mode))
+  if (! reg_operand (op, mode))
     return 0;
   return c4x_a_register (op);
 }
@@ -2823,7 +2893,7 @@ index_reg_operand (op, mode)
      rtx op;
      enum machine_mode mode;
 {
-  if (! register_operand (op, mode))
+  if (! reg_operand (op, mode))
     return 0;
   if (GET_CODE (op) == SUBREG)
     op = SUBREG_REG (op);
@@ -2914,6 +2984,10 @@ src_operand (op, mode)
      rtx op;
      enum machine_mode mode;
 {
+  if (GET_CODE (op) == SUBREG
+      && mixed_subreg_operand (op, mode))
+    return 0;
+
   if (REG_P (op))
     return reg_operand (op, mode);
 
index 347ce2c141b4498f2c57b4d22dc3aeaa298b2a10..743e8e862fe847222f03cac7e273fdcd727b7600 100644 (file)
@@ -2655,6 +2655,8 @@ extern int reg_or_const_operand ();
 
 extern int reg_operand ();
 
+extern int mixed_subreg_operand ();
+
 extern int reg_imm_operand ();
 
 extern int r0r1_reg_operand ();
index ab96ddd57ddb9574128dee669d34ef7160429a0b..97f67a5c4d66636b4916042713353a7fd0da10ea 100644 (file)
 ;  8 loadhf_int
 ;  9 storehf_int
 ; 10 RSQRF
-
+; 11 loadqf_int
+; 12 storeqf_int
+; 22 rptb_init
 
 ;
 ; C4x FUNCTIONAL UNITS
     DONE;
 }")
 
+; This can generate invalid stack slot displacements
+(define_split
+ [(set (match_operand:QI 0 "reg_operand" "=r")
+       (unspec [(match_operand:QF 1 "reg_operand" "f")] 12))]
+  "reload_completed"
+  [(set (match_dup 3) (match_dup 1))
+   (set (match_dup 0) (match_dup 2))]
+  "operands[2] = assign_stack_temp (QImode, GET_MODE_SIZE (QImode), 0);
+   operands[3] = copy_rtx (operands[2]);
+   PUT_MODE (operands[3], QFmode);")
+
+
+(define_insn "storeqf_int"
+ [(set (match_operand:QI 0 "reg_operand" "=r")
+       (unspec [(match_operand:QF 1 "reg_operand" "f")] 12))]
+ ""
+ "#"
+  [(set_attr "type" "multi")])
+
+(define_split
+ [(parallel [(set (match_operand:QI 0 "reg_operand" "=r")
+                  (unspec [(match_operand:QF 1 "reg_operand" "f")] 12))
+             (clobber (reg:CC 21))])]
+  "reload_completed"
+  [(set (mem:QF (pre_inc:QI (reg:QI 20)))
+        (match_dup 1))
+   (parallel [(set (match_dup 0)
+                   (mem:QI (post_dec:QI (reg:QI 20))))
+              (clobber (reg:CC 21))])]
+  "")
+
+
+; We need accurate death notes for this...
+;(define_peephole
+;  [(set (match_operand:QF 0 "reg_operand" "=f")
+;        (match_operand:QF 1 "memory_operand" "m"))
+;   (set (mem:QF (pre_inc:QI (reg:QI 20)))
+;        (match_dup 0))
+;   (parallel [(set (match_operand:QI 2 "reg_operand" "r")
+;                   (mem:QI (post_dec:QI (reg:QI 20))))
+;              (clobber (reg:CC 21))])]
+;  ""
+;  "ldiu\\t%1,%0")
+
+(define_insn "storeqf_int_clobber"
+ [(parallel [(set (match_operand:QI 0 "reg_operand" "=r")
+                  (unspec [(match_operand:QF 1 "reg_operand" "f")] 12))
+             (clobber (reg:CC 21))])]
+ ""
+ "#"
+  [(set_attr "type" "multi")])
+
+
+; This can generate invalid stack slot displacements
+(define_split
+ [(set (match_operand:QF 0 "reg_operand" "=f")
+       (unspec [(match_operand:QI 1 "reg_operand" "r")] 11))]
+  "reload_completed"
+  [(set (match_dup 2) (match_dup 1))
+   (set (match_dup 0) (match_dup 3))]
+  "operands[2] = assign_stack_temp (QImode, GET_MODE_SIZE (QImode), 0);
+   operands[3] = copy_rtx (operands[2]);
+   PUT_MODE (operands[3], QFmode);")
+
+
+(define_insn "loadqf_int"
+ [(set (match_operand:QF 0 "reg_operand" "=f")
+       (unspec [(match_operand:QI 1 "reg_operand" "r")] 11))]
+ ""
+ "#"
+  [(set_attr "type" "multi")])
+
+(define_split
+ [(parallel [(set (match_operand:QF 0 "reg_operand" "=f")
+                  (unspec [(match_operand:QI 1 "reg_operand" "r")] 11))
+             (clobber (reg:CC 21))])]
+  "reload_completed"
+  [(set (mem:QI (pre_inc:QI (reg:QI 20)))
+        (match_dup 1))
+   (parallel [(set (match_dup 0)
+                   (mem:QF (post_dec:QI (reg:QI 20))))
+              (clobber (reg:CC 21))])]
+  "")
+
+(define_insn "loadqf_int_clobber"
+ [(parallel [(set (match_operand:QF 0 "reg_operand" "=f")
+                  (unspec [(match_operand:QI 1 "reg_operand" "r")] 11))
+             (clobber (reg:CC 21))])]
+ ""
+ "#"
+  [(set_attr "type" "multi")])
+
 ; We must provide an alternative to store to memory in case we have to
 ; spill a register.
 (define_insn "movqf_noclobber"