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
This commit is contained in:
Jeffrey A Law 1998-09-09 21:31:17 +00:00 committed by Jeff Law
parent 1e5bd8410b
commit e1e837810e
3 changed files with 48 additions and 10 deletions

View 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>

View 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);
}

View File

@ -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)