public inbox for gcc@gcc.gnu.org
 help / color / mirror / Atom feed
From: Geoffrey KEATING <geoffk@discus.anu.edu.au>
To: Richard Henderson <rth@cygnus.com>
Cc: David Edelsohn <dje@watson.ibm.com>,
	Richard Henderson<rth@cygnus.com>,
	Geoffrey KEATING <geoffk@discus.anu.edu.au>,
	egcs@cygnus.com
Subject: Re: asm clobbers, !SMALL_REGISTER_CLASSES patch.
Date: Sat, 14 Feb 1998 20:23:00 -0000	[thread overview]
Message-ID: <199802150423.PAA00420@discus.anu.edu.au> (raw)
In-Reply-To: <19980213102956.17734@dot.cygnus.com>

[-- Attachment #1: Type: text/plain, Size: 1532 bytes --]

> Date: Fri, 13 Feb 1998 10:29:56 -0800
> From: Richard Henderson <rth@dot.cygnus.com>

> PowerPC, Sparc64, and others have multiple CC registers.  It
> comes to pass that while writing some inline assembly, you need
> one.  At present you can only just pick one at random and 
> clobber it.
> 
> What if we provide a way to allocate scratches explicitly?  My
> thought here is to put something special in the () part of the
> output section (whether we turn it into a clobber is immaterial;
> we need a parameter number for the asm string).  I considered
> using something like __scratch__, but it'd be nice to avoid a
> new keyword.  Using auto instead appeals to me.
> 
> So you could then do
> 
> 	asm ("cmpwi %0,%1,123\n\t"
> 	     "beq %0,1f\n\t"
> 	     "blah\n"
> 	     "1:"
> 	  : "=y"(auto) : "r"(foo));

Funny you should mention that.  I have such a patch attached; I did it
as a warmup to see how I should do the rewriting patch.  It uses the syntax

	: "=y" : "r"(foo));

That is, you just omit the expression.

My problem is that I can't find a compelling use for it.  Usually, you
only have one register that is best; on PPC, typically this is cr0
(for loops and suchlike) or cr7 (because it occupies the least
significant bits when you put the ccr in an integer register).

Thus I'm not terribly interested in it, unless someone else can find
an actual use for it.  I would rather spend the effort on important
things, like making sure that the released GNU C library doesn't crash
the released GNU C compiler :-).


[-- Attachment #2: egcs-asm-1.diff --]
[-- Type: text/x-diff, Size: 7012 bytes --]

--- gcc/c-parse.in.orig	Sat Feb  7 14:11:46 1998
+++ gcc/c-parse.in	Sat Feb  7 14:04:25 1998
@@ -2204,6 +2204,8 @@ nonnull_asm_operands:
 asm_operand:
 	  STRING '(' expr ')'
 		{ $$ = build_tree_list ($1, $3); }
+	| STRING
+		{ $$ = build_tree_list ($1, NULL_TREE); }
 	;
 
 asm_clobbers:
--- gcc/c-typeck.c.orig	Sat Sep 27 13:46:33 1997
+++ gcc/c-typeck.c	Fri Feb  6 23:50:00 1998
@@ -6519,7 +6519,7 @@ c_expand_asm_operands (string, outputs, 
 	}
       /* Detect modification of read-only values.
 	 (Otherwise done by build_modify_expr.)  */
-      else
+      else if (o[i] != NULL_TREE)
 	{
 	  tree type = TREE_TYPE (o[i]);
 	  if (TREE_READONLY (o[i])
--- gcc/stmt.c.orig	Fri Feb  6 21:25:08 1998
+++ gcc/stmt.c	Sat Feb  7 14:03:09 1998
@@ -47,6 +47,7 @@ Boston, MA 02111-1307, USA.  */
 #include "insn-config.h"
 #include "insn-codes.h"
 #include "expr.h"
+#include "regs.h"
 #include "hard-reg-set.h"
 #include "obstack.h"
 #include "loop.h"
@@ -1383,6 +1384,38 @@ expand_asm (body)
   last_expr_type = 0;
 }
 
+/* Choose a mode that might be suitable for a constraint.
+   If the constraint is too tricky, this can get it wrong.  */
+static enum machine_mode
+choose_constraint_mode(constraint)
+     char *constraint;
+{
+  for (;;)
+    switch (*constraint++)
+      {
+      case '0': case ',':
+	/* Wild guess.  This is why you shouldn't use this facility
+	   to (for instance) provide a memory location.  */
+	return byte_mode;
+      case 'r': case 'g':
+	/* Assume that general registers can at least hold a byte.  */
+	return byte_mode;
+      default:
+	{
+	  enum reg_class class = REG_CLASS_FROM_LETTER (constraint[-1]);
+	  int regno;
+
+	  if (class == NO_REGS)
+	    continue;
+
+	  for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
+	    if (TEST_HARD_REG_BIT (reg_class_contents[(int) class], regno))
+	      return reg_raw_mode[regno];
+	  continue;
+	}
+      }
+}
+
 /* Generate RTL for an asm statement with arguments.
    STRING is the instruction template.
    OUTPUTS is a list of output arguments (lvalues); INPUTS a list of inputs.
@@ -1455,15 +1488,18 @@ expand_asm_operands (string, outputs, in
   for (i = 0, tail = outputs; tail; tail = TREE_CHAIN (tail), i++)
     {
       tree val = TREE_VALUE (tail);
-      tree type = TREE_TYPE (val);
+      tree type;
       tree val1;
       int j;
       int found_equal = 0;
       int found_plus = 0;
       int allows_reg = 0;
 
+      if (val != NULL_TREE)
+	type = TREE_TYPE (val);
+
       /* If there's an erroneous arg, emit no insn.  */
-      if (TREE_TYPE (val) == error_mark_node)
+      if (val != NULL_TREE && type == error_mark_node)
 	return;
 
       /* Make sure constraint has `=' and does not have `+'.  Also, see
@@ -1519,17 +1555,29 @@ expand_asm_operands (string, outputs, in
 	  return;
 	}
 
+      if (found_plus && val == NULL_TREE)
+	{
+	  error ("inout operand to `asm' should have value");
+	  return;
+	}
       /* If an output operand is not a decl or indirect ref and our constraint
 	 allows a register, make a temporary to act as an intermediate.
 	 Make the asm insn write into that, then our caller will copy it to
-	 the real output operand.  Likewise for promoted variables.  */
+	 the real output operand.  Likewise for promoted variables,
+	 and for when we ignore the output (but then we don't want to have
+	 the caller copy it anywhere).  */
 
-      if (TREE_CODE (val) == INDIRECT_REF
-	  || (TREE_CODE_CLASS (TREE_CODE (val)) == 'd'
-	      && ! (GET_CODE (DECL_RTL (val)) == REG
-		    && GET_MODE (DECL_RTL (val)) != TYPE_MODE (type)))
-	  || ! allows_reg
-	  || found_plus)
+      if (val == NULL_TREE)
+	{
+	  char *constraint = TREE_STRING_POINTER (TREE_PURPOSE (tail));
+	  output_rtx[i] = gen_reg_rtx (choose_constraint_mode(constraint));
+	}
+      else if (TREE_CODE (val) == INDIRECT_REF
+	       || (TREE_CODE_CLASS (TREE_CODE (val)) == 'd'
+		   && ! (GET_CODE (DECL_RTL (val)) == REG
+			 && GET_MODE (DECL_RTL (val)) != TYPE_MODE (type)))
+	       || ! allows_reg
+	       || found_plus)
 	{
 	  if (! allows_reg)
 	    mark_addressable (TREE_VALUE (tail));
@@ -1579,6 +1627,13 @@ expand_asm_operands (string, outputs, in
     {
       int j;
       int allows_reg = 0;
+
+      /* Null inputs make little sense.  */
+      if (TREE_VALUE (tail) == NULL_TREE)
+	{
+	  error ("input operand to `asm' should have value");
+	  return;
+	}
 
       /* If there's an erroneous arg, emit no insn,
 	 because the ASM_INPUT would get VOIDmode
--- gcc/cp/parse.y.orig	Sat Feb  7 14:12:50 1998
+++ gcc/cp/parse.y	Sat Feb  7 14:12:33 1998
@@ -4065,6 +4065,8 @@ nonnull_asm_operands:
 asm_operand:
 	  STRING '(' expr ')'
 		{ $$ = build_tree_list ($$, $3); }
+	| STRING
+		{ $$ = build_tree_list ($1, NULL_TREE); }
 	;
 
 asm_clobbers:
--- gcc/ChangeLog~	Sun Jan 25 00:35:52 1998
+++ gcc/ChangeLog	Sat Feb  7 14:21:05 1998
@@ -1,3 +1,12 @@
+Fri Feb  6 22:15:24 1998  Geoff Keating  (geoffk@ozemail.com.au)
+
+	* c-parse.in (asm_operand): Add new `ignore output' syntax.
+	* c-typeck.c (c_expand_asm_operands): If we are ignoring the
+	output, don't copy it anywhere.
+	* stmt.c (choose_constraint_mode): New function.
+	(expand_asm_operands): Handle `ignore output' syntax by creating a
+	dummy pseudo to output to.
+
 Fri Jan  2 23:40:09 1998  Jim Wilson  (wilson@cygnus.com)
 			  Jeffrey A Law  (law@cygnus.com)
 
--- gcc/cp/ChangeLog~	Sun Jan 25 00:36:04 1998
+++ gcc/cp/ChangeLog	Sat Feb  7 14:21:35 1998
@@ -1,3 +1,7 @@
+Fri Feb  6 22:21:27 1998  Geoff Keating  <geoffk@ozemail.com.au>
+
+	* parse.y (asm_operand): Add new `ignore output' syntax.
+
 Sat Dec 20 13:00:30 1997  Jason Merrill  <jason@yorick.cygnus.com>
 
 	* pt.c (instantiate_decl): Defer all templates but inline functions.
--- gcc/extend.texi.orig	Sat Feb  7 14:50:39 1998
+++ gcc/extend.texi	Sat Feb  7 15:33:02 1998
@@ -2430,6 +2430,28 @@
 and therefore they cannot take account of them when deciding how to
 optimize.
 
+In some of these more complex @code{asm} statements, you need temporary
+registers.  You could just choose a register at random (and specify it
+as clobbered), but it is usually better to instead make the temporary an
+`output' of the @code{asm}; that way the register allocator can pick the
+most convenient temporary.  There is a special syntax to simplify using
+such temporaries: if you omit the C expression specifying the output
+destination, the output will be ignored.  For instance, the following
+example implements test-and-set on RS6000, using a temporary
+condition code register:
+
+@example
+asm volatile("0:  lwarx %0,0,%3;"
+             "    cmpwi %1,%0,0;"
+             "    bne %1,1f;"
+             "    stwcx. %4,0,%3;"
+             "    bne- 0b;"
+             "1: "
+     : "=&r"(oldvalue), "=y", "=x"
+     : "r"(address), "r"(1)
+     : "memory");
+@end example
+
 @cindex macros containing @code{asm}
 Usually the most convenient way to use these @code{asm} instructions is to
 encapsulate them in macros that look like functions.  For example,

      parent reply	other threads:[~1998-02-14 20:23 UTC|newest]

Thread overview: 14+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
1998-02-12 19:36 Geoffrey KEATING
1998-02-12 20:24 ` David Edelsohn
1998-02-12 20:24   ` Geoffrey KEATING
1998-02-13  2:28   ` Jeffrey A Law
1998-02-13  2:28     ` Geoffrey KEATING
1998-02-14  0:32       ` Jeffrey A Law
1998-02-14 21:14         ` Geoffrey KEATING
1998-02-15 11:33           ` Jeffrey A Law
1998-02-15 18:47             ` David Edelsohn
1998-02-13  2:28   ` Richard Henderson
1998-02-13 10:34     ` David Edelsohn
1998-02-13 10:58       ` Richard Henderson
1998-02-13 10:58         ` David Edelsohn
1998-02-14 20:23         ` Geoffrey KEATING [this message]

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=199802150423.PAA00420@discus.anu.edu.au \
    --to=geoffk@discus.anu.edu.au \
    --cc=dje@watson.ibm.com \
    --cc=egcs@cygnus.com \
    --cc=rth@cygnus.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).