diff mbox

[DOC] Add sample for @cc constraint

Message ID 56FF06A7.8040900@LimeGreenSocks.com
State New
Headers show

Commit Message

David Wohlferd April 1, 2016, 11:39 p.m. UTC
> I would like executable code that verifies that this feature is 
indeed working as intended.

First draft is attached.  It tests all 28 (14 conditions plus 14 
inverted).  I wasn't sure what to set for optimization (O2? O3? O0?), so 
I left the default.

It looks like even at O3 there are some missed optimizations here, but 
that's an issue for another day.

 > Is there any _actual_ problem here? Like, if you combine the output 
and the clobber you run into problems? Looks to me like an explicit "cc" 
clobber is just ignored on x86. We just need to make sure this stays 
working (testcases).

Today?  No.  You can clobber or not clobber and both will produce the 
exact same output.

But letting people program this two different ways guarantees that 
people *will* program it both ways.  And just because there isn't any 
definable reason to limit this today doesn't mean that there won't ever 
be.  But by then it will be 'too late' to change it because it "breaks 
existing code."

 >> 1) Leave this text in.
 >> 2) Remove the text and add the compiler check to v6.
 >> 3) Remove the text and add the compiler check to v7.
 >> 4) Leave the text in v6, then in v7: remove the text and add the 
compiler check.
 >> 5) (Reluctantly) remove the text and hope this never becomes a problem.

So, I've made my pitch, but it sounds like you want #5?

 > My question would be, can this information ever be relevant to users? 
They may notice that their code still works if they omit the "cc", but 
that's not really a habit we want to encourage.

People do this now without understanding how or why it works.

 > I think this is an internal implementation detail that doesn't 
necessarily even have to be documented.

One time it would matter is if people want to move from basic asm (which 
doesn't clobber "cc") to any type of extended asm (which always does).  
It /probably/ won't matter in that case (and may even make things 
better).  But it shouldn't be a secret.

dw

Comments

David Wohlferd April 11, 2016, 10:49 p.m. UTC | #1
Ping?

dw

On 4/1/2016 4:39 PM, David Wohlferd wrote:
> > I would like executable code that verifies that this feature is 
> indeed working as intended.
>
> First draft is attached.  It tests all 28 (14 conditions plus 14 
> inverted).  I wasn't sure what to set for optimization (O2? O3? O0?), 
> so I left the default.
>
> It looks like even at O3 there are some missed optimizations here, but 
> that's an issue for another day.
>
> > Is there any _actual_ problem here? Like, if you combine the output 
> and the clobber you run into problems? Looks to me like an explicit 
> "cc" clobber is just ignored on x86. We just need to make sure this 
> stays working (testcases).
>
> Today?  No.  You can clobber or not clobber and both will produce the 
> exact same output.
>
> But letting people program this two different ways guarantees that 
> people *will* program it both ways.  And just because there isn't any 
> definable reason to limit this today doesn't mean that there won't 
> ever be.  But by then it will be 'too late' to change it because it 
> "breaks existing code."
>
> >> 1) Leave this text in.
> >> 2) Remove the text and add the compiler check to v6.
> >> 3) Remove the text and add the compiler check to v7.
> >> 4) Leave the text in v6, then in v7: remove the text and add the 
> compiler check.
> >> 5) (Reluctantly) remove the text and hope this never becomes a 
> problem.
>
> So, I've made my pitch, but it sounds like you want #5?
>
> > My question would be, can this information ever be relevant to 
> users? They may notice that their code still works if they omit the 
> "cc", but that's not really a habit we want to encourage.
>
> People do this now without understanding how or why it works.
>
> > I think this is an internal implementation detail that doesn't 
> necessarily even have to be documented.
>
> One time it would matter is if people want to move from basic asm 
> (which doesn't clobber "cc") to any type of extended asm (which always 
> does).  It /probably/ won't matter in that case (and may even make 
> things better).  But it shouldn't be a secret.
>
> dw
Bernd Schmidt April 12, 2016, 1:06 p.m. UTC | #2
On 04/12/2016 12:49 AM, David Wohlferd wrote:
>> First draft is attached.  It tests all 28 (14 conditions plus 14
>> inverted).  I wasn't sure what to set for optimization (O2? O3? O0?),
>> so I left the default.

I've had it in a successful test run, and committed it with a minor 
tweak (__builtin_abort vs return 1).

As for the docs, I think you are unnecessarily worried about things that 
are never going to be a problem in practice.


Bernd
David Wohlferd April 15, 2016, 11:12 p.m. UTC | #3
> I've had it in a successful test run, and committed it with a minor 
> tweak (__builtin_abort vs return 1).

It didn't find anything, but it's probably good to have.

> As for the docs, I think you are unnecessarily worried about things 
> that are never going to be a problem in practice.

Perhaps so.  On the other hand, the reason x86 always clobbers cc now is 
that there was a concern during a change that people may have been using 
it incorrectly.  Giving people yet another way to muck this up seemed 
like a bad plan.

Anyway.

There were  basically 3 changes I was trying for in that doc patch. Are 
any of them worth keeping?  Or are we done?

1) "Do not clobber flags if they are being used as outputs."
2) Output flags sample (with #if removed).
3) "On the x86 platform, flags are always treated as clobbered by 
extended asm whether @code{"cc"} is specified or not."

I'm prepared to send an updated patch if there's anything here that 
might get approved.

dw
Bernd Schmidt April 25, 2016, 9:51 a.m. UTC | #4
On 04/16/2016 01:12 AM, David Wohlferd wrote:
> There were  basically 3 changes I was trying for in that doc patch. Are
> any of them worth keeping?  Or are we done?
>
> 1) "Do not clobber flags if they are being used as outputs."
> 2) Output flags sample (with #if removed).
> 3) "On the x86 platform, flags are always treated as clobbered by
> extended asm whether @code{"cc"} is specified or not."
>
> I'm prepared to send an updated patch if there's anything here that
> might get approved.

I think the updated flags sample would be nice to have.


Bernd
diff mbox

Patch

Index: gcc/testsuite/gcc.target/i386/asm-flag-6.c
===================================================================
--- gcc/testsuite/gcc.target/i386/asm-flag-6.c	(revision 0)
+++ gcc/testsuite/gcc.target/i386/asm-flag-6.c	(working copy)
@@ -0,0 +1,276 @@ 
+/* Executable testcase for 'output flags.'  */
+/* { dg-do run } */
+
+char TestC ()
+{
+  char r;
+
+  __asm__ ("stc" : "=@ccc"(r));
+  if (r)
+  {
+    __asm__ ("clc" : "=@ccnc"(r));
+    if (r)
+      return 1;
+  }
+  return 0;
+}
+
+char TestE ()
+{
+  char r;
+
+  /* 1 equals 1.  */
+  __asm__ ("cmp $1, %1" : "=@cce"(r) : "r" (1));
+  if (r)
+  {
+    /* 1 not equals 2.  */
+    __asm__ ("cmp $2, %1" : "=@ccne"(r) : "r" (1));
+    if (r)
+      return 1;
+  }
+  return 0;
+}
+
+char TestZ ()
+{
+  char r;
+
+  /* 1 equals 1.  */
+  __asm__ ("cmp $1, %1" : "=@ccz"(r) : "r" (1));
+  if (r)
+  {
+    /* 1 not equals 2.  */
+    __asm__ ("cmp $2, %1" : "=@ccnz"(r) : "r" (1));
+    if (r)
+      return 1;
+  }
+  return 0;
+}
+
+char TestA ()
+{
+  char r;
+
+  /* 1 a 0.  */
+  __asm__ ("cmp $0, %1" : "=@cca"(r) : "r" (1));
+  if (r)
+  {
+    /* 1 na 2.  */
+    __asm__ ("cmp $2, %1" : "=@ccna"(r) : "r" (1));
+    if (r)
+    {
+      /* 1 na 1.  */
+      __asm__ ("cmp $1, %1" : "=@ccna"(r) : "r" (1));
+      if (r)
+	return 1;
+    }
+  }
+  return 0;
+}
+
+char TestAE ()
+{
+  char r;
+
+  /* 1 ae 0.  */
+  __asm__ ("cmp $0, %1" : "=@ccae"(r) : "r" (1));
+  if (r)
+  {
+    /* 1 nae 2.  */
+    __asm__ ("cmp $2, %1" : "=@ccnae"(r) : "r" (1));
+    if (r)
+    {
+      /* 1 ae 1.  */
+      __asm__ ("cmp $1, %1" : "=@ccae"(r) : "r" (1));
+      if (r)
+	return 1;
+    }
+  }
+  return 0;
+}
+
+char TestB ()
+{
+  char r;
+
+  /* 1 b 2.  */
+  __asm__ ("cmp $2, %1" : "=@ccb"(r) : "r" (1));
+  if (r)
+  {
+    /* 1 nb 0.  */
+    __asm__ ("cmp $0, %1" : "=@ccnb"(r) : "r" (1));
+    if (r)
+    {
+      /* 1 nb 1.  */
+      __asm__ ("cmp $1, %1" : "=@ccnb"(r) : "r" (1));
+      if (r)
+	return 1;
+    }
+  }
+  return 0;
+}
+
+char TestBE ()
+{
+  char r;
+
+  /* 1 be 2.  */
+  __asm__ ("cmp $2, %1" : "=@ccbe"(r) : "r" (1));
+  if (r)
+  {
+    /* 1 nbe 0.  */
+    __asm__ ("cmp $0, %1" : "=@ccnbe"(r) : "r" (1));
+    if (r)
+    {
+      /* 1 be 1.  */
+      __asm__ ("cmp $1, %1" : "=@ccbe"(r) : "r" (1));
+      if (r)
+	return 1;
+    }
+  }
+  return 0;
+}
+
+char TestG ()
+{
+  char r;
+
+  /* 1 g 0.  */
+  __asm__ ("cmp $0, %1" : "=@ccg"(r) : "r" (1));
+  if (r)
+  {
+    /* 1 ng 2.  */
+    __asm__ ("cmp $2, %1" : "=@ccng"(r) : "r" (1));
+    if (r)
+    {
+      /* 1 ng 1.  */
+      __asm__ ("cmp $1, %1" : "=@ccng"(r) : "r" (1));
+      if (r)
+	return 1;
+    }
+  }
+  return 0;
+}
+
+char TestGE ()
+{
+  char r;
+
+  /* 1 ge 0.  */
+  __asm__ ("cmp $0, %1" : "=@ccge"(r) : "r" (1));
+  if (r)
+  {
+    /* 1 nge 2.  */
+    __asm__ ("cmp $2, %1" : "=@ccnge"(r) : "r" (1));
+    if (r)
+    {
+      /* 1 ge 1.  */
+      __asm__ ("cmp $1, %1" : "=@ccge"(r) : "r" (1));
+      if (r)
+	return 1;
+    }
+  }
+  return 0;
+}
+
+char TestL ()
+{
+  char r;
+
+  /* 1 l 2.  */
+  __asm__ ("cmp $2, %1" : "=@ccl"(r) : "r" (1));
+  if (r)
+  {
+    /* 1 nl 0.  */
+    __asm__ ("cmp $0, %1" : "=@ccnl"(r) : "r" (1));
+    if (r)
+    {
+      /* 1 nl 1.  */
+      __asm__ ("cmp $1, %1" : "=@ccnl"(r) : "r" (1));
+      if (r)
+	return 1;
+    }
+  }
+  return 0;
+}
+
+char TestLE ()
+{
+  char r;
+
+  /* 1 le 2.  */
+  __asm__ ("cmp $2, %1" : "=@ccle"(r) : "r" (1));
+  if (r)
+  {
+    /* 1 nle 0.  */
+    __asm__ ("cmp $0, %1" : "=@ccnle"(r) : "r" (1));
+    if (r)
+    {
+      /* 1 le 1.  */
+      __asm__ ("cmp $1, %1" : "=@ccle"(r) : "r" (1));
+      if (r)
+	return 1;
+    }
+  }
+  return 0;
+}
+
+char TestO ()
+{
+  char r;
+  unsigned char res = 128;
+
+  /* overflow.  */
+  __asm__ ("addb $128, %1" : "=@cco"(r), "+r"(res));
+  if (r)
+  {
+    /* not overflow.  */
+    __asm__ ("addb $1, %1" : "=@ccno"(r), "+r"(res));
+    if (r)
+      return 1;
+  }
+  return 0;
+}
+
+char TestP ()
+{
+  char r, res = 1;
+
+  /* even # bits.  */
+  __asm__ ("addb $2, %1" : "=@ccp"(r), "+r"(res));
+  if (r)
+  {
+    /* odd # bits.  */
+    __asm__ ("addb $1, %1" : "=@ccnp"(r), "+r"(res));
+    if (r)
+      return 1;
+  }
+  return 0;
+}
+
+char TestS ()
+{
+  char r, res = 1;
+
+  /* sign bit set.  */
+  __asm__ ("addb $128, %1" : "=@ccs"(r), "+r"(res));
+  if (r)
+  {
+    /* sign bit not set.  */
+    __asm__ ("subb $128, %1" : "=@ccns"(r), "+r"(res));
+    if (r)
+      return 1;
+  }
+  return 0;
+}
+
+/* dg-do treats exit code of 0 as success.  */
+int main ()
+{
+  if (TestC ()  && TestE () && TestZ ()  && TestA ()
+      && TestAE () && TestB () && TestBE () && TestG ()
+      && TestGE () && TestL () && TestLE () && TestO ()
+      && TestP ()  && TestS ())
+    return 0;
+  return 1;
+}