/*
 * flex.h
 *
 * [Generated from flex, 25 September 1996]
 */

#if !defined(__CC_NORCROFT) || !defined(__arm)
  #error You must use the Norcroft ARM Compiler for Sapphire programs
#endif

#pragma include_only_once
#pragma force_top_level

#ifndef __flex_h
#define __flex_h

#ifndef __sapphire_h
  #include "sapphire.h"
#endif

/*----- Overview ----------------------------------------------------------*
 *
 * Functions provided:
 *
 *  flex_reduce
 *  flex_compact
 *  flex_free
 *  flex_alloc
 *  flex_size
 *  flex_extend
 *  flex_midExtend
 *  flex_init
 *  flex_stackPtr
 *  flex_save
 *  flex_load
 *  flex_dump
 *
 * Macros provided:
 *
 *   FSAVE
 *   FLOAD
 */

/* --- flex_reduce --- *
 *
 * On entry:	--
 *
 * On exit:	--
 *
 * Use:		Compacts the flex heap by one iteration.
 */

extern routine flex_reduce;

/* --- flex_compact --- *
 *
 * On entry:	--
 *
 * On exit:	--
 *
 * Use:		Completely compacts the flex heap.
 */

extern routine flex_compact;

/* --- flex_free --- *
 *
 * On entry:	R0 == pointer to the flex anchor
 *
 * On exit:	--
 *
 * Use:		Frees a flex block allocated by flex_alloc.
 */

extern routine flex_free;

/* --- flex_alloc --- *
 *
 * On entry:	R0 == pointer to a flex anchor
 *		R1 == desired size of flex block
 *
 * On exit:	CS if no memory could be allocated, CC otherwise
 *
 * Use:		Allocates a block in the shifting heap.
 */

extern routine flex_alloc;

/* --- flex_size --- *
 *
 * On entry:	R0 == pointer to flex anchor
 *
 * On exit:	R0 == size of allocated block
 *
 * Use:		Reads the size of a flex block.
 */

extern routine flex_size;

/* --- flex_extend --- *
 *
 * On entry:	R0 == pointer to flex anchor
 *		R1 == new size of block to set
 *
 * On exit:	CS if it failed due to lack of memory, CC otherwise
 *
 * Use:		Alters the size of a block to the given value.
 */

extern routine flex_extend;

/* --- flex_midExtend --- *
 *
 * On entry:	R0 == pointer to a flex anchor
 *		R1 == `at' -- position in block to extend from
 *		R2 == `by' -- how many bytes to extend (may be -ve)
 *
 * On exit:	CS if it failed due to lack of memory, CC otherwise
 *
 * Use:		Either creates a gap in a block (by>0) or deletes bytes
 *		from a block.  This is always done in such a way that the
 *		byte originally at offset `at' is now at offset `at'+`by'.
 */

extern routine flex_midExtend;

/* --- flex_init --- *
 *
 * On entry:	--
 *
 * On exit:	--
 *
 * Use:		Initialises the flex heap for use.
 */

extern routine flex_init;

/* --- flex_stackPtr --- *
 *
 * On entry:	R0 == 0 to read, or value to set
 *
 * On exit:	R0 == old value
 *
 * Use:		Either reads or writes the flex stack pointer.  This sort
 *		of thing is useful in exception handlers etc.
 */

extern routine flex_stackPtr;

/* --- flex_save --- *
 *
 * On entry:	--
 *
 * On exit:	--
 *
 * Use:		Saves some registers on the flex relocation stack.  R13
 *		and R14 cannot be saved -- these registers are corrupted
 *		during this routine's execution.
 *
 *		Values saved on the flex relocation stack are adjusted as
 *		flex moves blocks of memory around, so that they still point
 *		to the same thing as they did before.  Obviously, values
 *		which aren't pointers into flex blocks may be corrupted.
 *		Values pointing to objects deleted (either free blocks, or
 *		areas removed by flex_midExtend) may also be corrupted.
 *
 *		Since this routine takes no arguments, some other method has
 *		to be used.  The method chosen is to follow the call to
 *		flex_save with a LDM or STM instruction containing the
 *		registers to be saved.  This instruction is skipped by the
 *		routine, and thus not executed.
 *
 *		Note that if you give the LDM or STM the same condition code
 *		as the BL preceding it, it will never be executed, since
 *		flex_save skips it if the condition is true and it can't be
 *		executed if the condition is false.
 */

extern routine flex_save;

/* --- flex_load --- *
 *
 * On entry:	--
 *
 * On exit:	Registers loaded from relocation stack as requested
 *
 * Use:		Restores registers saved on flex's relocation stack.  See
 *		flex_save for calling information and details about the
 *		relocation stack.
 */

extern routine flex_load;

/*----- Useful macros -----------------------------------------------------*/

/* --- Macro: FSAVE --- *
 *
 * Arguments:	rList == quoted register list to save on relocation stack
 *
 * Use:		Assembles code to write the given register list on the
 *		flex relocation stack.  The register list should be in the
 *		same form as that for an STM or LDM instruction.
 *
 *		For full details about the flex relocation stack, see
 *		flex_save.
 */

/* --- Macro: FLOAD --- *
 *
 * Arguments:	rList == quoted register list to read from relocation stack
 *
 * Use:		Assembles code to read the given register list from the
 *		flex relocation stack.  The register list should be in the
 *		same form as that for an STM or LDM instruction.
 *
 *		For full details about the flex relocation stack, see
 *		flex_save.
 */

/*----- That's all, folks -------------------------------------------------*/

#endif
