aboutsummaryrefslogtreecommitdiff
path: root/gcc/config/pa/pa.c
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/config/pa/pa.c
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/config/pa/pa.c')
-rw-r--r--gcc/config/pa/pa.c40
1 files changed, 37 insertions, 3 deletions
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);
}