Port-sparc64 archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

Re: CC64FSZ



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.


Home | Main Index | Thread Index | Old Index