View | Details | Return to bug 13585
Collapse All | Expand All

(-)config/sh/sh-protos.h (+1 lines)
Lines 131-136 extern bool sh_cannot_change_mode_class Link Here
131
extern void sh_mark_label PARAMS ((rtx, int));
131
extern void sh_mark_label PARAMS ((rtx, int));
132
extern int sh_register_move_cost
132
extern int sh_register_move_cost
133
  PARAMS ((enum machine_mode mode, enum reg_class, enum reg_class));
133
  PARAMS ((enum machine_mode mode, enum reg_class, enum reg_class));
134
extern int check_use_sfunc_addr (rtx, rtx);
134
135
135
#ifdef HARD_CONST
136
#ifdef HARD_CONST
136
extern void fpscr_set_from_mem PARAMS ((int, HARD_REG_SET));
137
extern void fpscr_set_from_mem PARAMS ((int, HARD_REG_SET));
(-)config/sh/sh.c (+47 lines)
Lines 7857-7860 sh_register_operand (op, mode) Link Here
7857
  return register_operand (op, mode);
7857
  return register_operand (op, mode);
7858
}
7858
}
7859
7859
7860
/* INSN is an sfunc; return the rtx that describes the address used.  */
7861
static rtx
7862
extract_sfunc_addr (rtx insn)
7863
{
7864
  rtx pattern, part = NULL_RTX;
7865
  int len, i;
7866
7867
  pattern = PATTERN (insn);
7868
  len = XVECLEN (pattern, 0);
7869
  for (i = 0; i < len; i++)
7870
    {
7871
      part = XVECEXP (pattern, 0, i);
7872
      if (GET_CODE (part) == USE && GET_MODE (XEXP (part, 0)) == Pmode
7873
	  && GENERAL_REGISTER_P (true_regnum (XEXP (part, 0))))
7874
	return XEXP (part, 0);
7875
    }
7876
  if (GET_CODE (XVECEXP (pattern, 0, 0)) == UNSPEC_VOLATILE)
7877
    return XVECEXP (XVECEXP (pattern, 0, 0), 0, 1);
7878
  abort ();
7879
}
7880
7881
/* Verify that the register in use_sfunc_addr still agrees with the address
7882
   used in the sfunc.  This prevents fill_slots_from_thread from changing
7883
   use_sfunc_addr.
7884
   INSN is the use_sfunc_addr instruction, and REG is the register it
7885
   guards.  */
7886
int
7887
check_use_sfunc_addr (rtx insn, rtx reg)
7888
{
7889
  /* Search for the sfunc.  It should really come right after INSN.  */
7890
  while ((insn = NEXT_INSN (insn)))
7891
    {
7892
      if (GET_CODE (insn) == CODE_LABEL || GET_CODE (insn) == JUMP_INSN)
7893
	break;
7894
      if (! INSN_P (insn))
7895
	continue;
7896
	
7897
      if (GET_CODE (PATTERN (insn)) == SEQUENCE)
7898
	insn = XVECEXP (PATTERN (insn), 0, 0);
7899
      if (GET_CODE (PATTERN (insn)) != PARALLEL
7900
	  || get_attr_type (insn) != TYPE_SFUNC)
7901
	continue;
7902
      return rtx_equal_p (extract_sfunc_addr (insn), reg);
7903
    }
7904
  abort ();
7905
}
7906
7860
#include "gt-sh.h"
7907
#include "gt-sh.h"
(-)config/sh/sh.md (-1 / +1 lines)
Lines 1220-1226 Link Here
1220
(define_insn "use_sfunc_addr"
1220
(define_insn "use_sfunc_addr"
1221
  [(set (reg:SI PR_REG)
1221
  [(set (reg:SI PR_REG)
1222
	(unspec:SI [(match_operand:SI 0 "register_operand" "r")] UNSPEC_SFUNC))]
1222
	(unspec:SI [(match_operand:SI 0 "register_operand" "r")] UNSPEC_SFUNC))]
1223
  "TARGET_SH1"
1223
  "TARGET_SH1 && check_use_sfunc_addr (insn, operands[0])"
1224
  ""
1224
  ""
1225
  [(set_attr "length" "0")])
1225
  [(set_attr "length" "0")])
1226
1226

Return to bug 13585