+ /* Compute the correct value for reg_CODE based on the LRA.
+ This is a "simple" matter of subtracting a constant from
+ reg_LRA (where the LRA is stored by the return sequence) to
+ obtain a tagged pointer to the enclosing code component. Both
+ values are tagged OTHER_POINTER_LOWTAG, so we just have to
+ account for the eight words (see calculation for
+ RETURN_PC_HEADER_WIDETAG, above) between the two addresses.
+ Restoring reg_CODE doesn't appear to be strictly necessary
+ here, but let's observe the niceties.*/
+ addi reg_CODE, reg_LRA, -32
+
+ /* Multiple values are stored relative to reg_OCFP, which we
+ set to be the current top-of-stack. */
+ mr reg_OCFP, reg_CSP
+
+ /* Reserve a save location for the one value we have. */
+ addi reg_CSP, reg_CSP, 4
+
+ /* Record the number of values we have as a FIXNUM. */
+ li reg_NARGS, 4
+
+ /* Blank the remaining arg-passing registers. */
+ mr reg_A1, reg_NULL
+ mr reg_A2, reg_NULL
+ mr reg_A3, reg_NULL
+
+ /* And branch to our trap. */
+ b CSYMBOL(fun_end_breakpoint_trap)
+
+fun_end_breakpoint_multiple_values:
+ /* Compute the correct value for reg_CODE. See the
+ explanation for the single-value case, above. */
+ addi reg_CODE, reg_LRA, -32
+
+ /* The actual magic trap. */
+CSYMBOL(fun_end_breakpoint_trap):
+ twllei reg_ZERO, trap_FunEndBreakpoint
+
+ /* Finally, the debugger needs to know where the end of the
+ fun_end_breakpoint_guts are, so that it may calculate its size
+ in order to populate out a suitably-sized code object. */
+CSYMBOL(fun_end_breakpoint_end):
+ SET_SIZE(fun_end_breakpoint_guts)
+\f