<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
		>
<channel>
	<title>Comments on: GCC inline asm annoyance</title>
	<atom:link href="http://hardwarebug.org/2008/10/25/gcc-inline-asm-annoyance/feed/" rel="self" type="application/rss+xml" />
	<link>http://hardwarebug.org/2008/10/25/gcc-inline-asm-annoyance/</link>
	<description>Everything is broken</description>
	<lastBuildDate>Mon, 30 Aug 2010 09:33:38 +0000</lastBuildDate>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.1</generator>
	<item>
		<title>By: Mans</title>
		<link>http://hardwarebug.org/2008/10/25/gcc-inline-asm-annoyance/comment-page-1/#comment-75</link>
		<dc:creator>Mans</dc:creator>
		<pubDate>Mon, 03 Aug 2009 23:37:18 +0000</pubDate>
		<guid isPermaLink="false">http://hardwarebug.org/?p=43#comment-75</guid>
		<description>A simple test like that is likely to produce the same code for both. Try something slightly more complicated instead:
&lt;pre&gt;
int func_m(int *p)
{
    int x;
    asm volatile (&quot;lwbrx %0, %y1&quot; : &quot;=r&quot;(x) : &quot;m&quot;(*(p+1)));
    return x;
}

int func_z(int *p)
{
    int x;
    asm volatile (&quot;lwbrx %0, %y1&quot; : &quot;=r&quot;(x) : &quot;Z&quot;(*(p+1)));
    return x;
}
&lt;/pre&gt;
This gives the following assembly:
&lt;pre&gt;
00000000 : &lt;func_m&gt;
   0:   7c 63 24 2c     lwbrx   r3,r3,r4
   4:   4e 80 00 20     blr

00000008 : &lt;func_z&gt;
   8:   38 63 00 04     addi    r3,r3,4
   c:   7c 60 1c 2c     lwbrx   r3,0,r3
  10:   4e 80 00 20     blr
&lt;/pre&gt;
I&#039;m not quite sure what&#039;s going on here, but &lt;code&gt;func_m&lt;/code&gt; is obviously incorrect.</description>
		<content:encoded><![CDATA[<p>A simple test like that is likely to produce the same code for both. Try something slightly more complicated instead:</p>
<pre>
int func_m(int *p)
{
    int x;
    asm volatile ("lwbrx %0, %y1" : "=r"(x) : "m"(*(p+1)));
    return x;
}

int func_z(int *p)
{
    int x;
    asm volatile ("lwbrx %0, %y1" : "=r"(x) : "Z"(*(p+1)));
    return x;
}
</pre>
<p>This gives the following assembly:</p>
<pre>
00000000 : &lt;func_m&gt;
   0:   7c 63 24 2c     lwbrx   r3,r3,r4
   4:   4e 80 00 20     blr

00000008 : &lt;func_z&gt;
   8:   38 63 00 04     addi    r3,r3,4
   c:   7c 60 1c 2c     lwbrx   r3,0,r3
  10:   4e 80 00 20     blr
</pre>
<p>I&#8217;m not quite sure what&#8217;s going on here, but <code>func_m</code> is obviously incorrect.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Manish</title>
		<link>http://hardwarebug.org/2008/10/25/gcc-inline-asm-annoyance/comment-page-1/#comment-74</link>
		<dc:creator>Manish</dc:creator>
		<pubDate>Thu, 25 Jun 2009 06:41:21 +0000</pubDate>
		<guid isPermaLink="false">http://hardwarebug.org/?p=43#comment-74</guid>
		<description>from the gcc page
Z
    Memory operand that is an indexed or indirect from a register (`m&#039; is preferable for asm statements)

&lt;pre&gt;
asm volatile(&quot;stbrx %1,%y0&quot;: &quot;=m&quot;(*addr): &quot;r&quot;(reg): &quot;memory&quot; );
asm volatile(&quot;stbrx %1,%y0&quot;: &quot;=Z&quot;(*addr): &quot;r&quot;(reg): &quot;memory&quot; );
&lt;/pre&gt;
Both gave the same assembly
&lt;pre&gt;
   c:   81 3f 00 08     lwz     r9,8(r31)
  10:   7d 80 4d 2c     stwbrx  r12,0,r9
&lt;/pre&gt;</description>
		<content:encoded><![CDATA[<p>from the gcc page<br />
Z<br />
    Memory operand that is an indexed or indirect from a register (`m&#8217; is preferable for asm statements)</p>
<pre>
asm volatile("stbrx %1,%y0": "=m"(*addr): "r"(reg): "memory" );
asm volatile("stbrx %1,%y0": "=Z"(*addr): "r"(reg): "memory" );
</pre>
<p>Both gave the same assembly</p>
<pre>
   c:   81 3f 00 08     lwz     r9,8(r31)
  10:   7d 80 4d 2c     stwbrx  r12,0,r9
</pre>
]]></content:encoded>
	</item>
	<item>
		<title>By: Mans</title>
		<link>http://hardwarebug.org/2008/10/25/gcc-inline-asm-annoyance/comment-page-/#comment-67</link>
		<dc:creator>Mans</dc:creator>
		<pubDate>Thu, 28 May 2009 19:52:15 +0000</pubDate>
		<guid isPermaLink="false">http://hardwarebug.org/?p=43#comment-67</guid>
		<description>That will work, but it is sub-optimal in forcing the offset to be zero. It is possible that the desired address is already available as the sum of two registers, in which case this code would either use up an additional register or require recomputing one of the values afterwards.</description>
		<content:encoded><![CDATA[<p>That will work, but it is sub-optimal in forcing the offset to be zero. It is possible that the desired address is already available as the sum of two registers, in which case this code would either use up an additional register or require recomputing one of the values afterwards.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Mike</title>
		<link>http://hardwarebug.org/2008/10/25/gcc-inline-asm-annoyance/comment-page-1/#comment-66</link>
		<dc:creator>Mike</dc:creator>
		<pubDate>Thu, 28 May 2009 19:41:02 +0000</pubDate>
		<guid isPermaLink="false">http://hardwarebug.org/?p=43#comment-66</guid>
		<description>What&#039;s wrong with the traditional version?
&lt;pre&gt;
static inline uint32_t __lwbrx(const register uint32_t *p)
{
    register uint32_t v;
    asm (&quot;lwbrx %0, 0, %1&quot; : &quot;=r&quot;(v) : &quot;b&quot;(p));
    return v;
}
&lt;/pre&gt;</description>
		<content:encoded><![CDATA[<p>What&#8217;s wrong with the traditional version?</p>
<pre>
static inline uint32_t __lwbrx(const register uint32_t *p)
{
    register uint32_t v;
    asm ("lwbrx %0, 0, %1" : "=r"(v) : "b"(p));
    return v;
}
</pre>
]]></content:encoded>
	</item>
	<item>
		<title>By: Mans</title>
		<link>http://hardwarebug.org/2008/10/25/gcc-inline-asm-annoyance/comment-page-1/#comment-31</link>
		<dc:creator>Mans</dc:creator>
		<pubDate>Tue, 12 May 2009 23:55:00 +0000</pubDate>
		<guid isPermaLink="false">http://hardwarebug.org/?p=43#comment-31</guid>
		<description>A few observations:
- There is still no mention of the magic &#039;y&#039; modifier.
- GCC 4.3 is so buggy, particularly for PPC, that it would be unwise to use it widely.
- The day GCC is able to optimise anything at all reliably will be a day to celebrate.</description>
		<content:encoded><![CDATA[<p>A few observations:<br />
- There is still no mention of the magic &#8216;y&#8217; modifier.<br />
- GCC 4.3 is so buggy, particularly for PPC, that it would be unwise to use it widely.<br />
- The day GCC is able to optimise anything at all reliably will be a day to celebrate.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Andrew Pinski</title>
		<link>http://hardwarebug.org/2008/10/25/gcc-inline-asm-annoyance/comment-page-1/#comment-30</link>
		<dc:creator>Andrew Pinski</dc:creator>
		<pubDate>Tue, 12 May 2009 22:31:48 +0000</pubDate>
		<guid isPermaLink="false">http://hardwarebug.org/?p=43#comment-30</guid>
		<description>The Z constraint has been documented since GCC 4.3.0 (as I added the documentation for it and all the missing constraints for PPC).  Also it is better to use __builtin_bswap32 for 4.3.0 and above because GCC is able to optimize that better if the load does not need to happen (if the value is in a register already, it uses three instructions, if the value is in a register).

Here is the documentation for the Z constraint (from http://gcc.gnu.org/onlinedocs/gcc-4.3.0/gcc/Machine-Constraints.html):

Z
Memory operand that is an indexed or indirect from a register (`m&#039; is preferable for asm statements) 


Thanks,
Andrew Pinski</description>
		<content:encoded><![CDATA[<p>The Z constraint has been documented since GCC 4.3.0 (as I added the documentation for it and all the missing constraints for PPC).  Also it is better to use __builtin_bswap32 for 4.3.0 and above because GCC is able to optimize that better if the load does not need to happen (if the value is in a register already, it uses three instructions, if the value is in a register).</p>
<p>Here is the documentation for the Z constraint (from <a href="http://gcc.gnu.org/onlinedocs/gcc-4.3.0/gcc/Machine-Constraints.html)" rel="nofollow">http://gcc.gnu.org/onlinedocs/gcc-4.3.0/gcc/Machine-Constraints.html)</a>:</p>
<p>Z<br />
Memory operand that is an indexed or indirect from a register (`m&#8217; is preferable for asm statements) </p>
<p>Thanks,<br />
Andrew Pinski</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Johannes Rajala</title>
		<link>http://hardwarebug.org/2008/10/25/gcc-inline-asm-annoyance/comment-page-1/#comment-10</link>
		<dc:creator>Johannes Rajala</dc:creator>
		<pubDate>Wed, 21 Jan 2009 08:59:44 +0000</pubDate>
		<guid isPermaLink="false">http://hardwarebug.org/?p=43#comment-10</guid>
		<description>Nice find, thanks! I was having the same problem.</description>
		<content:encoded><![CDATA[<p>Nice find, thanks! I was having the same problem.</p>
]]></content:encoded>
	</item>
</channel>
</rss>
