On Wed, Feb 26, 2014 at 11:32 AM, Andrew Haley <[email protected]> wrote:
> Say you have a pointer:
>
> int *p;
>
> and an inline asm that writes to a block of memory
>
> __asm__("\t0:\n"
> "\tstr wzr, [%2, #4]!\n"
> "\tsub %1, %1, #1\n"
> "\tcbnz %1, 0b\n"
> : "=m"(*p), "+r"(len) : "r"(p));
>
> I presume this is wrong because *p only refers to p[0]. Is it
> possible to tell GCC that the asm writes to the whole block of memory
> reachable from p without a total memory clobber?
>
> I have attached some code that works but it is so fugly that I'm
> reluctant to recommend it.
Well, you are surely lucky at the moment because nothing in GCC
disambiguates asms with memory operands against anything.
But yes, technically you write p[0] here but as "m" merely builds
an address to the memory I'd say that we have to treat any "m"
operand as possibly reading from / writing to / clobbering the
whole object that can be refered to using that address.
Anything else would need extra syntax to specify a memory
range that is accessed.
And yes, I probably should implement at least basic disambiguation
against memory accessing asm()s ;)
Summary: I consider your asm ok without changes. Does documentation
tell you otherwise? Did you run into optimization issues?
Thanks,
Richard.
> Andrew.
>
>
> typedef struct {
> int theData[0];
> } thing;
>
> int main() {
>
> int arr[20];
> thing *p = (thing*)arr;
>
> int len = 20;
> __asm__("\t0:\n"
> "\tstr %1, [%2, #4]!\n"
> "\tsub %1, %1, #1\n"
> "\tcbnz %1, 0b\n"
> : "=m"(*p), "+r"(len) : "r"(p));
>
> return p->theData[5];
> }