On 30/05/25 1:37 am, Peter Bergner wrote:
> On 5/29/25 5:35 AM, Segher Boessenkool wrote:
>>
>>> +#define _AMO_LD_INCREMENT(NAME, TYPE, OPCODE, FC) \
>>> +static __inline__ TYPE
>>> \
>>> +NAME (TYPE *_PTR) \
>>> +{ \
>>> + TYPE _RET;
>>> \
>>> + __asm__ volatile (OPCODE " %[ret],%P[addr],%[code]\n"
>>> \
>>> + : [addr] "+Q" (_PTR[0]), [ret] "=r" (_RET) \
>>> + : "Q" (*(TYPE (*)[2]) _PTR), [code] "n" (FC)); \
>>> + return _RET;
>>> \
>>> +}
>>
>> I don't understand the [2]. Should it be [1]? These instructions
>> can use the value at mem+s (as the ISA names things) as input, but not
>> mem+2*s.
>
> I think 2 is correct here. This 2 isn't an index like the 0 in _PTR[0],
> but it's a size. This specific use is trying to say we're reading from
> memory and we're reading 2 locations, mem(EA,s) and mem(EA+s,s).
> Maybe we could use separate mentions of _PTR[0] and _PTR[1] instead???
> We don't actually use that "operand" in the instruction, it's just there
> to tell the compiler that those memory locations are read.
IIUC, (*(TYPE (*)[2]) _PTR) says that _PTR points to an array of 2 integers.
Can the constraint 'Q' be used to denote two memory locations?
In any case, for _AMO_LD_DECREMENT, we should specify the two locations
separately (as _PTR[0] and _PTR[-1]). Otherwise, how would the compiler know
which 2 memory locations the expression "(*(TYPE (*)[2]) _PTR)" is referring to?
Regards,
Surya