Steven Bosscher wrote:

> GCC uses fake JUMP_INSNs as placeholders for jump table data. These
> JUMP_INSNs have an ADDR_VEC or ADDR_DIFF_VEC as PATTERN, but they are
> not real instructions and they are not inside basic blocks. This
> results in special-casing JUMP_P insns in various places throughout
> the compiler.
> 
> The attached patch adds a new object, JUMP_TABLE_DATA, to hold jump
> table data. All remaining JUMP_P insns will be real insns, which helps
> simplify things a bit -- or at least make things more intuitive.

This broke the SPU target.  The emit_nop_for_insn routine needs to handle
jump tables as well, but performs operations that now no longer work on
the new JUMP_TABLE_DATA object (in particular getting attributes,
inspecting INSN_LOCATION).

Fix this by handling JUMP_TABLE_DATA separately from real insns.

Tested on spu-elf.  Committed to mainline.

Bye,
Ulrich


ChangeLog:

        * config/spu/spu.c (emit_nop_for_insn): Handle JUMP_TABLE_DATA.

Index: gcc/config/spu/spu.c
===================================================================
*** gcc/config/spu/spu.c        (revision 197352)
--- gcc/config/spu/spu.c        (working copy)
*************** static struct spu_bb_info *spu_bb_info;
*** 1978,1990 ****
  /* Emit a nop for INSN such that the two will dual issue.  This assumes
     INSN is 8-byte aligned.  When INSN is inline asm we emit an lnop.
     We check for TImode to handle a MULTI1 insn which has dual issued its
!    first instruction.  get_pipe returns -1 for MULTI0, inline asm, or
!    ADDR_VEC insns. */
  static void
  emit_nop_for_insn (rtx insn)
  {
    int p;
    rtx new_insn;
    p = get_pipe (insn);
    if ((CALL_P (insn) || JUMP_P (insn)) && SCHED_ON_EVEN_P (insn))
      new_insn = emit_insn_after (gen_lnop (), insn);
--- 1978,1999 ----
  /* Emit a nop for INSN such that the two will dual issue.  This assumes
     INSN is 8-byte aligned.  When INSN is inline asm we emit an lnop.
     We check for TImode to handle a MULTI1 insn which has dual issued its
!    first instruction.  get_pipe returns -1 for MULTI0 or inline asm.  */
  static void
  emit_nop_for_insn (rtx insn)
  {
    int p;
    rtx new_insn;
+ 
+   /* We need to handle JUMP_TABLE_DATA separately.  */
+   if (JUMP_TABLE_DATA_P (insn))
+     {
+       new_insn = emit_insn_after (gen_lnop(), insn);
+       recog_memoized (new_insn);
+       INSN_LOCATION (new_insn) = UNKNOWN_LOCATION;
+       return;
+     }
+ 
    p = get_pipe (insn);
    if ((CALL_P (insn) || JUMP_P (insn)) && SCHED_ON_EVEN_P (insn))
      new_insn = emit_insn_after (gen_lnop (), insn);

-- 
  Dr. Ulrich Weigand
  GNU Toolchain for Linux on System z and Cell BE
  ulrich.weig...@de.ibm.com

Reply via email to