Re: CC64FSZ

Mark Cave-Ayland <[email protected]> Tue, 15 Feb 2022 07:38:52 +0000
Newsgroups gmane.os.netbsd.ports.sparc64
Message-ID <[email protected]>
On 15/02/2022 02:39, Eduardo Horvath wrote:

> On Tue, 15 Feb 2022, matthew green wrote:
> 
>> Palle Lyckegaard writes:
>>> Hello fellow SPARC friends.
>>>
>>> Looking at the comments in sys/arch/sparc/include/frame.h it seem to be
>>> incorrect:
>>> ...
>>> /*
>>>    * CC64FSZ (C Compiler 64-bit Frame SiZe) is the size of a stack frame
>>> used
>>>    * by the compiler in 64-bit mode.  It is (16)*8; space for 8 ins, 8 outs.
>>>    */
>>> #define CC64FSZ		176
>>> ...
>>>
>>>
>>> But 16 * 8 = 128.
>>>
>>> Can anyone share some knowledge on why CF64FSZ is 176 bytes and not 128
>>> bytes as the comment says?
>>
>> my memory tells me it was to store other registers and you
>> can find them in locore.s it seems.  176-128 is 48, which is
>> 6x 8 byte registers, and look here:
>>
>>     2485 Ldatafault_internal:
>> ...
>>     2499         stx     %g1, [%sp + CC64FSZ + STKB + TF_G + (1*8)]      ! save g1
>> ...
>>     2513         sth     %o1, [%sp + CC64FSZ + STKB + TF_TT]
>>     2514         stx     %g1, [%sp + CC64FSZ + STKB + TF_TSTATE]         ! set tf.tf_psr, tf.tf_pc
>>     2515         stx     %g2, [%sp + CC64FSZ + STKB + TF_PC]             ! set tf.tf_npc
>>     2516         stx     %g3, [%sp + CC64FSZ + STKB + TF_NPC]
>> ...
>>     2519         stb     %g4, [%sp + CC64FSZ + STKB + TF_PIL]
>>     2520         stb     %g4, [%sp + CC64FSZ + STKB + TF_OLDPIL]
>>
>>
>> i'm pretty sure this is the answer.  hopefully someone else
>> will correct me if i'm missing this one :)
> 
> Those extra registers should only be stored in trap frames, not regular
> stack frames.
> 
> ISTR the 176 value came from Solaris.  We could probably get by with 128
> byte stack frames, but for compatiblility and safety reasons I decided to
> follow Solaris does in case the compiler decides to generate funky code.
> If you take a look at the actual definition of the stack frame:
> 
> If you go up a few lines in frame.h you can see the actual layout:
> 
> struct frame64 {
> 	int64_t	fr_local[8];	/* space to save locals (%l0..%l7) */
> 	int64_t	fr_arg[6];	/* space to save arguments (%i0..%i5) */
> 	uint64_t	fr_fp;		/* space to save frame pointer
> (%i6) */
> 	uint64_t	fr_pc;		/* space to save return pc (%i7)
> */
> 	/*
> 	 * SVR4 reserves a bunch of extra stuff.
> 	 */
> 	int64_t fr_argd[6];	/* `register save area' (lunacy) */
> 	int64_t	fr_argx[0];	/* arg extension (args 7..n; variable
> size) */
> };
> 
> I think the idea is that on SPARC the first 6 function parameters are
> passed in registers,  Extra space is provided in the stack frame in case
> the compiler needs to spill those registers to the stack.  But I don't
> think this ever really happens.

FWIW OpenBIOS uses a stack frame size of 192 which was introduced in 
https://github.com/openbios/openbios/commit/a5eb73397577535e91927783e3bd3b1d81744d4c 
apparently because code generated using "gcc -O0" requires a larger stack size than 128.


ATB,

Mark.