Plan 9 from Bell Labs’s /usr/web/sources/contrib/steve/root/sys/src/c++/lib/task/sparc/frame.c

Copyright © 2021 Plan 9 Foundation.
Distributed under the MIT License.
Download the Plan 9 distribution.


#include "label.h"
#include <assert.h>

typedef unsigned long ulong;

/* 
 * return stack location guaranteed to have args for f in it
 */
unsigned long *
argbase(Label f)
{
	f = upframe(upframe(f));
	return (ulong *)f.sp;
}

/*
 * adjust label to reflect a moved stack location
 */
Label
movelabel(Label f, ulong sp)
{
	f.sp = sp;
	return f;
}

/*
 * return the top of main's stack
 * main => _main => __task__init => setlabel(m)
 */
ulong *
stackbase(Label m)
{
	return (ulong *)upframe(upframe(upframe(m))).sp;
}

#define MASKI	0xffffe000	/* mask SUBI reg bits in instruction */
#define MASKHI	0xfffc0000	/* mask SETHI reg bits in instruction */
#define SUBTSP	0x8220400e	/* SUB	R14, R1; for large stack frames */
#define	SUBISP	0x82206000	/* SUBI	const, R1 */
#define SETHI	0x1d000000	/* load hi part of R14 with constant << 10 */
#define ADDI	0x9c03a000	/* add low part to R14 */

#include <stdio.h>

/*
  * find the label for the frame calling f
 */
Label
upframe(Label f)
{
	ulong *pc;
	long offset;

	/* look for MOV R14,R1 or ADDIU const,R1 */
	for(pc = (ulong *)f.pc; (*pc & MASKI) != SUBISP; pc--)
		if(*pc == SUBTSP){
			/* look for sethi & optional add low into R14 */
			offset = 0;
			while((*--pc & MASKHI) != SETHI)
				if((*pc & MASKI) == ADDI){
					offset = *pc &~ MASKI;
					if(offset & 0x1000)
						offset |= MASKI;
				}
			offset += (*pc &~ MASKHI) << 10;
			break;
		}

	/* get the constant */
	if((*pc & MASKI) == SUBISP){
		offset = *pc &~ MASKI;
		/* sign extend */
		if (offset & 0x1000)
			offset |= MASKI;
	}

	/* return pc = 0(R1) */
	f.pc = *(ulong *)f.sp;

	f.sp += offset;
	return f;
}

Bell Labs OSI certified Powered by Plan 9

(Return to Plan 9 Home Page)

Copyright © 2021 Plan 9 Foundation. All Rights Reserved.
Comments to [email protected].