pa.c (pa_reorg): New marking scheme for jumps inside switch tables.
authorJeffrey A Law <law@cygnus.com>
Wed, 9 Sep 1998 21:31:17 +0000 (21:31 +0000)
committerJeff Law <law@gcc.gnu.org>
Wed, 9 Sep 1998 21:31:17 +0000 (15:31 -0600)
        * pa.c (pa_reorg): New marking scheme for jumps inside switch
        tables.
        (pa_adjust_insn_length): Update to work with new marking scheme
        for jumps inside switch tables.
        * pa.md (switch_jump): Remove pattern.
        (jump): Handle jumps inside jump tables.

From-SVN: r22368

gcc/ChangeLog
gcc/config/pa/pa.c
gcc/config/pa/pa.md

index 5925e02..af6291d 100644 (file)
@@ -34,6 +34,13 @@ Wed Sep  9 15:16:58 1998  Gavin Romig-Koch  <gavin@cygnus.com>
 
 Wed Sep  9 12:31:35 1998  Jeffrey A Law  (law@cygnus.com)
 
+       * pa.c (pa_reorg): New marking scheme for jumps inside switch
+       tables.
+       (pa_adjust_insn_length): Update to work with new marking scheme
+       for jumps inside switch tables. 
+       * pa.md (switch_jump): Remove pattern.
+       (jump): Handle jumps inside jump tables.
+
        * Makefile.in (profile.o): Depend on insn-config.h
 
 Wed Sep  9 09:36:51 1998  Jim Wilson  <wilson@cygnus.com>
index c3395cf..a3eab2a 100644 (file)
@@ -3563,7 +3563,7 @@ pa_adjust_insn_length (insn, length)
      also need adjustment.  */
   else if (GET_CODE (insn) == JUMP_INSN
           && simplejump_p (insn)
-          && GET_MODE (PATTERN (insn)) == DImode)
+          && GET_MODE (insn) == SImode)
     return 4;
   /* Millicode insn with an unfilled delay slot.  */
   else if (GET_CODE (insn) == INSN
@@ -6056,18 +6056,52 @@ pa_reorg (insns)
              if (GET_CODE (pattern) == ADDR_VEC)
                {
                  /* Emit the jump itself.  */
-                 tmp = gen_switch_jump (XEXP (XVECEXP (pattern, 0, i), 0));
+                 tmp = gen_jump (XEXP (XVECEXP (pattern, 0, i), 0));
                  tmp = emit_jump_insn_after (tmp, location);
                  JUMP_LABEL (tmp) = XEXP (XVECEXP (pattern, 0, i), 0);
+                 /* It is easy to rely on the branch table markers
+                    during assembly output to trigger the correct code
+                    for a switch table jump with an unfilled delay slot,
+
+                    However, that requires state and assumes that we look
+                    at insns in order.
+
+                    We can't make such assumptions when computing the length
+                    of instructions.  Ugh.  We could walk the insn chain to
+                    determine if this instruction is in a branch table, but
+                    that can get rather expensive, particularly during the
+                    branch shortening phase of the compiler.
+
+                    So instead we mark this jump as being special.  This is
+                    far from ideal and knows that no code after this will
+                    muck around with the mode of the JUMP_INSN itself.  */
+                 PUT_MODE (tmp, SImode);
                  LABEL_NUSES (JUMP_LABEL (tmp))++;
                  location = NEXT_INSN (location);
                }
              else
                {
                  /* Emit the jump itself.  */
-                 tmp = gen_switch_jump (XEXP (XVECEXP (pattern, 1, i), 0));
+                 tmp = gen_jump (XEXP (XVECEXP (pattern, 1, i), 0));
                  tmp = emit_jump_insn_after (tmp, location);
                  JUMP_LABEL (tmp) = XEXP (XVECEXP (pattern, 1, i), 0);
+                 /* It is easy to rely on the branch table markers
+                    during assembly output to trigger the correct code
+                    for a switch table jump with an unfilled delay slot,
+
+                    However, that requires state and assumes that we look
+                    at insns in order.
+
+                    We can't make such assumptions when computing the length
+                    of instructions.  Ugh.  We could walk the insn chain to
+                    determine if this instruction is in a branch table, but
+                    that can get rather expensive, particularly during the
+                    branch shortening phase of the compiler.
+
+                    So instead we mark this jump as being special.  This is
+                    far from ideal and knows that no code after this will
+                    muck around with the mode of the JUMP_INSN itself.  */
+                 PUT_MODE (tmp, SImode);
                  LABEL_NUSES (JUMP_LABEL (tmp))++;
                  location = NEXT_INSN (location);
                }
index ac3062a..2f3848c 100644 (file)
   ""
   [(set_attr "length" "0")])
 
-(define_insn "switch_jump"
-  [(set:DI (pc) (label_ref (match_operand 0 "" "")))]
-  ""
-  "bl %l0,0%#"
-  [(set_attr "type" "uncond_branch")
-   (set_attr "length" "4")])
-
 (define_insn "jump"
   [(set (pc) (label_ref (match_operand 0 "" "")))]
   ""
   "*
 {
   extern int optimize;
+
+  if (GET_MODE (insn) == SImode)
+    return \"bl %l0,0%#\";
+
   /* An unconditional branch which can reach its target.  */
   if (get_attr_length (insn) != 24
       && get_attr_length (insn) != 16)