On 07.03.2024 14:44, Oleksii wrote: > On Thu, 2024-03-07 at 14:24 +0100, Jan Beulich wrote: >> On 07.03.2024 14:01, Oleksii wrote: >>> On Wed, 2024-03-06 at 15:13 +0100, Jan Beulich wrote: >>>>> +/* Generic IO read/write. These perform native-endian >>>>> accesses. >>>>> */ >>>>> +static inline void __raw_writeb(uint8_t val, volatile void >>>>> __iomem >>>>> *addr) >>>>> +{ >>>>> + asm volatile ( "sb %0, 0(%1)" : : "r" (val), "r" (addr) ); >>>>> +} >>>> >>>> I realize this is like Linux has it, but how is the compiler to >>>> know >>>> that >>>> *addr is being access here? >>> Assembler syntax told compiler that. 0(%1) - means that the memory >>> location pointed to by the address in register %1. >> >> No, the compiler doesn't decompose the string to figure how operands >> are used. That's what the constraints are for. The only two things >> the >> compiler does with the string is replace % operators and count line >> separators. > It looks like I am missing something. > > addr -> a some register ( because of "r" contraint ). > val -> is also register ( because of "r" contraint ). > > So the compiler will update instert an instruction: > sb reg1, 0(reg2) > > what means *(uint_8 *)reg2 = (uint8_t)reg1. > > What am I missing?
The fact that the compiler will not know that *(uint_8 *)reg2 actually changes across this asm(). It may therefore continue to hold a cached value in a register, without knowing that its contents went stale. Jan