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

Reply via email to