Commit e1e83781 by Jeffrey A Law Committed by Jeff Law

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
parent 1e5bd841
......@@ -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>
......
......@@ -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);
}
......
......@@ -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)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment