Patchwork Handle attributes defined in terms of another

login
register
mail settings
Submitter Bernd Schmidt
Date Aug. 30, 2010, 4:32 p.m.
Message ID <4C7BDD2E.9030207@codesourcery.com>
Download mbox | patch
Permalink /patch/63072/
State New
Headers show

Comments

Bernd Schmidt - Aug. 30, 2010, 4:32 p.m.
In a new port, I have

(define_attr "units62" "unknown,d,d_addr,l,m,s,dl,dls,ls"
  (const_string "unknown"))

(define_attr "units64" "unknown,d,d_addr,l,m,s,dl,dls,ls"
  (const_string "unknown"))

(define_attr "units" "unknown,d,d_addr,l,m,s,dl,dls,ls"
  (cond [(eq_attr "cpu" "c62x") (attr "units62")
	 (eq_attr "cpu" "c64x") (attr "units64")]
	(const_string "unknown")))

which is intended to allow each insn either to define a single "units"
attribute, or more specific "units62" and "units64" if there are
differences between CPUs.

Tests of the form (eq_attr "units" "something") fail in genattrtab.c,
since evaluate_eq_attr can e.g. end up with (attr "units62") in the
value, and it doesn't handle this.

I don't know this code very well.  I've copied a block of code from
elsewhere to look up attributes in this case.  That seems to work on the
port I'm working on, and it also bootstraps ok on i686-linux.  Ok?


Bernd
* genattrtab.c (evaluate_eq_attr): Handle the case where one attribute
	is defined in terms of another.

Patch

Index: genattrtab.c
===================================================================
--- genattrtab.c	(revision 296735)
+++ genattrtab.c	(working copy)
@@ -1932,6 +1932,36 @@  evaluate_eq_attr (rtx exp, rtx value, in
   rtx newexp;
   int i;
 
+  while (GET_CODE (value) == ATTR)
+    {
+      struct attr_desc *attr;
+      struct attr_value *av = NULL;
+
+      attr = find_attr (&XSTR (value, 0), 0);
+      if (insn_code_values)
+	{
+	  struct attr_value_list *iv;
+	  for (iv = insn_code_values[insn_code]; iv; iv = iv->next)
+	    if (iv->attr == attr)
+	      {
+		av = iv->av;
+		break;
+	      }
+	}
+      else
+	{
+	  struct insn_ent *ie;
+	  for (av = attr->first_value; av; av = av->next)
+	    for (ie = av->first_insn; ie; ie = ie->next)
+	      if (ie->def->insn_code == insn_code)
+		goto got_av;
+	}
+      if (av)
+	{
+	got_av:
+	  value = av->value;
+	}
+    }
   switch (GET_CODE (value))
     {
     case CONST_STRING: