This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[xstormy16] add support for more opcodes


This patch adds support for a variety of special-purpose opcodes that
the xstormy16 supports, mostly dealing with addresses in the 0..255
and 0x7f00..0x7fff range.  This was done at Sanyo's request; they
chose the attribute syntax.

Some of the opcodes are supported through simple patterns; others
require extra passes (conditional branches, for example) to fully
support them.

Tested with no regressions after the -fno-web patch is applied.

	* config/stormy16/stormy16.c (xstormy16_splittable_below100_operand): New.
	(xstormy16_splittable_below100_or_register): New.
	(combine_bnp): New.
	(xstormy16_reorg): New.
	(TARGET_MACHINE_DEPENDENT_REORG): Define.


	* config/stormy16/stormy16.md (movqi_internal): Make name public.
	(movhi_internal): Likewise.
	(cbhranchhi): Likewise.
	(cbhranchhi_neg): Likewise.
	(andhi3): Only allow splittable below100 operands.
	(iorhi3): Likewise.
	(peephole2): New and/zero_extend->and peephole.
	(peephole2): New load/ior/save->set1 peephole.
	(peephole2): New load/and/save->clr1 peephole.
	(bclrx, bclrx2, bclr7, bclr15): New.
	(bsetx, bsetx2, bset7, bset15): New.

	* config/stormy16/stormy16.c (xstormy16_print_operand): Be more
	liberal about acceptable 'B' masks.

	* config/stormy16/stormy16-protos.h
	(xstormy16_asm_output_aligned_common, xstormy16_below100_symbol,
	xstormy16_below100_operand, xstormy16_below100_or_register,
	xstormy16_onebit_set_operand, xstormy16_onebit_clr_operand): New.
	(PREDICATE_CODES): Add new predicates.
	
	* config/stormy16/stormy16.c
	(xstormy16_asm_output_aligned_common, xstormy16_below100_symbol,
	xstormy16_below100_operand, xstormy16_below100_or_register,
	xstormy16_onebit_set_operand, xstormy16_onebit_clr_operand): New.
	(xstormy16_expand_iorqi3, xstormy16_expand_andqi3): New.
	(xstormy16_legitimate_address_p): Allow below100 symbols.
	(xstormy16_extra_constraint_p): Add 'W' for below100 operands.
	(xstormy16_expand_move): Leave below100 operands as-is.
	(xstormy16_encode_section_info): Encode below100 symbols.
	(xstormy16_strip_name_encoding): New.
	(xstormy16_print_operand): Print 'b' as shift mask.
	(xstormy16_attribute_table): Add below100 attributes.
	(xstormy16_handle_below100_attribute): New.

	* config/stormy16/stormy16.h (EXTRA_SECTIONS): add in_bss100.
	(XSTORMY16_SECTION_FUNCTION): New.
	(EXTRA_SECTION_FUNCTIONS): Define using the above.
	(ASM_OUTPUT_ALIGNED_DECL_COMMON, ASM_OUTPUT_ALIGNED_DECL_LOCAL): New.
	(ASM_OUTPUT_SYMBOL_REF): Handle encoded symbols.
	(ASM_OUTPUT_LABELREF): Define.

	* config/stormy16/stormy16.md (movqi_internal): Add below100 support.
	(movhi_internal): Add below100 support.
	(andhi3): Add below100 support.
	(iorhi3): Add below100 support.
	(iorqi3, iorqi3_internal, andqi3, andqi3_internal): New.

Index: stormy16-protos.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/stormy16/stormy16-protos.h,v
retrieving revision 1.17
diff -p -U1 -r1.17 stormy16-protos.h
--- stormy16-protos.h	9 Jul 2004 10:07:54 -0000	1.17
+++ stormy16-protos.h	16 Aug 2004 20:23:13 -0000
@@ -31,2 +31,9 @@ extern int xstormy16_epilogue_uses (int)
 extern void xstormy16_function_profiler (void);
+extern const char *xstormy16_strip_name_encoding (const char *name);
+extern void bss100_section (void);
+
+#if defined (TREE_CODE)
+extern void xstormy16_asm_output_aligned_common (FILE *, tree, const char *,
+						 int, int, int);
+#endif
 
@@ -58,2 +65,4 @@ extern void xstormy16_output_addr_vec (F
 extern void xstormy16_expand_call (rtx, rtx, rtx);
+extern void xstormy16_expand_iorqi3 (rtx *);
+extern void xstormy16_expand_andqi3 (rtx *);
 #endif
@@ -81,2 +90,9 @@ extern const char * xstormy16_output_shi
 					    rtx, rtx, rtx);
+extern int  xstormy16_below100_symbol (rtx, enum machine_mode);
+extern int  xstormy16_below100_operand (rtx, enum machine_mode);
+extern int  xstormy16_splittable_below100_operand (rtx, enum machine_mode);
+extern int  xstormy16_below100_or_register (rtx, enum machine_mode);
+extern int  xstormy16_splittable_below100_or_register (rtx, enum machine_mode);
+extern int xstormy16_onebit_set_operand (rtx, enum machine_mode);
+extern int xstormy16_onebit_clr_operand (rtx, enum machine_mode);
 #endif
Index: stormy16.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/stormy16/stormy16.c,v
retrieving revision 1.65
diff -p -U1 -r1.65 stormy16.c
--- stormy16.c	15 Aug 2004 15:45:19 -0000	1.65
+++ stormy16.c	16 Aug 2004 20:23:14 -0000
@@ -551,2 +551,180 @@ xstormy16_preferred_reload_class (rtx x,
 
+int
+xstormy16_below100_symbol (rtx x,
+			   enum machine_mode mode ATTRIBUTE_UNUSED)
+{
+  if (GET_CODE (x) == CONST)
+    x = XEXP (x, 0);
+  if (GET_CODE (x) == PLUS
+      && GET_CODE (XEXP (x, 1)) == CONST_INT)
+    x = XEXP (x, 0);
+  if (GET_CODE (x) == SYMBOL_REF)
+    {
+      const char *n = XSTR (x, 0);
+      if (n[0] == '@' && n[1] == 'b' && n[2] == '.')
+	return 1;
+    }
+  if (GET_CODE (x) == CONST_INT)
+    {
+      HOST_WIDE_INT i = INTVAL (x);
+      if ((i >= 0x0000 && i <= 0x00ff)
+	  || (i >= 0x7f00 && i <= 0x7fff))
+	return 1;
+    }
+  return 0;
+}
+
+int
+xstormy16_below100_operand (rtx x, enum machine_mode mode)
+{
+  if (GET_MODE (x) != mode)
+    return 0;
+  if (GET_CODE (x) == MEM)
+    x = XEXP (x, 0);
+  else if (GET_CODE (x) == SUBREG
+	   && GET_CODE (XEXP (x, 0)) == MEM
+	   && !MEM_VOLATILE_P (XEXP (x, 0)))
+    x = XEXP (XEXP (x, 0), 0);
+  else
+    return 0;
+  if (GET_CODE (x) == CONST_INT)
+    {
+      HOST_WIDE_INT i = INTVAL (x);
+      return (i >= 0x7f00 && i < 0x7fff);
+    }
+  return xstormy16_below100_symbol (x, HImode);
+}
+
+int
+xstormy16_splittable_below100_operand (rtx x, enum machine_mode mode)
+{
+  if (GET_CODE (x) == MEM && MEM_VOLATILE_P (x))
+    return 0;
+  return xstormy16_below100_operand (x, mode);
+}
+
+int
+xstormy16_below100_or_register (rtx x, enum machine_mode mode)
+{
+  return (xstormy16_below100_operand (x, mode)
+	  || register_operand (x, mode));
+}
+
+int
+xstormy16_splittable_below100_or_register (rtx x, enum machine_mode mode)
+{
+  if (GET_CODE (x) == MEM && MEM_VOLATILE_P (x))
+    return 0;
+  return (xstormy16_below100_operand (x, mode)
+	  || register_operand (x, mode));
+}
+
+int
+xstormy16_onebit_set_operand (rtx x, enum machine_mode mode)
+{
+  HOST_WIDE_INT i;
+  if (GET_CODE (x) != CONST_INT)
+    return 0;
+  i = INTVAL (x);
+  if (mode == QImode)
+    i &= 0xff;
+  if (mode == HImode)
+    i &= 0xffff;
+  return exact_log2 (i) != -1;
+}
+
+int
+xstormy16_onebit_clr_operand (rtx x, enum machine_mode mode)
+{
+  HOST_WIDE_INT i;
+  if (GET_CODE (x) != CONST_INT)
+    return 0;
+  i = ~ INTVAL (x);
+  if (mode == QImode)
+    i &= 0xff;
+  if (mode == HImode)
+    i &= 0xffff;
+  return exact_log2 (i) != -1;
+}
+
+void
+xstormy16_expand_iorqi3 (rtx *operands)
+{
+  rtx in, out, outsub, val;
+
+  out = operands[0];
+  in = operands[1];
+  val = operands[2];
+
+  if (xstormy16_onebit_set_operand (val, QImode))
+    {
+      if (!xstormy16_below100_or_register (in, QImode))
+	in = copy_to_mode_reg (QImode, in);
+      if (!xstormy16_below100_or_register (out, QImode))
+	out = gen_reg_rtx (QImode);
+      emit_insn (gen_iorqi3_internal (out, in, val));
+      if (out != operands[0])
+	emit_move_insn (operands[0], out);
+      return;
+    }
+
+  if (GET_CODE (in) != REG)
+    in = copy_to_mode_reg (QImode, in);
+  if (GET_CODE (val) != REG
+      && GET_CODE (val) != CONST_INT)
+    val = copy_to_mode_reg (QImode, val);
+  if (GET_CODE (out) != REG)
+    out = gen_reg_rtx (QImode);
+
+  in = simplify_gen_subreg (HImode, in, QImode, 0);
+  outsub = simplify_gen_subreg (HImode, out, QImode, 0);
+  if (GET_CODE (val) != CONST_INT)
+    val = simplify_gen_subreg (HImode, val, QImode, 0);
+
+  emit_insn (gen_iorhi3 (outsub, in, val));
+
+  if (out != operands[0])
+    emit_move_insn (operands[0], out);
+}
+
+void
+xstormy16_expand_andqi3 (rtx *operands)
+{
+  rtx in, out, outsub, val;
+
+  out = operands[0];
+  in = operands[1];
+  val = operands[2];
+
+  if (xstormy16_onebit_clr_operand (val, QImode))
+    {
+      if (!xstormy16_below100_or_register (in, QImode))
+	in = copy_to_mode_reg (QImode, in);
+      if (!xstormy16_below100_or_register (out, QImode))
+	out = gen_reg_rtx (QImode);
+      emit_insn (gen_andqi3_internal (out, in, val));
+      if (out != operands[0])
+	emit_move_insn (operands[0], out);
+      return;
+    }
+
+  if (GET_CODE (in) != REG)
+    in = copy_to_mode_reg (QImode, in);
+  if (GET_CODE (val) != REG
+      && GET_CODE (val) != CONST_INT)
+    val = copy_to_mode_reg (QImode, val);
+  if (GET_CODE (out) != REG)
+    out = gen_reg_rtx (QImode);
+
+  in = simplify_gen_subreg (HImode, in, QImode, 0);
+  outsub = simplify_gen_subreg (HImode, out, QImode, 0);
+  if (GET_CODE (val) != CONST_INT)
+    val = simplify_gen_subreg (HImode, val, QImode, 0);
+
+  emit_insn (gen_andhi3 (outsub, in, val));
+
+  if (out != operands[0])
+    emit_move_insn (operands[0], out);
+}
+
 #define LEGITIMATE_ADDRESS_INTEGER_P(X, OFFSET)				\
@@ -581,2 +759,5 @@ xstormy16_legitimate_address_p (enum mac
     return 1;
+
+  if (xstormy16_below100_symbol(x, mode))
+    return 1;
   
@@ -670,2 +851,5 @@ xstormy16_extra_constraint_p (rtx x, int
 
+    case 'W':
+      return xstormy16_below100_operand(x, GET_MODE(x));
+
     default:
@@ -870,2 +1054,3 @@ xstormy16_expand_move (enum machine_mode
 	  || ! xstormy16_legitimate_address_p (mode, XEXP (dest, 0), 0))
+      && ! xstormy16_below100_operand (dest, mode)
       && GET_CODE (src) != REG
@@ -1491,2 +1676,108 @@ xstormy16_asm_output_mi_thunk (FILE *fil
 
+void
+xstormy16_asm_output_aligned_common (FILE *stream,
+				     tree decl ATTRIBUTE_UNUSED,
+				     const char *name,
+				     int size,
+				     int align,
+				     int global)
+{
+  if (name[0] == '@' && name[2] == '.')
+    {
+      const char *op = 0;
+      switch (name[1])
+	{
+	case 'b':
+	  bss100_section();
+	  op = "space";
+	  break;
+	}
+      if (op)
+	{
+	  const char *name2;
+	  int p2align = 0;
+
+	  while (align > 8)
+	    {
+	      align /= 2;
+	      p2align ++;
+	    }
+	  name2 = xstormy16_strip_name_encoding (name);
+	  if (global)
+	    fprintf (stream, "\t.globl\t%s\n", name2);
+	  if (p2align)
+	    fprintf (stream, "\t.p2align %d\n", p2align);
+	  fprintf (stream, "\t.type\t%s, @object\n", name2);
+	  fprintf (stream, "\t.size\t%s, %d\n", name2, size);
+	  fprintf (stream, "%s:\n\t.%s\t%d\n", name2, op, size);
+	  return;
+	}
+    }
+
+  if (!global)
+    {
+      fprintf (stream, "\t.local\t");
+      assemble_name (stream, name);
+      fprintf (stream, "\n");
+    }
+  fprintf (stream, "\t.comm\t");
+  assemble_name (stream, name);
+  fprintf (stream, ",%u,%u\n", size, align);
+}
+
+/* Mark functions with SYMBOL_REF_FLAG.  */
+
+static void
+xstormy16_encode_section_info (tree decl,
+			       rtx r,
+			       int first ATTRIBUTE_UNUSED)
+{
+  if (TREE_CODE (decl) == VAR_DECL
+      && (lookup_attribute ("below100", DECL_ATTRIBUTES (decl))
+	  || lookup_attribute ("BELOW100", DECL_ATTRIBUTES (decl))))
+    {
+      const char *newsection = 0;
+      char *newname;
+      tree idp;
+      rtx rtlname, rtl;
+      const char *oldname;
+
+      rtl = r;
+      rtlname = XEXP (rtl, 0);
+      if (GET_CODE (rtlname) == SYMBOL_REF)
+	oldname = XSTR (rtlname, 0);
+      else if (GET_CODE (rtlname) == MEM
+	       && GET_CODE (XEXP (rtlname, 0)) == SYMBOL_REF)
+	oldname = XSTR (XEXP (rtlname, 0), 0);
+      else
+	abort ();
+
+      if (DECL_INITIAL (decl))
+	{
+	  newsection = ".data_below100";
+	  DECL_SECTION_NAME (decl) = build_string (strlen (newsection), newsection);
+	}
+
+      newname = alloca (strlen (oldname) + 4);
+      sprintf (newname, "@b.%s", oldname);
+      idp = get_identifier (newname);
+      XEXP (rtl, 0) =
+	gen_rtx_SYMBOL_REF (Pmode, IDENTIFIER_POINTER (idp));
+    }
+}
+
+const char *
+xstormy16_strip_name_encoding (const char *name)
+{
+  while (1)
+    {
+      if (name[0] == '@' && name[2] == '.')
+	name += 3;
+      else if (name[0] == '*')
+	name ++;
+      else
+	return name;
+    }
+}
+
 /* Output constructors and destructors.  Just like 
@@ -1605,2 +1896,3 @@ xstormy16_print_operand (FILE *file, rtx
       {
+	static int bits_set[8] = { 0, 1, 1, 2, 1, 2, 2, 3 };
 	HOST_WIDE_INT xx = 1;
@@ -1613,5 +1905,26 @@ xstormy16_print_operand (FILE *file, rtx
 	
-	l = exact_log2 (xx);
-	if (l == -1)
-	  l = exact_log2 (~xx);
+	/* GCC seems to randomly sign-extend masks with the MSB set,
+	   so we have to detect all the cases that differ only in sign
+	   extension beyond the bits we care about.  Normally, the
+	   predicates and constraints ensure that we have the right
+	   values.  This works correctly for valid masks.  */
+	if (bits_set[xx & 7] <= 1)
+	  {
+	    /* Remove sign extension bits.  */
+	    if ((~xx & ~(HOST_WIDE_INT)0xff) == 0)
+	      xx &= 0xff;
+	    else if ((~xx & ~(HOST_WIDE_INT)0xffff) == 0)
+	      xx &= 0xffff;
+	    l = exact_log2 (xx);
+	  }
+	else
+	  {
+	    /* Add sign extension bits.  */
+	    if ((xx & ~(HOST_WIDE_INT)0xff) == 0)
+	      xx |= ~(HOST_WIDE_INT)0xff;
+	    else if ((xx & ~(HOST_WIDE_INT)0xffff) == 0)
+	      xx |= ~(HOST_WIDE_INT)0xffff;
+	    l = exact_log2 (~xx);
+	  }
+
 	if (l == -1)
@@ -1652,2 +1965,20 @@ xstormy16_print_operand (FILE *file, rtx
 
+    case 'b':
+      /* Print the shift mask for bp/bn.  */
+      {
+	HOST_WIDE_INT xx = 1;
+	HOST_WIDE_INT l;
+
+	if (GET_CODE (x) == CONST_INT)
+	  xx = INTVAL (x);
+	else
+	  output_operand_lossage ("`B' operand is not constant");
+	
+	l = 7 - xx;
+	
+	fputs (IMMEDIATE_PREFIX, file);
+	fprintf (file, HOST_WIDE_INT_PRINT_DEC, l);
+	return;
+      }
+
     case 0:
@@ -2042,2 +2373,4 @@ static tree xstormy16_handle_interrupt_a
   (tree *, tree, tree, int, bool *);
+static tree xstormy16_handle_below100_attribute
+  (tree *, tree, tree, int, bool *);
 
@@ -2047,2 +2380,4 @@ static const struct attribute_spec xstor
   { "interrupt", 0, 0, false, true,  true,  xstormy16_handle_interrupt_attribute },
+  { "BELOW100",  0, 0, false, false, false, xstormy16_handle_below100_attribute },
+  { "below100",  0, 0, false, false, false, xstormy16_handle_below100_attribute },
   { NULL,        0, 0, false, false, false, NULL }
@@ -2067,2 +2402,30 @@ xstormy16_handle_interrupt_attribute (tr
 }
+
+/* Handle an "below" attribute;
+   arguments as in struct attribute_spec.handler.  */
+static tree
+xstormy16_handle_below100_attribute (tree *node,
+				     tree name ATTRIBUTE_UNUSED,
+				     tree args ATTRIBUTE_UNUSED,
+				     int flags ATTRIBUTE_UNUSED,
+				     bool *no_add_attrs)
+{
+  if (TREE_CODE (*node) != VAR_DECL
+      && TREE_CODE (*node) != POINTER_TYPE
+      && TREE_CODE (*node) != TYPE_DECL)
+    {
+      warning ("`__BELOW100__' attribute only applies to variables");
+      *no_add_attrs = true;
+    }
+  else if (args == NULL_TREE && TREE_CODE (*node) == VAR_DECL)
+    {
+      if (! (TREE_PUBLIC (*node) || TREE_STATIC (*node)))
+	{
+	  warning ("__BELOW100__ attribute not allowed with auto storage class.");
+	  *no_add_attrs = true;
+	}
+    }
+  
+  return NULL_TREE;
+}
 
@@ -2185,2 +2548,170 @@ xstormy16_expand_builtin(tree exp, rtx t
 
+
+/* Look for combinations of insns that can be converted to BN or BP
+   opcodes.  This is, unfortunately, too complex to do with MD
+   patterns.  */
+static void
+combine_bnp (rtx insn)
+{
+  int insn_code, regno, need_extend, mask;
+  rtx cond, reg, and, load, qireg, mem;
+  enum machine_mode load_mode = QImode;
+
+  insn_code = recog_memoized (insn);
+  if (insn_code != CODE_FOR_cbranchhi
+      && insn_code != CODE_FOR_cbranchhi_neg)
+    return;
+
+  cond = XVECEXP (PATTERN (insn), 0, 0); /* set */
+  cond = XEXP (cond, 1); /* if */
+  cond = XEXP (cond, 0); /* cond */
+  switch (GET_CODE (cond))
+    {
+    case NE:
+    case EQ:
+      need_extend = 0;
+      break;
+    case LT:
+    case GE:
+      need_extend = 1;
+      break;
+    default:
+      return;
+    }
+
+  reg = XEXP (cond, 0);
+  if (GET_CODE (reg) != REG)
+    return;
+  regno = REGNO (reg);
+  if (XEXP (cond, 1) != const0_rtx)
+    return;
+  if (! find_regno_note (insn, REG_DEAD, regno))
+    return;
+  qireg = gen_rtx_REG (QImode, regno);
+
+  if (need_extend)
+    {
+      /* LT and GE conditionals should have an sign extend before
+	 them.  */
+      for (and = prev_real_insn (insn); and; and = prev_real_insn (and))
+	{
+	  int and_code = recog_memoized (and);
+	  if (and_code == CODE_FOR_extendqihi2
+	      && rtx_equal_p (XEXP (PATTERN (and), 0), reg)
+	      && rtx_equal_p (XEXP (XEXP (PATTERN (and), 1), 0), qireg))
+	    {
+	      break;
+	    }
+	
+	  if (and_code == CODE_FOR_movhi_internal
+	      && rtx_equal_p (XEXP (PATTERN (and), 0), reg))
+	    {
+	      /* This is for testing bit 15.  */
+	      and = insn;
+	      break;
+	    }
+
+	  if (reg_mentioned_p (reg, and))
+	    return;
+	  if (GET_CODE (and) != NOTE
+	      && GET_CODE (and) != INSN)
+	    return;
+	}
+    }
+  else
+    {
+      /* EQ and NE conditionals have an AND before them.  */
+      for (and = prev_real_insn (insn); and; and = prev_real_insn (and))
+	{
+	  if (recog_memoized (and) == CODE_FOR_andhi3
+	      && rtx_equal_p (XEXP (PATTERN (and), 0), reg)
+	      && rtx_equal_p (XEXP (XEXP (PATTERN (and), 1), 0), reg))
+	    {
+	      break;
+	    }
+	
+	  if (reg_mentioned_p (reg, and))
+	    return;
+	  if (GET_CODE (and) != NOTE
+	      && GET_CODE (and) != INSN)
+	    return;
+	}
+    }
+  if (!and)
+    return;
+
+  for (load = prev_real_insn (and); load; load = prev_real_insn (load))
+    {
+      int load_code = recog_memoized (load);
+      if (load_code == CODE_FOR_movhi_internal
+	  && rtx_equal_p (XEXP (PATTERN (load), 0), reg)
+	  && xstormy16_below100_operand (XEXP (PATTERN (load), 1), HImode)
+	  && ! MEM_VOLATILE_P (XEXP (PATTERN (load), 1)))
+	{
+	  load_mode = HImode;
+	  break;
+	}
+
+      if (load_code == CODE_FOR_movqi_internal
+	  && rtx_equal_p (XEXP (PATTERN (load), 0), qireg)
+	  && xstormy16_below100_operand (XEXP (PATTERN (load), 1), QImode))
+	{
+	  load_mode = QImode;
+	  break;
+	}
+	
+      if (reg_mentioned_p (reg, load))
+	return;
+      if (GET_CODE (load) != NOTE
+	  && GET_CODE (load) != INSN)
+	return;
+    }
+  if (!load)
+    return;
+
+  if (!need_extend)
+    {
+      if (!xstormy16_onebit_set_operand (XEXP (XEXP (PATTERN (and), 1), 1), load_mode))
+	return;
+      mask = (int) INTVAL (XEXP (XEXP (PATTERN (and), 1), 1));
+    }
+  else
+    mask = (load_mode == HImode) ? 0x8000 : 0x80;
+
+  mem = XEXP (PATTERN (load), 1);
+  if (load_mode == HImode)
+    {
+      rtx addr = XEXP (mem, 0);
+      if (! (mask & 0xff))
+	{
+	  addr = plus_constant (addr, 1);
+	  mask >>= 8;
+	}
+      mem = gen_rtx_MEM (QImode, addr);
+    }
+
+  if (need_extend)
+    XEXP (cond, 0) = gen_rtx_SIGN_EXTEND (HImode, mem);
+  else
+    XEXP (cond, 0) = gen_rtx_AND (QImode, mem, GEN_INT (mask));
+  INSN_CODE (insn) = -1;
+  delete_insn (load);
+  if (and != insn)
+    delete_insn (and);
+}
+
+static void
+xstormy16_reorg (void)
+{
+  rtx insn;
+
+  for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
+    {
+      if (! JUMP_P (insn))
+	continue;
+      combine_bnp (insn);
+    }
+}
+
+
 /* Worker function for TARGET_RETURN_IN_MEMORY.  */
@@ -2198,2 +2729,6 @@ xstormy16_return_in_memory (tree type, t
 #define TARGET_ASM_ALIGNED_SI_OP "\t.word\t"
+#undef TARGET_ENCODE_SECTION_INFO
+#define TARGET_ENCODE_SECTION_INFO xstormy16_encode_section_info
+#undef TARGET_STRIP_NAME_ENCODING
+#define TARGET_STRIP_NAME_ENCODING xstormy16_strip_name_encoding
 
@@ -2224,2 +2759,5 @@ xstormy16_return_in_memory (tree type, t
 
+#undef TARGET_MACHINE_DEPENDENT_REORG
+#define TARGET_MACHINE_DEPENDENT_REORG xstormy16_reorg
+
 struct gcc_target targetm = TARGET_INITIALIZER;
Index: stormy16.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/stormy16/stormy16.h,v
retrieving revision 1.91
diff -p -U1 -r1.91 stormy16.h
--- stormy16.h	14 Jul 2004 06:24:26 -0000	1.91
+++ stormy16.h	16 Aug 2004 20:23:14 -0000
@@ -628,2 +628,18 @@ do {							\
 #define DTORS_SECTION_ASM_OP	"\t.section\t.dtors,\"a\""
+#define EXTRA_SECTIONS in_bss100
+
+#define XSTORMY16_SECTION_FUNCTION(name, in, string, bits) 				  \
+  void										  \
+  name ()									  \
+  { 										  \
+    if (in_section != in)							  \
+      { 									  \
+	fprintf (asm_out_file, "\t.section %s,\"aw\",@%sbits\n", string, bits);  \
+	in_section = in;							  \
+      }										  \
+  }
+
+#undef  EXTRA_SECTION_FUNCTIONS
+#define EXTRA_SECTION_FUNCTIONS		\
+  XSTORMY16_SECTION_FUNCTION (bss100_section, in_bss100, ".bss_below100", "no")
 
@@ -644,2 +660,7 @@ do {							\
 
+#define ASM_OUTPUT_ALIGNED_DECL_COMMON(STREAM, DECL, NAME, SIZE, ALIGNMENT) \
+  xstormy16_asm_output_aligned_common(STREAM, DECL, NAME, SIZE, ALIGNMENT, 1)
+#define ASM_OUTPUT_ALIGNED_DECL_LOCAL(STREAM, DECL, NAME, SIZE, ALIGNMENT) \
+  xstormy16_asm_output_aligned_common(STREAM, DECL, NAME, SIZE, ALIGNMENT, 0)
+
 
@@ -649,6 +670,9 @@ do {							\
   do {									\
+    const char *rn = XSTR (SYMBOL, 0);					\
+    if (rn[0] == '@' && rn[2] == '.')					\
+      rn += 3;								\
     if (SYMBOL_REF_FUNCTION_P (SYMBOL))					\
-      ASM_OUTPUT_LABEL_REF ((STREAM), XSTR (SYMBOL, 0));		\
+      ASM_OUTPUT_LABEL_REF ((STREAM), rn);				\
     else								\
-      assemble_name (STREAM, XSTR (SYMBOL, 0));				\
+      assemble_name (STREAM, rn);					\
   } while (0)
@@ -662,2 +686,5 @@ do  {						\
 
+#define ASM_OUTPUT_LABELREF(STREAM, NAME)	\
+  asm_fprintf ((STREAM), "%U%s", xstormy16_strip_name_encoding (NAME));
+
 /* Globalizing directive for a label.  */
@@ -787,2 +814,7 @@ do  {						\
   {"xstormy16_ineqsi_operator", {LT, GE, LTU, GEU }}, \
+  {"xstormy16_below100_operand", {MEM }}, \
+  {"xstormy16_below100_or_register", {MEM, REG }}, \
+  {"xstormy16_splittable_below100_or_register", {MEM, REG }}, \
+  {"xstormy16_onebit_clr_operand", {CONST_INT }}, \
+  {"xstormy16_onebit_set_operand", {CONST_INT }}, \
   {"nonimmediate_nonstack_operand", {REG, MEM}},
Index: stormy16.md
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/stormy16/stormy16.md,v
retrieving revision 1.14
diff -p -U1 -r1.14 stormy16.md
--- stormy16.md	10 Jun 2003 16:32:58 -0000	1.14
+++ stormy16.md	16 Aug 2004 20:23:14 -0000
@@ -132,5 +132,5 @@
 
-(define_insn "*movqi_internal"
-  [(set (match_operand:QI 0 "nonimmediate_nonstack_operand" "=r,m,e,e,T,r,S")
-	(match_operand:QI 1 "general_operand"       "r,e,m,i,i,i,i"))]
+(define_insn "movqi_internal"
+  [(set (match_operand:QI 0 "nonimmediate_nonstack_operand" "=r,m,e,e,T,r,S,W,r")
+	(match_operand:QI 1 "general_operand"       "r,e,m,i,i,i,i,ir,W"))]
   ""
@@ -143,2 +143,4 @@
    mov %0,%1
+   mov.b %0,%1
+   mov.b %0,%1
    mov.b %0,%1"
@@ -155,4 +157,6 @@
 	      (const_int 4)
-	      (const_int 4)])
-   (set_attr "psw_operand" "0,0,0,0,nop,0,nop")])
+	      (const_int 4)
+	      (const_int 2)
+	      (const_int 2)])
+   (set_attr "psw_operand" "0,0,0,0,nop,0,nop,0,0")])
 
@@ -180,5 +184,5 @@
 
-(define_insn "*movhi_internal"
-  [(set (match_operand:HI 0 "nonimmediate_nonstack_operand" "=r,m,e,e,T,r,S")
-	(match_operand:HI 1 "xs_hi_general_operand"       "r,e,m,L,L,i,i"))]
+(define_insn "movhi_internal"
+  [(set (match_operand:HI 0 "nonimmediate_nonstack_operand" "=r,m,e,e,T,r,S,W,r")
+	(match_operand:HI 1 "xs_hi_general_operand"       "r,e,m,L,L,i,i,ir,W"))]
   ""
@@ -191,2 +195,4 @@
    mov.w %0,%1
+   mov.w %0,%1
+   mov.w %0,%1
    mov.w %0,%1"
@@ -203,4 +209,6 @@
 	      (const_int 4)
+	      (const_int 4)
+	      (const_int 4)
 	      (const_int 4)])
-   (set_attr "psw_operand" "0,0,0,0,nop,0,nop")])
+   (set_attr "psw_operand" "0,0,0,0,nop,0,nop,0,0")])
 
@@ -554,5 +562,5 @@
 (define_insn "andhi3"
-  [(set (match_operand:HI 0 "register_operand" "=T,r,r,r")
-	(and:HI (match_operand:HI 1 "register_operand" "%0,0,0,0")
-		(match_operand:HI 2 "nonmemory_operand" "L,r,K,i")))]
+  [(set (match_operand:HI 0 "xstormy16_splittable_below100_or_register" "=T,r,r,r,W")
+	(and:HI (match_operand:HI 1 "xstormy16_below100_or_register" "%0,0,0,0,0")
+		(match_operand:HI 2 "nonmemory_operand" "L,r,K,i,K")))]
   ""
@@ -562,4 +570,21 @@
    clr1 %0,%B2
-   and %0,%2"
-  [(set_attr "length" "2,2,2,4")])
+   and %0,%2
+   #"
+  [(set_attr "length" "2,2,2,4,2")])
+
+(define_split
+  [(set (match_operand:HI 0 "xstormy16_below100_operand" "")
+	(and:HI (match_operand:HI 1 "xstormy16_below100_operand" "")
+		(match_operand:HI 2 "xstormy16_onebit_clr_operand" "")))]
+  ""
+  [(set (match_dup 3)
+	(and:QI (match_dup 4)
+		(match_dup 5)))]
+  "{ int s = ((INTVAL (operands[2]) & 0xff) == 0xff) ? 1 : 0;
+     operands[3] = simplify_gen_subreg (QImode, operands[0], HImode, s);
+     operands[4] = simplify_gen_subreg (QImode, operands[1], HImode, s);
+     operands[5] = simplify_gen_subreg (QImode, operands[2], HImode, s);
+     operands[5] = GEN_INT (INTVAL (operands[5]) | ~(HOST_WIDE_INT)0xff);
+   }
+")
 
@@ -567,5 +592,5 @@
 (define_insn "iorhi3"
-  [(set (match_operand:HI 0 "register_operand" "=T,r,r,r")
-	(ior:HI (match_operand:HI 1 "register_operand" "%0,0,0,0")
-		(match_operand:HI 2 "nonmemory_operand" "L,r,J,i")))]
+  [(set (match_operand:HI 0 "xstormy16_splittable_below100_or_register" "=T,r,r,r,W")
+	(ior:HI (match_operand:HI 1 "xstormy16_below100_or_register" "%0,0,0,0,0")
+		(match_operand:HI 2 "nonmemory_operand" "L,r,J,i,J")))]
   ""
@@ -575,4 +600,21 @@
    set1 %0,%B2
-   or %0,%2"
-  [(set_attr "length" "2,2,2,4")])
+   or %0,%2
+   #"
+  [(set_attr "length" "2,2,2,4,2")])
+
+(define_split
+  [(set (match_operand:HI 0 "xstormy16_below100_operand" "")
+	(ior:HI (match_operand:HI 1 "xstormy16_below100_operand" "")
+		(match_operand:HI 2 "xstormy16_onebit_set_operand" "")))]
+  ""
+  [(set (match_dup 3)
+	(ior:QI (match_dup 4)
+		(match_dup 5)))]
+  "{ int s = ((INTVAL (operands[2]) & 0xff) == 0x00) ? 1 : 0;
+     operands[3] = simplify_gen_subreg (QImode, operands[0], HImode, s);
+     operands[4] = simplify_gen_subreg (QImode, operands[1], HImode, s);
+     operands[5] = simplify_gen_subreg (QImode, operands[2], HImode, s);
+     operands[5] = GEN_INT (INTVAL (operands[5]) & 0xff);
+   }
+")
 
@@ -798,3 +840,3 @@
 
-(define_insn "*cbranchhi"
+(define_insn "cbranchhi"
   [(set (pc) 
@@ -816,3 +858,3 @@
 
-(define_insn "*cbranchhi_neg"
+(define_insn "cbranchhi_neg"
   [(set (pc) 
@@ -1097 +1139,206 @@
    (set_attr "psw_operand" "nop")])
+
+;;---------------------------------------------------------------------------
+
+(define_expand "iorqi3"
+  [(match_operand:QI 0 "xstormy16_below100_or_register" "")
+   (match_operand:QI 1 "xstormy16_below100_or_register" "")
+   (match_operand:QI 2 "nonmemory_operand" "")]
+  ""
+  "
+{
+  xstormy16_expand_iorqi3 (operands);
+  DONE;
+}")
+
+(define_insn "iorqi3_internal"
+  [(set (match_operand:QI 0 "xstormy16_below100_or_register" "=Wr")
+	(ior:QI (match_operand:QI 1 "xstormy16_below100_or_register" "0")
+		(match_operand:QI 2 "xstormy16_onebit_set_operand" "i")))]
+  ""
+  "set1 %0,%B2"
+  [(set_attr "length" "2")
+   (set_attr "psw_operand" "0")])
+
+(define_peephole2
+  [(set (match_operand:QI 0 "register_operand" "")
+	(match_operand:QI 1 "xstormy16_below100_operand" ""))
+   (set (match_operand:HI 2 "register_operand" "")
+	(ior:HI (match_operand:HI 3 "register_operand" "")
+		(match_operand:QI 4 "xstormy16_onebit_set_operand" "")))
+   (set (match_operand:QI 5 "xstormy16_below100_operand" "")
+	(match_operand:QI 6 "register_operand" ""))
+   ]
+  "REGNO (operands[0]) == REGNO (operands[2])
+   && REGNO (operands[0]) == REGNO (operands[3])
+   && REGNO (operands[0]) == REGNO (operands[6])
+   && rtx_equal_p (operands[1], operands[5])"
+  [(set (match_dup 1)
+	(ior:QI (match_dup 1)
+		(match_dup 4)))
+   ]
+  "")
+
+
+(define_expand "andqi3"
+  [(match_operand:QI 0 "xstormy16_below100_or_register" "")
+   (match_operand:QI 1 "xstormy16_below100_or_register" "")
+   (match_operand:QI 2 "nonmemory_operand" "")]
+  ""
+  "
+{
+  xstormy16_expand_andqi3 (operands);
+  DONE;
+}")
+
+(define_insn "andqi3_internal"
+  [(set (match_operand:QI 0 "xstormy16_below100_or_register" "=Wr")
+	(and:QI (match_operand:QI 1 "xstormy16_below100_or_register" "0")
+		(match_operand:QI 2 "xstormy16_onebit_clr_operand" "i")))]
+  ""
+  "clr1 %0,%B2"
+  [(set_attr "length" "2")
+   (set_attr "psw_operand" "0")])
+
+(define_peephole2
+  [(set (match_operand:HI 0 "register_operand" "")
+	(and:HI (match_operand:HI 1 "register_operand" "")
+		(match_operand 2 "immediate_operand" "")))
+   (set (match_operand:HI 3 "register_operand" "")
+	(zero_extend:HI (match_operand:QI 4 "register_operand" "")));
+   ]
+  "REGNO (operands[0]) == REGNO (operands[1])
+   && REGNO (operands[0]) == REGNO (operands[3])
+   && REGNO (operands[0]) == REGNO (operands[4])"
+  [(set (match_dup 0)
+	(and:HI (match_dup 1)
+		(match_dup 5)))
+   ]
+  "operands[5] = GEN_INT (INTVAL (operands[2]) & 0xff);")
+
+(define_peephole2
+  [(set (match_operand:QI 0 "register_operand" "")
+	(match_operand:QI 1 "xstormy16_below100_operand" ""))
+   (set (match_operand:HI 2 "register_operand" "")
+	(and:HI (match_operand:HI 3 "register_operand" "")
+		(match_operand:QI 4 "xstormy16_onebit_clr_operand" "")))
+   (set (match_operand:QI 5 "xstormy16_below100_operand" "")
+	(match_operand:QI 6 "register_operand" ""))
+   ]
+  "REGNO (operands[0]) == REGNO (operands[2])
+   && REGNO (operands[0]) == REGNO (operands[3])
+   && REGNO (operands[0]) == REGNO (operands[6])
+   && rtx_equal_p (operands[1], operands[5])"
+  [(set (match_dup 1)
+	(and:QI (match_dup 1)
+		(match_dup 4)))
+   ]
+  "")
+
+;; GCC uses different techniques to optimize MSB and LSB accesses, so
+;; we have to code those separately.
+
+(define_insn "*bclrx"
+  [(set (pc) 
+	(if_then_else (eq:HI (and:QI (match_operand:QI 1 "xstormy16_below100_operand" "W")
+				     (match_operand:HI 2 "immediate_operand" "i"))
+			     (const_int 0))
+		      (label_ref (match_operand 0 "" ""))
+		      (pc)))
+   (clobber (match_operand:BI 3 "" "=y"))]
+  ""
+  "bn %1,%B2,%l0"
+  [(set_attr "length" "4")
+   (set_attr "psw_operand" "nop")])
+
+(define_insn "*bclrx2"
+  [(set (pc) 
+	(if_then_else (zero_extract:HI
+		       (xor:HI (subreg:HI
+				(match_operand:QI 1 "xstormy16_below100_operand" "W") 0)
+			       (match_operand:HI 2 "xstormy16_onebit_set_operand" "J"))
+		       (const_int 1)
+		       (match_operand:HI 3 "immediate_operand" "i"))
+		      (label_ref (match_operand 0 "" ""))
+		      (pc)))
+   (clobber (match_operand:BI 4 "" "=y"))]
+  ""
+  "bn %1,%B2,%l0"
+  [(set_attr "length" "4")
+   (set_attr "psw_operand" "nop")])
+
+(define_insn "*bclr7"
+  [(set (pc) 
+	(if_then_else (xor:HI (lshiftrt:HI (subreg:HI
+					    (match_operand:QI 1 "xstormy16_below100_operand" "W") 0)
+					   (const_int 7))
+			      (const_int 1))
+		      (label_ref (match_operand 0 "" ""))
+		      (pc)))
+   (clobber (match_operand:BI 2 "" "=y"))]
+  ""
+  "bn %1,#7,%l0"
+  [(set_attr "length" "4")
+   (set_attr "psw_operand" "nop")])
+
+(define_insn "*bclr15"
+  [(set (pc) 
+	(if_then_else (ge:HI (sign_extend:HI (match_operand:QI 1 "xstormy16_below100_operand" "W"))
+			     (const_int 0))
+		      (label_ref (match_operand 0 "" ""))
+		      (pc)))
+   (clobber (match_operand:BI 2 "" "=y"))]
+  ""
+  "bn %1,#7,%l0"
+  [(set_attr "length" "4")
+   (set_attr "psw_operand" "nop")])
+
+(define_insn "*bsetx"
+  [(set (pc) 
+	(if_then_else (ne:HI (and:QI (match_operand:QI 1 "xstormy16_below100_operand" "W")
+				     (match_operand:HI 2 "immediate_operand" "i"))
+			     (const_int 0))
+		      (label_ref (match_operand 0 "" ""))
+		      (pc)))
+   (clobber (match_operand:BI 3 "" "=y"))]
+  ""
+  "bp %1,%B2,%l0"
+  [(set_attr "length" "4")
+   (set_attr "psw_operand" "nop")])
+
+(define_insn "*bsetx2"
+  [(set (pc) 
+	(if_then_else (zero_extract:HI (match_operand:QI 1 "xstormy16_below100_operand" "W")
+				       (const_int 1)
+				       (match_operand:HI 2 "immediate_operand" "i"))
+		      (label_ref (match_operand 0 "" ""))
+		      (pc)))
+   (clobber (match_operand:BI 3 "" "=y"))]
+  ""
+  "bp %1,%b2,%l0"
+  [(set_attr "length" "4")
+   (set_attr "psw_operand" "nop")])
+
+(define_insn "*bset7"
+  [(set (pc) 
+	(if_then_else (lshiftrt:HI (subreg:HI (match_operand:QI 1 "xstormy16_below100_operand" "W") 0)
+				   (const_int 7))
+		      (label_ref (match_operand 0 "" ""))
+		      (pc)))
+   (clobber (match_operand:BI 2 "" "=y"))]
+  ""
+  "bp %1,#7,%l0"
+  [(set_attr "length" "4")
+   (set_attr "psw_operand" "nop")])
+
+(define_insn "*bset15"
+  [(set (pc) 
+	(if_then_else (lt:HI (sign_extend:HI (match_operand:QI 1 "xstormy16_below100_operand" "W"))
+			     (const_int 0))
+		      (label_ref (match_operand 0 "" ""))
+		      (pc)))
+   (clobber (match_operand:BI 2 "" "=y"))]
+  ""
+  "bp %1,#7,%l0"
+  [(set_attr "length" "4")
+   (set_attr "psw_operand" "nop")])


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]