OSDN Git Service

* config/xtensa/xtensa-protos.h (smalloffset_double_mem_p): Delete.
authorbwilson <bwilson@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 29 May 2003 00:08:36 +0000 (00:08 +0000)
committerbwilson <bwilson@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 29 May 2003 00:08:36 +0000 (00:08 +0000)
        (xtensa_split_operand_pair): New proto.
        * config/xtensa/xtensa.c (move_operand): Handle DFmode and DImode.
        (smalloffset_double_mem_p): Delete.
        (gen_float_relational, printx, print_operand, xtensa_va_arg):
        Fix whitespace.
        (xtensa_split_operand_pair): New.
        (xtensa_dbx_register_number): Fix formatting.
        * config/xtensa/xtensa.h (EXTRA_CONSTRAINT): Remove 'S' constraint.
        * config/xtensa/xtensa.md (movdi, movdf): Force constants to memory
        instead of splitting them into single-word moves.  Remove unnecessary
        checks for reload_in_progress and reload_completed.
        (movdi_internal, movdf_internal): Change to post-reload split patterns.
        Add constraints to allow constant operands.
        (movsf_internal): Allow CONST_INT operands.

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

gcc/ChangeLog
gcc/config/xtensa/xtensa-protos.h
gcc/config/xtensa/xtensa.c
gcc/config/xtensa/xtensa.h
gcc/config/xtensa/xtensa.md

index f9541bb..3998831 100644 (file)
@@ -1,3 +1,21 @@
+2003-05-28  Bob Wilson  <bob.wilson@acm.org>
+
+       * config/xtensa/xtensa-protos.h (smalloffset_double_mem_p): Delete.
+       (xtensa_split_operand_pair): New proto.
+       * config/xtensa/xtensa.c (move_operand): Handle DFmode and DImode.
+       (smalloffset_double_mem_p): Delete.
+       (gen_float_relational, printx, print_operand, xtensa_va_arg):
+       Fix whitespace.
+       (xtensa_split_operand_pair): New.
+       (xtensa_dbx_register_number): Fix formatting.
+       * config/xtensa/xtensa.h (EXTRA_CONSTRAINT): Remove 'S' constraint.
+       * config/xtensa/xtensa.md (movdi, movdf): Force constants to memory
+       instead of splitting them into single-word moves.  Remove unnecessary
+       checks for reload_in_progress and reload_completed.
+       (movdi_internal, movdf_internal): Change to post-reload split patterns.
+       Add constraints to allow constant operands.
+       (movsf_internal): Allow CONST_INT operands.
+
 2003-05-27  Danny Smith   <dannysmith@users.sourceforge.net>
 
        * config.gcc (i[34567]86-*-mingw32*): Add host makefile
 2003-05-27  Danny Smith   <dannysmith@users.sourceforge.net>
 
        * config.gcc (i[34567]86-*-mingw32*): Add host makefile
index b5ca611..7800f0f 100644 (file)
@@ -54,7 +54,6 @@ extern int ubranch_operand PARAMS ((rtx, enum machine_mode));
 extern int call_insn_operand PARAMS ((rtx, enum machine_mode));
 extern int move_operand PARAMS ((rtx, enum machine_mode));
 extern int smalloffset_mem_p PARAMS ((rtx));
 extern int call_insn_operand PARAMS ((rtx, enum machine_mode));
 extern int move_operand PARAMS ((rtx, enum machine_mode));
 extern int smalloffset_mem_p PARAMS ((rtx));
-extern int smalloffset_double_mem_p PARAMS ((rtx));
 extern int constantpool_address_p PARAMS ((rtx));
 extern int constantpool_mem_p PARAMS ((rtx));
 extern int const_float_1_operand PARAMS ((rtx, enum machine_mode));
 extern int constantpool_address_p PARAMS ((rtx));
 extern int constantpool_mem_p PARAMS ((rtx));
 extern int const_float_1_operand PARAMS ((rtx, enum machine_mode));
@@ -67,6 +66,7 @@ extern void xtensa_expand_conditional_branch PARAMS ((rtx *, enum rtx_code));
 extern int xtensa_expand_conditional_move PARAMS ((rtx *, int));
 extern int xtensa_expand_scc PARAMS ((rtx *));
 extern int xtensa_expand_block_move PARAMS ((rtx *));
 extern int xtensa_expand_conditional_move PARAMS ((rtx *, int));
 extern int xtensa_expand_scc PARAMS ((rtx *));
 extern int xtensa_expand_block_move PARAMS ((rtx *));
+extern void xtensa_split_operand_pair PARAMS ((rtx *, enum machine_mode));
 extern int xtensa_emit_move_sequence PARAMS ((rtx *, enum machine_mode));
 extern bool xtensa_copy_incoming_a7 PARAMS ((rtx *, enum machine_mode));
 extern void xtensa_emit_block_move PARAMS ((rtx *, rtx *, int));
 extern int xtensa_emit_move_sequence PARAMS ((rtx *, enum machine_mode));
 extern bool xtensa_copy_incoming_a7 PARAMS ((rtx *, enum machine_mode));
 extern void xtensa_emit_block_move PARAMS ((rtx *, rtx *, int));
index 18ed9d3..d3ec724 100644 (file)
@@ -599,19 +599,32 @@ move_operand (op, mode)
       || memory_operand (op, mode))
     return TRUE;
 
       || memory_operand (op, mode))
     return TRUE;
 
-  if (mode == SFmode)
-    return TARGET_CONST16 && CONSTANT_P (op);
+  switch (mode)
+    {
+    case DFmode:
+    case SFmode:
+      return TARGET_CONST16 && CONSTANT_P (op);
 
 
-  /* Accept CONSTANT_P_RTX, since it will be gone by CSE1 and
-     result in 0/1.  */
-  if (GET_CODE (op) == CONSTANT_P_RTX)
-    return TRUE;
+    case DImode:
+    case SImode:
+      if (TARGET_CONST16)
+       return CONSTANT_P (op);
+      /* fall through */
 
 
-  if (GET_CODE (op) == CONST_INT && xtensa_simm12b (INTVAL (op)))
-    return TRUE;
+    case HImode:
+    case QImode:
+      /* Accept CONSTANT_P_RTX, since it will be gone by CSE1 and
+        result in 0/1.  */
+      if (GET_CODE (op) == CONSTANT_P_RTX)
+       return TRUE;
+
+      if (GET_CODE (op) == CONST_INT && xtensa_simm12b (INTVAL (op)))
+       return TRUE;
+      break;
 
 
-  if (mode == SImode)
-    return TARGET_CONST16 && CONSTANT_P (op);
+    default:
+      break;
+    }
 
   return FALSE;
 }
 
   return FALSE;
 }
@@ -641,16 +654,6 @@ smalloffset_mem_p (op)
 
 
 int
 
 
 int
-smalloffset_double_mem_p (op)
-     rtx op;
-{
-  if (!smalloffset_mem_p (op))
-    return FALSE;
-  return smalloffset_mem_p (adjust_address (op, GET_MODE (op), 4));
-}
-
-
-int
 constantpool_address_p (addr)
      rtx addr;
 {
 constantpool_address_p (addr)
      rtx addr;
 {
@@ -1014,7 +1017,7 @@ gen_float_relational (test_code, cmp0, cmp1)
     case GT: reverse_regs = 1; invert = 0; gen_fn = gen_slt_sf; break;
     case LT: reverse_regs = 0; invert = 0; gen_fn = gen_slt_sf; break;
     case GE: reverse_regs = 1; invert = 0; gen_fn = gen_sle_sf; break;
     case GT: reverse_regs = 1; invert = 0; gen_fn = gen_slt_sf; break;
     case LT: reverse_regs = 0; invert = 0; gen_fn = gen_slt_sf; break;
     case GE: reverse_regs = 1; invert = 0; gen_fn = gen_sle_sf; break;
-    default: 
+    default:
       fatal_insn ("bad test", gen_rtx (test_code, VOIDmode, cmp0, cmp1));
       reverse_regs = 0; invert = 0; gen_fn = 0; /* avoid compiler warnings */
     }
       fatal_insn ("bad test", gen_rtx (test_code, VOIDmode, cmp0, cmp1));
       reverse_regs = 0; invert = 0; gen_fn = 0; /* avoid compiler warnings */
     }
@@ -1207,6 +1210,53 @@ xtensa_expand_scc (operands)
 }
 
 
 }
 
 
+/* Split OP[1] into OP[2,3] and likewise for OP[0] into OP[0,1].  MODE is
+   for the output, i.e., the input operands are twice as big as MODE.  */
+
+void
+xtensa_split_operand_pair (operands, mode)
+     rtx operands[4];
+     enum machine_mode mode;
+{
+  switch (GET_CODE (operands[1]))
+    {
+    case REG:
+      operands[3] = gen_rtx_REG (mode, REGNO (operands[1]) + 1);
+      operands[2] = gen_rtx_REG (mode, REGNO (operands[1]));
+      break;
+
+    case MEM:
+      operands[3] = adjust_address (operands[1], mode, GET_MODE_SIZE (mode));
+      operands[2] = adjust_address (operands[1], mode, 0);
+      break;
+
+    case CONST_INT:
+    case CONST_DOUBLE:
+      split_double (operands[1], &operands[2], &operands[3]);
+      break;
+
+    default:
+      abort ();
+    }
+
+  switch (GET_CODE (operands[0]))
+    {
+    case REG:
+      operands[1] = gen_rtx_REG (mode, REGNO (operands[0]) + 1);
+      operands[0] = gen_rtx_REG (mode, REGNO (operands[0]));
+      break;
+
+    case MEM:
+      operands[1] = adjust_address (operands[0], mode, GET_MODE_SIZE (mode));
+      operands[0] = adjust_address (operands[0], mode, 0);
+      break;
+
+    default:
+      abort ();
+    }
+}
+
+
 /* Emit insns to move operands[1] into operands[0].
    Return 1 if we have written out everything that needs to be done to
    do the move.  Otherwise, return 0 and the caller will emit the move
 /* Emit insns to move operands[1] into operands[0].
    Return 1 if we have written out everything that needs to be done to
    do the move.  Otherwise, return 0 and the caller will emit the move
@@ -1658,24 +1708,27 @@ xtensa_dbx_register_number (regno)
      int regno;
 {
   int first = -1;
      int regno;
 {
   int first = -1;
-  
-  if (GP_REG_P (regno)) {
-    regno -= GP_REG_FIRST;
-    first = 0;
-  }
-  else if (BR_REG_P (regno)) {
-    regno -= BR_REG_FIRST;
-    first = 16;
-  }
-  else if (FP_REG_P (regno)) {
-    regno -= FP_REG_FIRST;
-    /* The current numbering convention is that TIE registers are
-       numbered in libcc order beginning with 256.  We can't guarantee
-       that the FP registers will come first, so the following is just
-       a guess.  It seems like we should make a special case for FP
-       registers and give them fixed numbers < 256.  */
-    first = 256;
-  }
+
+  if (GP_REG_P (regno))
+    {
+      regno -= GP_REG_FIRST;
+      first = 0;
+    }
+  else if (BR_REG_P (regno))
+    {
+      regno -= BR_REG_FIRST;
+      first = 16;
+    }
+  else if (FP_REG_P (regno))
+    {
+      regno -= FP_REG_FIRST;
+      /* The current numbering convention is that TIE registers are
+        numbered in libcc order beginning with 256.  We can't guarantee
+        that the FP registers will come first, so the following is just
+        a guess.  It seems like we should make a special case for FP
+        registers and give them fixed numbers < 256.  */
+      first = 256;
+    }
   else if (ACC_REG_P (regno))
     {
       first = 0;
   else if (ACC_REG_P (regno))
     {
       first = 0;
@@ -1885,7 +1938,7 @@ override_options ()
    a null pointer for X and the punctuation character for CODE.
 
    'a', 'c', 'l', and 'n' are reserved.
    a null pointer for X and the punctuation character for CODE.
 
    'a', 'c', 'l', and 'n' are reserved.
-   
+
    The Xtensa specific codes are:
 
    'd'  CONST_INT, print as signed decimal
    The Xtensa specific codes are:
 
    'd'  CONST_INT, print as signed decimal
@@ -2041,7 +2094,7 @@ print_operand (file, x, letter)
          print_operand (file, XEXP (XEXP (x, 0), 1), 0);
        }
       else
          print_operand (file, XEXP (XEXP (x, 0), 1), 0);
        }
       else
-       { 
+       {
          output_addr_const (file, x);
          fputs (letter == 't' ? "@h" : "@l", file);
        }
          output_addr_const (file, x);
          fputs (letter == 't' ? "@h" : "@l", file);
        }
@@ -2608,7 +2661,7 @@ xtensa_va_arg (valist, type)
 
   size = gen_reg_rtx (SImode);
   emit_move_insn (size, va_size);
 
   size = gen_reg_rtx (SImode);
   emit_move_insn (size, va_size);
-  
+
   if (BYTES_BIG_ENDIAN)
     {
       rtx lab_use_va_size = gen_label_rtx ();
   if (BYTES_BIG_ENDIAN)
     {
       rtx lab_use_va_size = gen_label_rtx ();
index 9b7f261..0322109 100644 (file)
@@ -691,7 +691,6 @@ extern enum reg_class xtensa_char_to_class[256];
    operand types.
 
    R = memory that can be accessed with a 4-bit unsigned offset
    operand types.
 
    R = memory that can be accessed with a 4-bit unsigned offset
-   S = memory where the second word can be addressed with a 4-bit offset
    T = memory in a constant pool (addressable with a pc-relative load)
    U = memory *NOT* in a constant pool
 
    T = memory in a constant pool (addressable with a pc-relative load)
    U = memory *NOT* in a constant pool
 
@@ -713,7 +712,6 @@ extern enum reg_class xtensa_char_to_class[256];
        && reload_in_progress && GET_CODE (OP) == REG                   \
         && REGNO (OP) >= FIRST_PSEUDO_REGISTER)                                \
    : ((CODE) == 'R') ? smalloffset_mem_p (OP)                          \
        && reload_in_progress && GET_CODE (OP) == REG                   \
         && REGNO (OP) >= FIRST_PSEUDO_REGISTER)                                \
    : ((CODE) == 'R') ? smalloffset_mem_p (OP)                          \
-   : ((CODE) == 'S') ? smalloffset_double_mem_p (OP)                   \
    : ((CODE) == 'T') ? !TARGET_CONST16 && constantpool_mem_p (OP)      \
    : ((CODE) == 'U') ? !constantpool_mem_p (OP)                                \
    : FALSE)
    : ((CODE) == 'T') ? !TARGET_CONST16 && constantpool_mem_p (OP)      \
    : ((CODE) == 'U') ? !constantpool_mem_p (OP)                                \
    : FALSE)
index 40bf5c0..26bad87 100644 (file)
   ""
   "
 {
   ""
   "
 {
-  if (CONSTANT_P (operands[1])
-      && register_operand (operands[0], DImode))
-    {
-      rtx src0, src1, dst0, dst1;
-      dst0 = operand_subword (operands[0], 0, 1, DImode);
-      src0 = operand_subword (operands[1], 0, 1, DImode);
-      dst1 = operand_subword (operands[0], 1, 1, DImode);
-      src1 = operand_subword (operands[1], 1, 1, DImode);
-      if (!dst0 || !src0 || !dst1 || !src1)
-        abort ();
-      emit_insn (gen_movsi (dst0, src0));
-      emit_insn (gen_movsi (dst1, src1));
-      DONE;
-    }
+  if (CONSTANT_P (operands[1]) && !TARGET_CONST16)
+    operands[1] = force_const_mem (DImode, operands[1]);
 
 
-  if (!(reload_in_progress | reload_completed))
-    {
-      if (!register_operand (operands[0], DImode)
-         && !register_operand (operands[1], DImode))
-       operands[1] = force_reg (DImode, operands[1]);
+  if (!register_operand (operands[0], DImode)
+      && !register_operand (operands[1], DImode))
+    operands[1] = force_reg (DImode, operands[1]);
 
 
-      if (xtensa_copy_incoming_a7 (operands, DImode))
-       DONE;
-    }
+  if (xtensa_copy_incoming_a7 (operands, DImode))
+    DONE;
 }")
 
 }")
 
-(define_insn "movdi_internal"
-  [(set (match_operand:DI 0 "nonimmed_operand" "=D,D,S,a,a,U")
-       (match_operand:DI 1 "nonimmed_operand" "d,S,d,r,U,r"))]
+(define_insn_and_split "movdi_internal"
+  [(set (match_operand:DI 0 "nonimmed_operand" "=a,W,a,a,U")
+       (match_operand:DI 1 "move_operand" "r,i,T,U,r"))]
   "register_operand (operands[0], DImode)
    || register_operand (operands[1], DImode)"
   "register_operand (operands[0], DImode)
    || register_operand (operands[1], DImode)"
-  "*
+  "#"
+  "reload_completed"
+  [(set (match_dup 0) (match_dup 2))
+   (set (match_dup 1) (match_dup 3))]
 {
 {
-  rtx dstreg;
-  switch (which_alternative)
+  xtensa_split_operand_pair (operands, SImode);
+  if (reg_overlap_mentioned_p (operands[0], operands[3]))
     {
     {
-    case 0: return \"mov.n\\t%0, %1\;mov.n\\t%D0, %D1\";
-    case 2: return \"%v0s32i.n\\t%1, %0\;s32i.n\\t%D1, %N0\";
-    case 3: return \"mov\\t%0, %1\;mov\\t%D0, %D1\";
-    case 5: return \"%v0s32i\\t%1, %0\;s32i\\t%D1, %N0\";
-
-    case 1:
-    case 4:
-      /* Check if the first half of the destination register is used
-        in the source address.  If so, reverse the order of the loads
-        so that the source address doesn't get clobbered until it is
-        no longer needed. */
-
-      dstreg = operands[0];
-      if (GET_CODE (dstreg) == SUBREG)
-       dstreg = SUBREG_REG (dstreg);
-      if (GET_CODE (dstreg) != REG)
-       abort();
-
-      if (reg_mentioned_p (dstreg, operands[1]))
-       {
-         switch (which_alternative)
-           {
-           case 1: return \"%v1l32i.n\\t%D0, %N1\;l32i.n\\t%0, %1\";
-           case 4: return \"%v1l32i\\t%D0, %N1\;l32i\\t%0, %1\";
-           }
-       }
-      else
-       {
-         switch (which_alternative)
-           {
-           case 1: return \"%v1l32i.n\\t%0, %1\;l32i.n\\t%D0, %N1\";
-           case 4: return \"%v1l32i\\t%0, %1\;l32i\\t%D0, %N1\";
-           }
-       }
+      rtx tmp;
+      tmp = operands[0], operands[0] = operands[1], operands[1] = tmp;
+      tmp = operands[2], operands[2] = operands[3], operands[3] = tmp;
     }
     }
-  abort ();
-  return \"\";
-}"
-  [(set_attr "type"    "move,load,store,move,load,store")
-   (set_attr "mode"    "DI")
-   (set_attr "length"  "4,4,4,6,6,6")])
+})
 
 
 ;; 32-bit Integer moves
 
 
 ;; 32-bit Integer moves
 
 (define_insn "movsf_internal"
   [(set (match_operand:SF 0 "nonimmed_operand" "=f,f,U,D,D,R,a,f,a,W,a,a,U")
 
 (define_insn "movsf_internal"
   [(set (match_operand:SF 0 "nonimmed_operand" "=f,f,U,D,D,R,a,f,a,W,a,a,U")
-       (match_operand:SF 1 "move_operand" "f,U,f,d,R,d,r,r,f,F,T,U,r"))]
+       (match_operand:SF 1 "move_operand" "f,U,f,d,R,d,r,r,f,iF,T,U,r"))]
   "((register_operand (operands[0], SFmode)
      || register_operand (operands[1], SFmode))
     && !(FP_REG_P (xt_true_regnum (operands[0]))
   "((register_operand (operands[0], SFmode)
      || register_operand (operands[1], SFmode))
     && !(FP_REG_P (xt_true_regnum (operands[0]))
   ""
   "
 {
   ""
   "
 {
-  if (CONSTANT_P (operands[1]))
-    {
-      rtx src0, src1, dst0, dst1;
-      dst0 = operand_subword (operands[0], 0, 1, DFmode);
-      src0 = operand_subword (operands[1], 0, 1, DFmode);
-      dst1 = operand_subword (operands[0], 1, 1, DFmode);
-      src1 = operand_subword (operands[1], 1, 1, DFmode);
-      if (!dst0 || !src0 || !dst1 || !src1)
-        abort ();
-      emit_insn (gen_movsi (dst0, src0));
-      emit_insn (gen_movsi (dst1, src1));
-      DONE;
-    }
+  if (CONSTANT_P (operands[1]) && !TARGET_CONST16)
+    operands[1] = force_const_mem (DFmode, operands[1]);
 
 
-  if (!(reload_in_progress | reload_completed))
-    {
-      if (!register_operand (operands[0], DFmode)
-         && !register_operand (operands[1], DFmode))
-       operands[1] = force_reg (DFmode, operands[1]);
+  if (!register_operand (operands[0], DFmode)
+      && !register_operand (operands[1], DFmode))
+    operands[1] = force_reg (DFmode, operands[1]);
 
 
-      if (xtensa_copy_incoming_a7 (operands, DFmode))
-       DONE;
-    }
+  if (xtensa_copy_incoming_a7 (operands, DFmode))
+    DONE;
 }")
 
 }")
 
-(define_insn "movdf_internal"
-  [(set (match_operand:DF 0 "nonimmed_operand" "=D,D,S,a,a,U")
-       (match_operand:DF 1 "nonimmed_operand" "d,S,d,r,U,r"))]
+(define_insn_and_split "movdf_internal"
+  [(set (match_operand:DF 0 "nonimmed_operand" "=a,W,a,a,U")
+       (match_operand:DF 1 "move_operand" "r,iF,T,U,r"))]
   "register_operand (operands[0], DFmode)
    || register_operand (operands[1], DFmode)"
   "register_operand (operands[0], DFmode)
    || register_operand (operands[1], DFmode)"
-  "*
+  "#"
+  "reload_completed"
+  [(set (match_dup 0) (match_dup 2))
+   (set (match_dup 1) (match_dup 3))]
 {
 {
-  rtx dstreg;
-  switch (which_alternative)
+  xtensa_split_operand_pair (operands, SFmode);
+  if (reg_overlap_mentioned_p (operands[0], operands[3]))
     {
     {
-    case 0: return \"mov.n\\t%0, %1\;mov.n\\t%D0, %D1\";
-    case 2: return \"%v0s32i.n\\t%1, %0\;s32i.n\\t%D1, %N0\";
-    case 3: return \"mov\\t%0, %1\;mov\\t%D0, %D1\";
-    case 5: return \"%v0s32i\\t%1, %0\;s32i\\t%D1, %N0\";
-
-    case 1:
-    case 4:
-      /* Check if the first half of the destination register is used
-        in the source address.  If so, reverse the order of the loads
-        so that the source address doesn't get clobbered until it is
-        no longer needed.  */
-
-      dstreg = operands[0];
-      if (GET_CODE (dstreg) == SUBREG)
-       dstreg = SUBREG_REG (dstreg);
-      if (GET_CODE (dstreg) != REG)
-       abort ();
-
-      if (reg_mentioned_p (dstreg, operands[1]))
-       {
-         switch (which_alternative)
-           {
-           case 1: return \"%v1l32i.n\\t%D0, %N1\;l32i.n\\t%0, %1\";
-           case 4: return \"%v1l32i\\t%D0, %N1\;l32i\\t%0, %1\";
-           }
-       }
-      else
-       {
-         switch (which_alternative)
-           {
-           case 1: return \"%v1l32i.n\\t%0, %1\;l32i.n\\t%D0, %N1\";
-           case 4: return \"%v1l32i\\t%0, %1\;l32i\\t%D0, %N1\";
-           }
-       }
+      rtx tmp;
+      tmp = operands[0], operands[0] = operands[1], operands[1] = tmp;
+      tmp = operands[2], operands[2] = operands[3], operands[3] = tmp;
     }
     }
-  abort ();
-  return \"\";
-}"
-  [(set_attr "type"    "move,load,store,move,load,store")
-   (set_attr "mode"    "DF")
-   (set_attr "length"  "4,4,4,6,6,6")])
+})
 
 ;; Block moves
 
 
 ;; Block moves