[gimplefe] Add __BIT_FIELD_REF parsing

Message ID alpine.LSU.2.20.1905151302350.10704@zhemvz.fhfr.qr
State New
Headers show
Series
  • [gimplefe] Add __BIT_FIELD_REF parsing
Related show

Commit Message

Richard Biener May 15, 2019, 11:03 a.m.
Amends basic vector support.

Bootstrap / regtest pending on x86_64-unknown-linux-gnu.

Richard.

2019-05-15  Richard Biener  <rguenther@suse.de>

	c/
	* gimple-parser.c (c_parser_gimple_postfix_expression): Handle
	__BIT_FIELD_REF.

	* tree-pretty-print.c (dump_generic_node): Dump BIT_FIELD_REF
	as __BIT_FIELD_REF with type with -gimple.

	* gcc.dg/gimplefe-40.c: Amend.

Patch

Index: gcc/c/gimple-parser.c
===================================================================
--- gcc/c/gimple-parser.c	(revision 271203)
+++ gcc/c/gimple-parser.c	(working copy)
@@ -1415,6 +1415,43 @@  c_parser_gimple_postfix_expression (gimp
 		}
 	      break;
 	    }
+	  else if (strcmp (IDENTIFIER_POINTER (id), "__BIT_FIELD_REF") == 0)
+	    {
+	      /* __BIT_FIELD_REF '<' type-name [ ',' number ] '>'
+	                        '(' postfix-expression, integer, integer ')'  */
+	      location_t loc = c_parser_peek_token (parser)->location;
+	      c_parser_consume_token (parser);
+	      tree type = c_parser_gimple_typespec (parser);
+	      if (c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
+		{
+		  c_expr op0 = c_parser_gimple_postfix_expression (parser);
+		  c_parser_skip_until_found (parser, CPP_COMMA,
+					     "expected %<,%>");
+		  c_expr op1 = c_parser_gimple_postfix_expression (parser);
+		  if (TREE_CODE (op1.value) != INTEGER_CST
+		      || !int_fits_type_p (op1.value, bitsizetype))
+		    c_parser_error (parser, "expected constant size");
+		  c_parser_skip_until_found (parser, CPP_COMMA,
+					     "expected %<,%>");
+		  c_expr op2 = c_parser_gimple_postfix_expression (parser);
+		  if (TREE_CODE (op2.value) != INTEGER_CST
+		      || !int_fits_type_p (op2.value, bitsizetype))
+		    c_parser_error (parser, "expected constant offset");
+		  c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
+					     "expected %<)%>");
+		  if (type
+		      && op0.value != error_mark_node
+		      && TREE_CODE (op1.value) == INTEGER_CST
+		      && TREE_CODE (op2.value) == INTEGER_CST)
+		    expr.value = build3_loc (loc, BIT_FIELD_REF, type,
+					     op0.value,
+					     fold_convert (bitsizetype,
+							   op1.value),
+					     fold_convert (bitsizetype,
+							   op2.value));
+		}
+	      break;
+	    }
 	  else if (strcmp (IDENTIFIER_POINTER (id), "_Literal") == 0)
 	    {
 	      /* _Literal '(' type-name ')' ( [ '-' ] constant | constructor ) */
Index: gcc/tree-pretty-print.c
===================================================================
--- gcc/tree-pretty-print.c	(revision 271203)
+++ gcc/tree-pretty-print.c	(working copy)
@@ -2111,13 +2111,39 @@  dump_generic_node (pretty_printer *pp, t
       break;
 
     case BIT_FIELD_REF:
-      pp_string (pp, "BIT_FIELD_REF <");
-      dump_generic_node (pp, TREE_OPERAND (node, 0), spc, flags, false);
-      pp_string (pp, ", ");
-      dump_generic_node (pp, TREE_OPERAND (node, 1), spc, flags, false);
-      pp_string (pp, ", ");
-      dump_generic_node (pp, TREE_OPERAND (node, 2), spc, flags, false);
-      pp_greater (pp);
+      if (flags & TDF_GIMPLE)
+	{
+	  pp_string (pp, "__BIT_FIELD_REF <");
+	  dump_generic_node (pp, TREE_TYPE (node),
+			     spc, flags | TDF_SLIM, false);
+	  if (TYPE_ALIGN (TREE_TYPE (node))
+	      != TYPE_ALIGN (TYPE_MAIN_VARIANT (TREE_TYPE (node))))
+	    {
+	      pp_string (pp, ", ");
+	      pp_decimal_int (pp, TYPE_ALIGN (TREE_TYPE (node)));
+	    }
+	  pp_greater (pp);
+	  pp_string (pp, " (");
+	  dump_generic_node (pp, TREE_OPERAND (node, 0), spc,
+			     flags | TDF_SLIM, false);
+	  pp_string (pp, ", ");
+	  dump_generic_node (pp, TREE_OPERAND (node, 1), spc,
+			     flags | TDF_SLIM, false);
+	  pp_string (pp, ", ");
+	  dump_generic_node (pp, TREE_OPERAND (node, 2), spc,
+			     flags | TDF_SLIM, false);
+	  pp_right_paren (pp);
+	}
+      else
+	{
+	  pp_string (pp, "BIT_FIELD_REF <");
+	  dump_generic_node (pp, TREE_OPERAND (node, 0), spc, flags, false);
+	  pp_string (pp, ", ");
+	  dump_generic_node (pp, TREE_OPERAND (node, 1), spc, flags, false);
+	  pp_string (pp, ", ");
+	  dump_generic_node (pp, TREE_OPERAND (node, 2), spc, flags, false);
+	  pp_greater (pp);
+	}
       break;
 
     case BIT_INSERT_EXPR:
Index: gcc/testsuite/gcc.dg/gimplefe-40.c
===================================================================
--- gcc/testsuite/gcc.dg/gimplefe-40.c	(revision 271203)
+++ gcc/testsuite/gcc.dg/gimplefe-40.c	(working copy)
@@ -1,15 +1,21 @@ 
 /* { dg-do compile { target int128 } } */
-/* { dg-options "-fgimple -Wno-psabi -w" } */
+/* { dg-options "-fgimple" } */
 
 typedef float v4sf __attribute__((vector_size(16)));
-v4sf __GIMPLE (ssa)
+float __GIMPLE (ssa)
 load (const void * p)
 {
   __int128 unsigned _3;
   v4sf _4;
+  float _5;
 
   __BB(2):
   _3 = __MEM <__int128 unsigned, 8> ((char *)p_2(D));
   _4 = __VIEW_CONVERT <v4sf>(_3);
-  return _4;
+#if __SIZEOF_FLOAT__ == 4
+  _5 = __BIT_FIELD_REF <float> (_4, 32, 64);
+#else
+  _5 = 1.0f;
+#endif
+  return _5;
 }