	.title	caller	Return name of profiled caller
	.ident	/000002/
;+
;
; Index		Return name of profiled caller
;
; Usage
;
;	char	*
;	caller();
;
; Description
;
;	If the routine which called the current function was compiled
;	using the profile option, caller() returns a pointer to the
;	name of the calling function.  If the calling function was
;	not compiled with profiling enabled, a pointer to the null
;	string is returned.
;
;	Example:
;
;		foo()
;		{
;			foobar();
;		}
;
;		foobar()
;		{
;			extern char *caller();
;
;			printf("foobar was called by %s\n",
;					caller());
;		}
;
;
; Internal
;
;	Warning -- this routine is sensitive to the format of
;	the environment frame and profile information layout.  If
;	csv$, pcsv$, or $$prof change, this may have to be modified.
; Bugs
;
;-
;
; Edit history
; 000001 17-Jun-80 MM	Initial edit
; 000002 19-Jan-87 JMC  Change .psect for I/D space.
;
	.enabl	gbl,lc
	.psect	c$data,d						;02
nopro:	.asciz	//		;Null string if needed
	.even

	.psect	c$code
caller::
;
; On entrance, r5 -> caller's caller's r5
;
	mov	(r5),r1		;r1 -> caller's caller's r5
	beq	10$		;Too soon for this mess
	mov	2(r1),r1	;r1 -> caller**2 return addr
	cmp	-(r1),-(r1)	;r1 -> call of caller**2
	cmp	(r1)+,#4767	;jsr pc,foo
	bne	10$		;bne if no good
	mov	(r1)+,r0	;entrance to caller**2
	add	r1,r0		;r0 -> caller entry
	cmp	(r0)+,#4567	;jsr r5
	bne	10$		;br if no not call
	mov	(r0)+,r1	;where's it calling?
	add	r0,r1		;r1 should -> pcsv
	cmp	r1,#pcsv$	;well?
	bne	10$		;br if not
	mov	(r0)+,r0	;yes, r0 -> profile buffer
	tst	(r0)+		;text begins at 2nd word
	return			;gotcha

10$:
	mov	#nopro,r0
	return
	.end

