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:
parent
1e5bd8410b
commit
e1e837810e
|
@ -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)
|
||||
|
|
Loading…
Reference in New Issue