[PATCH v6 01/13] ARC: ABI Implementation

Vineet Gupta Vineet.Gupta1@synopsys.com
Thu Jun 4 19:01:10 GMT 2020

On 6/4/20 2:04 AM, Florian Weimer via Libc-alpha wrote:
> * Vineet Gupta via Libc-alpha:
>> On 5/27/20 11:26 AM, Adhemerval Zanella via Libc-alpha wrote:
>>> +ENTRY (__longjmp)
>>> +
>>> +	ld_s r13,   [r0]
>>> +	ld_s r14,   [r0,4]
>>> +	ld   r15,   [r0,8]
>>> +	ld   r16,   [r0,12]
>>> +	ld   r17,   [r0,16]
>>> +	ld   r18,   [r0,20]
>>> +	ld   r19,   [r0,24]
>>> +	ld   r20,   [r0,28]
>>> +	ld   r21,   [r0,32]
>>> +	ld   r22,   [r0,36]
>>> +	ld   r23,   [r0,40]
>>> +	ld   r24,   [r0,44]
>>> +	ld   r25,   [r0,48]
>>> +
>>> +	ld   blink, [r0,60]
>>> +	ld   fp,    [r0,52]
>>> +	ld   sp,    [r0,56]
>>> +
>>> +	mov.f  r0, r1	; get the setjmp return value(due to longjmp) in place
>>> +
>>> +	j.d    [blink]	; to caller of setjmp location, right after the call
>>> +	mov.z  r0, 1	; can't let setjmp return 0 when it is due to longjmp
>>> +
>>> +END (__longjmp)
>> So wanted to pick your brains on this thing. While longjmp is not necessarily an
>> application hotspot, it seems bulk load/store can in general benefit from with
>> ARCv2 double load/store instructions LDD/STD which work with register pairs.
>> So we could have 2 variants which compile differently to one runtime
>> implementation or better still have 2 runtime implementations which could be
>> switched to using hwcaps (which I can add to kernel). Does that require IFUNC
>> which ARC toolchain doesn't support ATM.
> Without IFUNCs, you would have to use a conditional branch in the
> (single) __longjmp implementation.
> With IFUNCs, all internal callers will have to go through a function
> pointer—or those internal callers would have to turn into IFUNCs as
> well.
> So it's doubtful whether this is beneficial in this case.
> Also, please double-check the register list.  The ABI manual says this:
> | The scratch registers are not preserved across function calls. When
> | calling an external function, the compiler assumes that registers %r0
> | through %r12 and %r30 are trashed; and that %r13 through %r29 are
> | preserved.  The EV6x processor reserves %r25.
> r27 and r28 are handled as fp and sp.  That leaves r26 and r29 as
> unhandled.

r29 is ILINK1 (Interrupt Link Register) and accessible only in kernel mode so can
be ignored here.

r26 is GP and indeed could be potential problem and thus needs saving. The reason
it is missing in first place is the historic use of GP as "PIC assist" register
which has since been reworked in compiler). As of today the register allocator is
simply ignoring GP.

> r25 seems to be the thread pointer.  It cannot change its value between
> setjmp and longjmp because you cannot longjmp onto another thread, so
> saving and restoring it should not be necessary.

Good point. This can be removed.

It seems that *jmp and *context routines deal with same set of regs (in different
structures) and perhaps I should make them reuse asm code.

More information about the Libc-alpha mailing list