Hi Adhemerval,

A few comments on the assembly code:


+# This function is called with non-standard calling convention: on entry
+# x10 is the requested stack pointer, x11 is previous stack pointer (if
+# functions has stacked arguments which needs to be restored), and x12 is
+# the caller link register on function entry (which will be restored by
+# morestack when returning to caller).  The split-stack prologue is in
+# the form:
+#
+# function:
+#      mrs    x9, tpidr_el0
+#      ldur   x9, [x9, #-8]
+#      mov    x10, <required stack allocation>
+#      movk   x10, #0x0, lsl #16
+#      sub    x10, sp, x10
+#      mov    x11, sp          # if function has stacked arguments

+#      mov    x12, x30

This should go...

+#      cmp    x9, x10
+#      bcc    .LX
+# main_fn_entry:
+#      [function body]
+# LX:

...here:

        mov    x12, x30

+#      bl      __morestack
+#      b       main_fn_entry

Note using a bl here rather than a branch means you'll kill the return stack.

+# The N bit is also restored to indicate that the function is called
+# (so the prologue addition can set up the argument pointer correctly).
+
+ENTRY(__morestack)
+.LFB1:
+       .cfi_startproc
+
+#ifdef __PIC__
+       .cfi_personality 0x9b,DW.ref.__gcc_personality_v0
+       .cfi_lsda 0x1b,.LLSDA1
+#else
+       .cfi_personality 0x3,__gcc_personality_v0
+       .cfi_lsda 0x3,.LLSDA1
+#endif
+       # Calculate requested stack size.
+       sub     x10, sp, x10
+
+       # Save parameters
+       stp     x29, x12, [sp, -MORESTACK_FRAMESIZE]!
+       .cfi_def_cfa_offset MORESTACK_FRAMESIZE
+       .cfi_offset 29, -MORESTACK_FRAMESIZE
+       .cfi_offset 30, -MORESTACK_FRAMESIZE+8
+       add     x29, sp, 0
+       .cfi_def_cfa_register 29
+       # Adjust the requested stack size for the frame pointer save.
+       stp     x0, x1, [x29, 16]
+       stp     x2, x3, [x29, 32]
+       add     x10, x10, BACKOFF
+       stp     x4, x5, [x29, 48]
+       stp     x6, x7, [x29, 64]
+       stp     x8, x30, [x29, 80]
+       str     x10, [x29, 96]

Probably best to use NEWSTACK_SAVE here for clarity.

+       # void __morestack_block_signals (void)
+       bl      __morestack_block_signals
+
+       # void *__generic_morestack (size_t *pframe_size,
+       #                            void *old_stack,
+       #                            size_t param_size)
+       # pframe_size: is the size of the required stack frame (the function
+       #              amount of space remaining on the allocated stack).
+       # old_stack: points at the parameters the old stack
+       # param_size: size in bytes of parameters to copy to the new stack.
+       add     x0, x29, NEWSTACK_SAVE
+       add     x1, x29, MORESTACK_FRAMESIZE
+       mov     x2, 0
+       bl      __generic_morestack
+
+       # Start using new stack
+       mov     sp, x0
+
+       # Set __private_ss stack guard for the new stack.
+       ldr     x9, [x29, NEWSTACK_SAVE]
+       add     x0, x0, BACKOFF
+       sub     x0, x0, x9
+.LEHB0:
+       mrs     x1, tpidr_el0
+       str     x0, [x1, SPLITSTACK_PTR_TP]

Is the label for unwinding exactly at the right place?

+       # void __morestack_unblock_signals (void)
+       bl      __morestack_unblock_signals
+
+       # Set up for a call to the target function.
+       ldp     x0, x1, [x29, 16]
+       ldp     x2, x3, [x29, 32]
+       ldp     x4, x5, [x29, 48]
+       ldp     x6, x7, [x29, 64]
+       ldp     x8, x12, [x29, 80]
+       add     x11, x29, MORESTACK_FRAMESIZE

+       ldr     x30, [x29, 8]
+       # Indicate __morestack was called.
+       cmp     x12, 0

No idea what this is for but the ldr/cmp are completely redundant.

+       blr     x12
+
+       stp     x0, x1, [x29, 16]

+       stp     x2, x3, [x29, 32]
+       stp     x4, x5, [x29, 48]
+       stp     x6, x7, [x29, 64]

These 3 STPs are dead.

+       bl      __morestack_block_signals
+
+       # void *__generic_releasestack (size_t *pavailable)
+       add     x0, x29, NEWSTACK_SAVE
+       bl      __generic_releasestack
+
+       # Reset __private_ss stack guard to value for old stack
+       ldr     x9, [x29, NEWSTACK_SAVE]
+       add     x0, x0, BACKOFF
+       sub     x0, x0, x9
+
+       # Update TCB split stack field
+.LEHE0:
+       mrs     x1, tpidr_el0
+       str     x0, [x1, SPLITSTACK_PTR_TP]
+
+       bl __morestack_unblock_signals
+
+       # Use old stack again.
+       add     sp, x29, MORESTACK_FRAMESIZE
+
+       ldp     x0, x1, [x29, 16]

+       ldp     x2, x3, [x29, 32]
+       ldp     x4, x5, [x29, 48]
+       ldp     x6, x7, [x29, 64]

These 3 LDPs are dead.

+       ldp     x29, x30, [x29]
+
+       .cfi_remember_state
+       .cfi_restore 30
+       .cfi_restore 29
+       .cfi_def_cfa 31, 0
+
+       ret

Reply via email to