On 02/06/25 12:30 pm, Surya Kumari Jangala wrote:
>
> 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?
Spoken too soon. Please ignore.
Just realized that _AMO_LD_DECREMENT takes _PTR as input and this points to an
array where the 0th element is actually MEM(EA – s, s) while the 1st element is
MEM(EA, s). So in the input operands, we do not need to specify _PTR[-1].
Regards,
Surya