aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJeffrey A Law <law@cygnus.com>1998-09-09 21:31:17 +0000
committerJeff Law <law@gcc.gnu.org>1998-09-09 15:31:17 -0600
commite1e837810ee2bbfa22c4529a11ebc3a3a66aafbb (patch)
treebb47f155392ed7db586bbedd2ef18e309aee8abe /gcc
parent1e5bd8410b935246410e9b3c6d4428632afa05f9 (diff)
downloadgcc-e1e837810ee2bbfa22c4529a11ebc3a3a66aafbb.zip
gcc-e1e837810ee2bbfa22c4529a11ebc3a3a66aafbb.tar.gz
gcc-e1e837810ee2bbfa22c4529a11ebc3a3a66aafbb.tar.bz2
pa.c (pa_reorg): New marking scheme for jumps inside switch tables.
* 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
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog7
-rw-r--r--gcc/config/pa/pa.c40
-rw-r--r--gcc/config/pa/pa.md11
3 files changed, 48 insertions, 10 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 5925e02..af6291d 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -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>
diff --git a/gcc/config/pa/pa.c b/gcc/config/pa/pa.c
index c3395cf..a3eab2a 100644
--- a/gcc/config/pa/pa.c
+++ b/gcc/config/pa/pa.c
@@ -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);
}
diff --git a/gcc/config/pa/pa.md b/gcc/config/pa/pa.md
index ac3062a..2f3848c 100644
--- a/gcc/config/pa/pa.md
+++ b/gcc/config/pa/pa.md
@@ -3910,19 +3910,16 @@
""
[(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)