/*
 * $Header: /smsa/bsd:include/arm/frame.h:bsd  1.9  $
 * $Source: /smsa/bsd:include/arm/frame.h: $
 *
 * Copyright (c) 1988 Acorn Computers Ltd., Cambridge, England
 *
 */

#ifndef __arm_frame_h
#define __arm_frame_h
#define	__machine_frame_h	"arm"

#ifndef	_KERNEL
#ifndef __machine_apcs_h
#include "apcs.h"
#endif
#endif	_KERNEL

/*
 * The ARM procedure call standard describes the layout of
 * a stack frame at the time of an external procedure call
 * in a language system which obeys the procedure call standard.
 *
 * RISC iX further requires that the frame pointer register
 * (as defined by the procedure call standard) always points to
 * a valid stack frame.  The register bindings are defined in
 * the arm setjmp.h header file.  These values are not used
 * here - the layout of the stack frame is independant of the
 * register bindings.
 */

/*
 * The following structures define the static part of the
 * frame.  Notice that the frame pointer points to the
 * save mask pointer (as saved pc/r15 value) not at the
 * base of the structure, thus the ``frame'' is at fp[-1]
 * where fp is of type (struct frame *).
 */
typedef unsigned Instruction;
typedef int Register;
typedef Instruction *RSMPtr;

struct frame {
    struct frame *fp;    /* Save frame pointer */
    void         *sp;    /* Saved stack pointer */
    Instruction  *lr;    /* Return link value */
};

typedef union {
    RSMPtr       *fprsm; /* Actually twelve bytes beyond it */
    struct frame *fpfp;  /* Frame is fpfp[-1] */
}   FramePtr;

/*
 * The following is the nearest reasonable mapping onto a
 * calls/callg type frame:-
 */
struct pseudo_vax_frame {
	unsigned	fr_savfp;	/* Saved frame pointer */
	unsigned	fr_savap;	/* Argument pointer == saved stack pointer */
	unsigned	fr_savpc;	/* Saved return pc for this routine */
	unsigned	fr_maskp;	/* Save mask pointer/bits - fp points here */
};

/*
 * Immediately before the frame (higher on the stack == lower
 * address) are up to six saved register variables, followed
 * by up to four saved argument variables (never placed here
 * in RISC iX) and four saved (extended precision) floating
 * point values.
 */

/*
 * The fr_maskp/fprsm field points twelve bytes beyond a word which
 * defines the register save mask, when bits 0,1,26-31 have been
 * cleared:-
 */
struct arm_pc {
	unsigned	mode: 2;	/* Processor mode */
	unsigned	pc: 24;		/* Program counter (/4) */
	unsigned	F: 1;		/* FIQ disable */
	unsigned	I: 1;		/* IRQ disable */
	unsigned	V: 1;		/* overflow */
	unsigned	C: 1;		/* carry */
	unsigned	Z: 1;		/* zero */
	unsigned	N: 1;		/* negative */
};

#define FR_MODE_BITS 0xFC000003

/* The processor modes are: */
#define FR_USER_MODE	0
#define FR_FIQ_MODE	1
#define FR_IRQ_MODE	2
#define FR_SVC_MODE	3

#define FR_rsm_instructions(maskp) \
	((RSMPtr)( ((unsigned)(maskp) & ~FR_MODE_BITS) - 12 ) )
#define FR_savedreg(mask) ((mask) & 0x2FF)

#ifndef _KERNEL
/*
 * The register save mask must have the following bit pattern
 * when the low 10 bits have been cleared (the low 10 bits correspond
 * to the 10 registers which might have been saved on the stack.)  The
 * other pattern given is that of the floating point save instructions
 * which may immediately follow the register save instruction.
 */
#define FR_RSM_INSTRUCTION APCS_RSM_INSTRUCTION
#define FR_FPS_INSTRUCTION APCS_FPS_INSTRUCTION

#endif _KERNEL

#define FR_savedfpreg(mask) (((mask) & 0x3000) >> 12)

#endif/*_arm_frame_h*/

/* EOF frame.h */
