Re: Specifying different registers in inline asm

jh--- via Gcc-help <[email protected]>
Newsgroups gmane.comp.gcc.help
Message-ID <[email protected]>
Le 2025-11-19 16:19, Richard Earnshaw (foss) a écrit :
[snip]

Thank you all very much, I am slowly (the slowness comes entirely from 
my side) understanding what I should do, both on a conceptual and on a 
practical levels.

I still need a little push.

>> 
>> #define byte_from_user(addr)     ({uint8_t val; __asm__ 
>> __volatile__("LDRBT    %0, [%1]\n" : "=&r"(val) : "r" (addr), 
>> "m"(*addr)); val;})
>> 
>> void dump(const uint8_t * src, size_t count;
>>     for(size_t cntsrc=0;cntsrc<count;cntsrc++){
>>         uint8_t data = byte_from_user(&src[cntsrc]);
>>         printf("%02X ", data);
>>     }
>>     printf("\n");
>> }
>> 
>> So the only way to be theoretically correct is to copy addr to a dummy 
>> variable and say it will come out of the asm block? Like this:
>> 
>> #define byte_from_user(addr)     ({uint8_t val; uintptr_t clob_addr = 
>> addr; __asm__ __volatile__("LDRBT    %0, [%1]\n" : "=&r"(val), 
>> "+r"(clob_addr) : "m"(*clob_addr)); val;})
>> 
> 
> With the '+r' variant you don't need to mention clob_addr twice.  You
> also don't need '&' on the first value now because the compiler will
> never assign two outputs to the same register.
> 
> So I think you're best solution would be:
> 
> 
> static inline uint8_t
> byte_from_user(uint8_t *addr)
> {
>   uint8_t val;
>   void *unused;
>   __asm__ __volatile__ ("LDRBT    %0, [%1]\n"
> 			: "=r"(val), "=r" (unused)
> 			: "1" (addr)
> 			: "memory");
>   return val;
> }
> 
> void dump(const uint8_t * src, size_t count;
>     for(size_t cntsrc=0;cntsrc<count;cntsrc++){
>         uint8_t data = byte_from_user(&src[cntsrc]);
>         printf("%02X ", data);
>     }
>     printf("\n");
> }
> 
> You probably won't need the clobber of 'memory' in addition to the
> 'volatile' qualifier, but you certainly need at least one.
> 
About memory access, I think I made a mistake, *addr is not clobbered, 
but will be read, should that be mentioned in the input list?
In the converse function byte_to_user, *addr would be written, should it 
then be marked as clobber?
Is there a sense in saying that my code only reads/writes *addr and not 
any other memory (i.e. does it make a difference for clobber to write 
"m"(*addr) rather then "memory")?

Cheers,
JH
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.