From 705762808c65a962a2a4a601114718bee1cb9862 Mon Sep 17 00:00:00 2001
From: David Malcolm <dmalcolm@redhat.com>
Date: Fri, 8 Apr 2016 13:45:14 -0400
Subject: [PATCH 051/101] FIXME: handle <retval> for REG_EXPR

---
 gcc/read-md.h          |  4 +++
 gcc/read-rtl.c         | 47 +++++++++++++++++++++++++-----
 gcc/rtl/rtl-frontend.c | 79 ++++++++++++++++++++++++++++++++++++++++++--------
 3 files changed, 110 insertions(+), 20 deletions(-)

diff --git a/gcc/read-md.h b/gcc/read-md.h
index 02a54ac..a011f64 100644
--- a/gcc/read-md.h
+++ b/gcc/read-md.h
@@ -121,6 +121,10 @@ class rtx_reader
 				     const char */*label*/)
   {}
 
+  virtual void add_fixup_reg_expr (file_location /*loc*/, rtx /*insn*/,
+				   const char */*desc*/)
+  {}
+
   file_location get_current_location () const;
 
   void update_location (bool advancing);
diff --git a/gcc/read-rtl.c b/gcc/read-rtl.c
index 018090a..442adc3 100644
--- a/gcc/read-rtl.c
+++ b/gcc/read-rtl.c
@@ -1191,6 +1191,39 @@ void maybe_read_location (int operand_idx, rtx insn)
 					     filename, atoi(name.string));
 }
 
+/* Consume characters until TERMINATOR.  Return all characters
+   before TERMINATOR as an allocated buffer.  */
+
+static char *
+read_until (char terminator)
+{
+  int ch = read_skip_spaces ();
+  unread_char (ch);
+  auto_vec<char> buf;
+  while (1)
+    {
+      ch = read_char ();
+      if (ch == terminator)
+	break;
+      buf.safe_push (ch);
+    }
+  buf.safe_push ('\0');
+  return xstrdup (buf.address ());
+}
+
+static void strip_trailing_whitespace (char *desc)
+{
+  char *terminator = desc + strlen (desc);
+  while (desc < terminator)
+    {
+      terminator--;
+      if (ISSPACE (*terminator))
+	*terminator = '\0';
+      else
+	break;
+    }
+}
+
 #endif /* #ifndef GENERATOR_FILE */
 
 /* Subroutine of read_rtx and read_nested_rtx.  CODE_NAME is the name of
@@ -1615,16 +1648,14 @@ read_rtx_code (const char *code_name)
 	      fprintf (stderr, "FIXME: 'r': extra string `%s'\n", name.string);
 	    }
 	  int ch = read_skip_spaces ();
+	  /* Parse extra stuff at end of 'r'.  */
 	  if (ch == '[')
 	    {
-	      // FIXME: parse extra stuff at end of 'r'
-	      do
-		{
-		  ch = read_char ();
-		  if (ch == ']')
-		    break;
-		}
-	      while (1);
+	      file_location loc = rtx_reader_ptr->get_current_location ();
+	      char *desc = read_until (']');
+	      strip_trailing_whitespace (desc);
+	      rtx_reader_ptr->add_fixup_reg_expr (loc, return_rtx, desc);
+	      free (desc);
 	    }
 	  else
 	    unread_char (ch);
diff --git a/gcc/rtl/rtl-frontend.c b/gcc/rtl/rtl-frontend.c
index 03465a0..3b3114d 100644
--- a/gcc/rtl/rtl-frontend.c
+++ b/gcc/rtl/rtl-frontend.c
@@ -44,6 +44,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "basic-block.h"
 #include "cfgrtl.h"
 #include "deferred-locations.h"
+#include "emit-rtl.h"
 
 /* Language-dependent contents of a type.  */
 
@@ -169,8 +170,8 @@ class function_reader;
 class fixup
 {
  public:
-  fixup (file_location loc, rtx insn, int operand_idx)
-    : m_loc (loc), m_insn (insn), m_operand_idx (operand_idx)
+  fixup (file_location loc, rtx insn)
+    : m_loc (loc), m_insn (insn)
   {}
   virtual ~fixup () {}
 
@@ -179,14 +180,24 @@ class fixup
  protected:
   file_location m_loc;
   rtx m_insn;
+};
+
+class operand_fixup : public fixup
+{
+ public:
+  operand_fixup (file_location loc, rtx insn, int operand_idx)
+    : fixup (loc, insn), m_operand_idx (operand_idx)
+  {}
+
+ protected:
   int m_operand_idx;
 };
 
-class fixup_insn_uid : public fixup
+class fixup_insn_uid : public operand_fixup
 {
  public:
   fixup_insn_uid (file_location loc, rtx insn, int operand_idx, int insn_uid)
-    : fixup (loc, insn, operand_idx),
+    : operand_fixup (loc, insn, operand_idx),
       m_insn_uid (insn_uid)
   {}
 
@@ -196,11 +207,11 @@ class fixup_insn_uid : public fixup
   int m_insn_uid;
 };
 
-class fixup_bb : public fixup
+class fixup_bb : public operand_fixup
 {
  public:
   fixup_bb (file_location loc, rtx insn, int operand_idx, int bb_idx)
-    : fixup (loc, insn, operand_idx),
+    : operand_fixup (loc, insn, operand_idx),
       m_bb_idx (bb_idx)
   {}
 
@@ -210,12 +221,12 @@ class fixup_bb : public fixup
   int m_bb_idx;
 };
 
-class fixup_note_insn_basic_block : public fixup
+class fixup_note_insn_basic_block : public operand_fixup
 {
  public:
   fixup_note_insn_basic_block (file_location loc, rtx insn, int operand_idx,
 			       int bb_idx)
-    : fixup (loc, insn, operand_idx),
+    : operand_fixup (loc, insn, operand_idx),
       m_bb_idx (bb_idx)
   {}
 
@@ -225,13 +236,13 @@ class fixup_note_insn_basic_block : public fixup
   int m_bb_idx;
 };
 
-class fixup_source_location : public fixup
+class fixup_source_location : public operand_fixup
 {
  public:
   fixup_source_location (file_location loc, rtx insn,
 			 int operand_idx,
 			 deferred_location *dloc)
-    : fixup (loc, insn, operand_idx),
+    : operand_fixup (loc, insn, operand_idx),
       m_dloc (dloc)
   {}
 
@@ -241,13 +252,13 @@ class fixup_source_location : public fixup
   deferred_location *m_dloc;
 };
 
-class fixup_jump_label : public fixup
+class fixup_jump_label : public operand_fixup
 {
  public:
   fixup_jump_label (file_location loc, rtx insn,
 		    int operand_idx,
 		    const char *label)
-    : fixup (loc, insn, operand_idx),
+    : operand_fixup (loc, insn, operand_idx),
       m_label (xstrdup (label))
   {}
 
@@ -257,6 +268,19 @@ class fixup_jump_label : public fixup
   const char *m_label;
 };
 
+class fixup_reg_expr : public fixup
+{
+ public:
+  fixup_reg_expr (file_location loc, rtx insn, const char *desc)
+    : fixup (loc, insn),
+      m_desc (xstrdup (desc))
+  {}
+
+  void apply (function_reader *reader) const;
+
+ private:
+  char *m_desc;
+};
 
 class function_reader : public rtx_reader
 {
@@ -285,6 +309,9 @@ class function_reader : public rtx_reader
 			     int operand_idx,
 			     const char *label);
 
+  void add_fixup_reg_expr (file_location loc, rtx insn,
+			   const char *desc);
+
   void create_function ();
   void apply_fixups ();
 
@@ -386,6 +413,27 @@ fixup_jump_label::apply (function_reader *reader) const
     }
 }
 
+static tree
+parse_mem_expr (const char *desc)
+{
+  if (0 == strcmp (desc, "<retval>"))
+    {
+      tree fndecl = cfun->decl;
+      return DECL_RESULT (fndecl);
+    }
+
+  return NULL_TREE;
+}
+
+void
+fixup_reg_expr::apply (function_reader */*reader*/) const
+{
+  //inform (m_loc, "fixup_reg_expr::apply: %qs", m_desc);
+  tree expr = parse_mem_expr (m_desc);
+  set_reg_attrs_for_decl_rtl (expr, m_insn);
+  /* FIXME: not actually an insn. */
+}
+
 function_reader::~function_reader ()
 {
   int i;
@@ -456,6 +504,13 @@ function_reader::add_fixup_jump_label (file_location loc, rtx insn,
 }
 
 void
+function_reader::add_fixup_reg_expr (file_location loc, rtx insn,
+				     const char *desc)
+{
+  m_fixups.safe_push (new fixup_reg_expr (loc, insn, desc));
+}
+
+void
 function_reader::create_function ()
 {
 #if 1
-- 
1.8.5.3

