addsub.md (addhi3): Add two more alternatives, for mova with fb, and for fb+0 -> An.
authorDJ Delorie <dj@redhat.com>
Thu, 12 Jan 2006 21:40:27 +0000 (16:40 -0500)
committerDJ Delorie <dj@gcc.gnu.org>
Thu, 12 Jan 2006 21:40:27 +0000 (16:40 -0500)
* config/m32c/addsub.md (addhi3): Add two more alternatives, for
mova with fb, and for fb+0 -> An.

* config/m32c/mov.md (peephole2): Fix enabling logic.

* config/m32c/m32c.h (CTOR_LIST_BEGIN, CTOR_LIST_END,
DTOR_LIST_BEGIN, DTOR_LIST_END, CTORS_SECTION_ASM_OP,
DTORS_SECTION_ASM_OP, INIT_ARRAY_SECTION_ASM_OP,
FINI_ARRAY_SECTION_ASM_OP): Define.

* config/m32c/m32c.c (m32c_legitimize_address): Remove temporary variable.
(m32c_legitimize_reload_address): New logic to reload FB to An.
(m32c_output_reg_push): Add newline.
(m32c_output_reg_pop): Likewise.

From-SVN: r109648

gcc/ChangeLog
gcc/config/m32c/addsub.md
gcc/config/m32c/m32c.c
gcc/config/m32c/m32c.h
gcc/config/m32c/mov.md

index d6af785..38405e7 100644 (file)
@@ -1,3 +1,20 @@
+2006-01-12  DJ Delorie  <dj@redhat.com>
+
+       * config/m32c/addsub.md (addhi3): Add two more alternatives, for
+       mova with fb, and for fb+0 -> An.
+
+       * config/m32c/mov.md (peephole2): Fix enabling logic.
+
+       * config/m32c/m32c.h (CTOR_LIST_BEGIN, CTOR_LIST_END,
+       DTOR_LIST_BEGIN, DTOR_LIST_END, CTORS_SECTION_ASM_OP,
+       DTORS_SECTION_ASM_OP, INIT_ARRAY_SECTION_ASM_OP,
+       FINI_ARRAY_SECTION_ASM_OP): Define.
+
+       * config/m32c/m32c.c (m32c_legitimize_address): Remove temporary variable.
+       (m32c_legitimize_reload_address): New logic to reload FB to An.
+       (m32c_output_reg_push): Add newline.
+       (m32c_output_reg_pop): Likewise.
+
 2006-01-12  Ulrich Weigand  <uweigand@de.ibm.com>
 
        * struct-equiv.c (find_dying_inputs): Fix off-by-one bug.
index 57f81ac..104709c 100644 (file)
 
 (define_insn "addhi3"
   [(set (match_operand:HI 0 "nonimmediate_operand"
-                 "=SdRhi,SdRhi,??Rmm,??Rmm, SdRhi,??Rmm, Rhi, !Rsp")
+                 "=SdRhi,SdRhi,??Rmm,??Rmm, SdRhi,??Rmm, Rhi, Raw, Raw, !Rsp")
        (plus:HI (match_operand:HI 1 "general_operand"
-                 "%0,0,0,0, 0,0, Raw, 0")
+                 "%0,0,0,0, 0,0, Raw, Rfb, Rfb, 0")
                 (match_operand:HI 2 "general_operand"
-                 "IU2sSdRhi,?Rmm,IU2sSdRhi,?Rmm, IM2,IM2, IS2IU2, i")))]
+                 "IU2sSdRhi,?Rmm,IU2sSdRhi,?Rmm, IM2,IM2, IS2IU2, I00, IS1, i")))]
   ""
   "@
    add.w\t%2,%0
    sub.w\t%m2,%0
    sub.w\t%m2,%0
    mova\t%d2[%1],%0
+   stc\t%1,%0
+   mova\t%D2[%1],%0
    add.w\t%2,%0"
-  [(set_attr "flags" "oszc,oszc,oszc,oszc,oszc,oszc,oszc,oszc")]
+  [(set_attr "flags" "oszc,oszc,oszc,oszc,oszc,oszc,oszc,oszc,oszc,oszc")]
   )
 
 (define_insn "addpsi3"
index 8580922..8712131 100644 (file)
@@ -1822,6 +1822,31 @@ m32c_reg_ok_for_base_p (rtx x, int strict)
     }
 }
 
+/* We have three choices for choosing fb->aN offsets.  If we choose -128,
+   we need one MOVA -128[fb],aN opcode and 16 bit aN displacements,
+   like this:
+       EB 4B FF    mova    -128[$fb],$a0
+       D8 0C FF FF mov.w:Q #0,-1[$a0]
+
+   Alternately, we subtract the frame size, and hopefully use 8 bit aN
+   displacements:
+       7B F4       stc $fb,$a0
+       77 54 00 01 sub #256,$a0
+       D8 08 01    mov.w:Q #0,1[$a0]
+
+   If we don't offset (i.e. offset by zero), we end up with:
+       7B F4       stc $fb,$a0
+       D8 0C 00 FF mov.w:Q #0,-256[$a0]
+
+   We have to subtract *something* so that we have a PLUS rtx to mark
+   that we've done this reload.  The -128 offset will never result in
+   an 8 bit aN offset, and the payoff for the second case is five
+   loads *if* those loads are within 256 bytes of the other end of the
+   frame, so the third case seems best.  Note that we subtract the
+   zero, but detect that in the addhi3 pattern.  */
+
+#define BIG_FB_ADJ 0
+
 /* Implements LEGITIMIZE_ADDRESS.  The only address we really have to
    worry about is frame base offsets, as $fb has a limited
    displacement range.  We deal with this by attempting to reload $fb
@@ -1846,10 +1871,9 @@ m32c_legitimize_address (rtx * x ATTRIBUTE_UNUSED,
          || INTVAL (XEXP (*x, 1)) > (128 - GET_MODE_SIZE (mode))))
     {
       /* reload FB to A_REGS */
-      rtx foo;
       rtx temp = gen_reg_rtx (Pmode);
       *x = copy_rtx (*x);
-      foo = emit_insn (gen_rtx_SET (VOIDmode, temp, XEXP (*x, 0)));
+      emit_insn (gen_rtx_SET (VOIDmode, temp, XEXP (*x, 0)));
       XEXP (*x, 0) = temp;
       return 1;
     }
@@ -1875,7 +1899,47 @@ m32c_legitimize_reload_address (rtx * x,
      *also* still trying to reload the whole address, and we'd run out
      of address registers.  So we let gcc do the naive (but safe)
      reload instead, when the above function doesn't handle it for
-     us.  */
+     us.
+
+     The code below is a second attempt at the above.  */
+
+  if (GET_CODE (*x) == PLUS
+      && GET_CODE (XEXP (*x, 0)) == REG
+      && REGNO (XEXP (*x, 0)) == FB_REGNO
+      && GET_CODE (XEXP (*x, 1)) == CONST_INT
+      && (INTVAL (XEXP (*x, 1)) < -128
+         || INTVAL (XEXP (*x, 1)) > (128 - GET_MODE_SIZE (mode))))
+    {
+      rtx sum;
+      int offset = INTVAL (XEXP (*x, 1));
+      int adjustment = -BIG_FB_ADJ;
+
+      sum = gen_rtx_PLUS (Pmode, XEXP (*x, 0),
+                         GEN_INT (adjustment));
+      *x = gen_rtx_PLUS (Pmode, sum, GEN_INT (offset - adjustment));
+      if (type == RELOAD_OTHER)
+       type = RELOAD_FOR_OTHER_ADDRESS;
+      push_reload (sum, NULL_RTX, &XEXP (*x, 0), NULL,
+                  A_REGS, Pmode, VOIDmode, 0, 0, opnum,
+                  type);
+      return 1;
+    }
+
+  if (GET_CODE (*x) == PLUS
+      && GET_CODE (XEXP (*x, 0)) == PLUS
+      && GET_CODE (XEXP (XEXP (*x, 0), 0)) == REG
+      && REGNO (XEXP (XEXP (*x, 0), 0)) == FB_REGNO
+      && GET_CODE (XEXP (XEXP (*x, 0), 1)) == CONST_INT
+      && GET_CODE (XEXP (*x, 1)) == CONST_INT
+      )
+    {
+      if (type == RELOAD_OTHER)
+       type = RELOAD_FOR_OTHER_ADDRESS;
+      push_reload (XEXP (*x, 0), NULL_RTX, &XEXP (*x, 0), NULL,
+                  A_REGS, Pmode, VOIDmode, 0, 0, opnum,
+                  type);
+      return 1;
+    }
 
   return 0;
 }
@@ -2386,7 +2450,7 @@ m32c_output_reg_push (FILE * s, int regno)
   if (regno == FLG_REGNO)
     fprintf (s, "\tpushc\tflg\n");
   else
-    fprintf (s, "\tpush.%c\t%s",
+    fprintf (s, "\tpush.%c\t%s\n",
             " bwll"[reg_push_size (regno)], reg_names[regno]);
 }
 
@@ -2397,7 +2461,7 @@ m32c_output_reg_pop (FILE * s, int regno)
   if (regno == FLG_REGNO)
     fprintf (s, "\tpopc\tflg\n");
   else
-    fprintf (s, "\tpop.%c\t%s",
+    fprintf (s, "\tpop.%c\t%s\n",
             " bwll"[reg_push_size (regno)], reg_names[regno]);
 }
 
index 99968f9..98400a0 100644 (file)
@@ -575,6 +575,15 @@ typedef struct m32c_cumulative_args
 #define DATA_SECTION_ASM_OP ".data"
 #define BSS_SECTION_ASM_OP ".bss"
 
+#define CTOR_LIST_BEGIN
+#define CTOR_LIST_END
+#define DTOR_LIST_BEGIN
+#define DTOR_LIST_END
+#define CTORS_SECTION_ASM_OP "\t.section\t.init_array,\"aw\",%init_array"
+#define DTORS_SECTION_ASM_OP "\t.section\t.fini_array,\"aw\",%fini_array"
+#define INIT_ARRAY_SECTION_ASM_OP "\t.section\t.init_array,\"aw\",%init_array"
+#define FINI_ARRAY_SECTION_ASM_OP "\t.section\t.fini_array,\"aw\",%fini_array"
+
 /* The Overall Framework of an Assembler File */
 
 #define ASM_COMMENT_START ";"
index e146bb6..c3794a3 100644 (file)
        (mem:QHSI (match_operand:HPSI 4 "register_operand" "")))]
   "REGNO (operands[0]) == REGNO (operands[1])
    && REGNO (operands[0]) == REGNO (operands[4])
-   && dead_or_set_p (peep2_next_insn (1), operands[4])
-   && ! reg_mentioned_p (operands[0], operands[3])"
+   && (rtx_equal_p (operands[0], operands[3])
+       || (dead_or_set_p (peep2_next_insn (1), operands[4])
+          && ! reg_mentioned_p (operands[0], operands[3])))"
   [(set (match_dup 3)
        (mem:QHSI (plus:HPSI (match_dup 1)
                             (match_dup 2))))]