/* $Id: rgir.h,v 1.6 1997/02/17 20:19:14 jay Exp $ */
/* Copyright (C) 1995, by Motorola, Inc. */

/*
   $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$
   $
   $                COMMON DEFINITIONS AND ENUMERATED TYPES
   $
   $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$
 */

#define MB_NUM MB_NOT_AVAILABLE

typedef int BOOL;
typedef int CONDITION;
typedef int REGISTER_NAME;
typedef unsigned long INST_ATTRIBUTES;
typedef unsigned long DATA_ATTRIBUTES;
typedef int OPERATION;
typedef void *KEY;

#ifndef DSP_TYPES_DEFINED
#define DSP_TYPES_DEFINED

typedef unsigned long DSP_ADDR;	/* absolute memory address */
typedef unsigned long DSP_DATA;	/* data word */

#endif

/***************************************************************************

 *  address space 
 *
 **************************************************************************/
typedef enum
{
    MEM_NONE,
    MEM_X,
    MEM_Y,
    MEM_P,
    MEM_L,
    NUM_ADDR_SPACES
}
ADDRESS_SPACE;

/***************************************************************************

 *  addressing mode 
 *
 **************************************************************************/
typedef enum
{
    AM_NONE,
    AM_POST_DEC_OFF,		/* (r0)-n0 */
    AM_POST_INC_OFF,		/* (r0)+n0 */
    AM_POST_DEC,		/* (r0)- */
    AM_POST_INC,		/* (r0)+ */
    AM_INDIRECT,		/* (r0) */
    AM_INDEX,			/* (r0+n0) */
    AM_UNUSED1,			/* place holder */
    AM_PRE_DEC,			/* -(r0) */
    AM_ABSVAL,			/* $1234 */
    AM_IMMVAL,			/* #$1234 */
    AM_UNUSED2,			/* place holder */
    AM_DIRECT,			/* r0 */
    AM_DISP,			/* (r0+$123) */
    AM_PCREL,			/* for bsr etc. */
    AM_IMPLICIT,		/* implicit reference */
    AM_LAST_MODE		/* MUST BE LAST ELEMENT */
}
ADDR_MODE;

#define IS_AM_MEMORY(AM)        (((AM) > AM_NONE && (AM) <= AM_INDEX) || \
                                        ((AM) == AM_DISP))

/******************************************************************************

 *    Operand position 
 *
 *****************************************************************************/
typedef enum
{
    POS_SRC1,
    POS_SRC2,
    POS_DEST,			/* target of the computation or branch */
    POS_VALUE,			/* constant value */
    /* NUM_OPND must be last */
    NUM_OPND			/* number of operands in the array */
}
OPND_POS;

/******************************************************************************

 *    Memory Operation Type
 *
 *****************************************************************************/
typedef enum MOT
{
    MO_READ,
    MO_WRITE,
    MO_last
}
MOT;

/*****************************************************************************

 *    Memory Block Type
 *
 *****************************************************************************/

typedef enum MBT
{
    MB_INTERNAL,
    MB_EXTERNAL,
    MB_INTERNAL_ROM,
    MB_EXTERNAL_ROM,
    MB_NOT_AVAILABLE,
    MB_RO,
    MB_RW,
    MB_LAST
}
MBT;

/************************************************************

 *   Binary tree Node structure
 *
 ************************************************************/
struct NODE
{
    int hight;
    struct NODE *left;
    KEY key;
    struct NODE *right;
};

/************************************************************
 * Type: TREE
 *
 * Purpose:
 *          Binary tree
 * Members:
 *          root - pointer to the root node
 *          size - number of elements currently in the node
 *          compare_fnc - index of comparison function by which 
 *                        the tree is sorted
 ************************************************************/
struct TREE
{
    struct NODE *root;
    unsigned size;
    int compare_fnc;
};

/*
   $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$
   $
   $                MEMORY ALLOCATION MANAGEMENT
   $
   $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$
 */

/************************************************************
 * Type: CALLOC_BLOCK
 *
 * Purpose:
 *          hold a single memory block
 * Members:
 *          block_size   - block's size in bytes
 *          block_string - block's type (TRUE only for block of strings)
 *          block_bottom - pointer to bottom of actual block
 *          block_top    - pointer to top of actual block 
 *          block_next   - pointer to the next memory block
 ************************************************************/
struct CALLOC_BLOCK
{
    int block_size;
    BOOL block_string;
    char *block_bottom;
    char *block_top;
    struct CALLOC_BLOCK *block_next;
};

/************************************************************
 * Type: CALLOC
 *
 * Purpose:
 *           memory allocation structure
 * Members:
 *           first_block  - pointer to the first block
 *           last_block   - pointer to the last block
 *           last_reg_block - pointer to the last "regular" block
 *           last_str_block - pointer to the last "string" block
 *           default_size - default block size 
 *                         (the actual size of some blocks may be bigger)
 *           num_blocks   - current length of block list
 ************************************************************/
struct CALLOC
{
    struct CALLOC_BLOCK *first_block;
    struct CALLOC_BLOCK *last_block;
    struct CALLOC_BLOCK *last_reg_block;
    struct CALLOC_BLOCK *last_str_block;
    int default_size;
    int num_blocks;
};

/*
   $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$
   $
   $                DSP SYMBOLS
   $
   $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$
 */

/******************************************************************************

 *    Symbol type 
 *
 *****************************************************************************/
typedef enum
{
    ST_INT,			/* A one-word value */
    ST_LONG,			/* A two-word value */
    ST_FLOAT,
    ST_ADDR,			/* Symbol is a label */
    ST_SUB,			/* Symbol is a subroutine name */
    ST_MACRO			/* Symbol is a macro name */
}
SYMBOL_TYPE;


/******************************************************************************

 *    Symbol type 
 *
 *****************************************************************************/
typedef enum
{
    SCP_SYS = 0,
    SCP_GLOBAL = A_GLOBAL,
    SCP_LOCAL = A_SLOCAL,
    SCP_XDEF = A_XDEF
}
SYMBOL_SCOPE;


/************************************************************
 * Union: SYMBOL_VALUE
 *
 * Purpose:
 *           Holds the value of a single symbol
 * Members:
 *           int_value   - For ST_INT 
 *           addr_value  - union:
 *                          space    - Space to which this symbol refers 
 *                          addr     - Address to which the symbol refers 
 *                          end_addr - Address up to which it refers 
 *                          inst     - Instruction node (if exists)
 * 
 *           long_value  - For ST_LONG 
 *           float_value - For ST_FLOAT 
 *           routine_value - For Subroutines
 ************************************************************/
union SYMBOL_VALUE
{
    DSP_DATA int_value;
    DSP_DATA long_value[2];
    double float_value;

    struct
    {
	ADDRESS_SPACE space;
	DSP_ADDR addr;
	DSP_ADDR end_addr;
	struct INSTRUCTION_NODE *inst;
    }
    addr_value;

    struct ROUTINE_INFO *routine_value;
};

/***************************************************************************
 * Type: SYMBOL
 *
 * Purpose:
 *   Holds a single symbol's record.
 *   This is a variant record. The type field specifies which member
 *   of the variant record is in use.
 *
 * Members:
 *    name         -  Name of the symbol 
 *    section      -  Section in which this symbol is defined after remap
 *    type         -  Type of the symbol 
 *    value        -  Value of symbol
 ***************************************************************************/
struct SYMBOL
{
    char *name;
    int section;
    SYMBOL_SCOPE scope;	
    SYMBOL_TYPE type;
    union SYMBOL_VALUE value;
};

/**************************************************************************

 *   OPERAND structure. This is a record which describes an operand
 *   for an operation. There may be more than one of these for the
 *   instruction.
 *
 **************************************************************************/
struct OPERAND
{
    ADDR_MODE mode;		/* addressing mode */
    REGISTER_NAME regn;		/* register name of the operand */
    DSP_DATA value;		/* value of the operand */
    ADDRESS_SPACE m_space;	/* address space for the operand */
    BOOL is_long_operand;	/* for imm/abs */

    struct DATA_NODE *location;	/* pointer to the data node for the
				 * operand */
    char *reference;		/* string containing the reference to
				 * the memory location from the source
				 * code. includes any computation
				 */
};

/***************************************************************************

 * types of parallel move instructions 
 *
 **************************************************************************/
enum
{
    RGM_SINGLE,			/* single move no paired instruction */
    RGM_SINGLE_PAIRED,		/* single move, paired */
    RGM_DOUBLE,			/* double move,no paired instruction */
    RGM_DOUBLE_PAIRED,		/* double move, paired */
    RGM_L,			/* L space move,no paired instruction */
    RGM_L_PAIRED,		/* paired L space move */
    RGM_MOVE_NUM
};

/***************************************************************************

 * PARALLEL MOVE structure. These form a linked list of nodes which describe
 * a move operation that takes place in parallel with the instruction
 * operation. If the list is set to null, then there are no parallel moves for
 * this instruction.
 *
 * Used with LINK structure.
 *
 ***************************************************************************/
struct PARALLEL_MOVES
{
    struct OPERAND source;	/* source of the move */
    struct OPERAND destination;	/* destination of the move */
};

/****************************************************************************
 *  LINK node. parallel move linked list node. 
 *
 ****************************************************************************/
struct LINK
{
    struct LINK *prev;		/* pointer to the previous node in the list */
    struct LINK *next;		/* pointer to the next node in the list */
    struct PARALLEL_MOVES *moves;
};

/*
   $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$
   $                        SUBROUTINE PART
   $
   $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$
 */

#define MAX_SUB_STACK_DEPTH 22

/***************************************************************************
 * SUBROUTINE ATTRIBUTE enumeration. A data structure which contains
 * information used in the subroutine manipulation
 ***************************************************************************/

#define SUBROUTINE_DIRECTIVE_ATTRIBUTE \
SATR(IGNORE) \
SATR(RETURN) \
SATR(ENTER) \
SATR(ANY) \
SATR(CALL) \
SATR(JOINT_RET)

enum
{
#define SATR(X) SATR_shift_ ## X,
    SUBROUTINE_DIRECTIVE_ATTRIBUTE
#undef SATR
    SATR_shift_LAST
};

typedef enum
{
#define SATR(X) SATR_ ## X = (1 << SATR_shift_ ## X),
    SUBROUTINE_DIRECTIVE_ATTRIBUTE
#undef SATR
    SATR_LAST
}
ROUTINE_DIRECTIVE;

#define DRCT_PREFIX ";##"
#define DRCT_NESTED "nested"	/* set code coverage format */
#define DRCT_IGNORE "ignore"	/* ignore routine-related meaning of inst */
#define DRCT_RETURN "return"	/* instruction returns from call */
#define DRCT_ENTER  "enter"	/* instruction can start a call */
#define DRCT_ANY    "any"	/* instruction always starts a call */
#define DRCT_CALL   "call"	/* instruction performs a call */
#define DRCT_JOINT_RET "joint_ret"	/* a call that return with its caller */

/* 
 *  routine attributes. means:
 *  INLINE    - macro subroutine
 *  NAME      - explicit name known
 *  RECURSION - set when the subroutine calls itself directly
 *  DOUBT     - set in the merged subroutine when the
 *              two merged subroutines might have called one another
 *  SHOW_..   - graph flags showing whether the routine was already displayed
 */

#define SUBROUTINE_ATTRIBUTE \
SA(INLINE) \
SA(NAME) \
SA(RECURSION) \
SA(DOUBT) \
SA(SHOW) \
SA(SHOW_PS)\
SA(SHOW_GRAPH)

enum
{
#define SA(X) SA_shift_ ## X,
    SUBROUTINE_ATTRIBUTE
#undef SA
    SA_shift_LAST
};

typedef enum
{
#define SA(X) SA_ ## X = (1 << SA_shift_ ## X),
    SUBROUTINE_ATTRIBUTE
#undef SA
    SA_LAST
}
ROUTINE_ATT;

/************************************************************
 * Type: CALL_INFO
 *
 * Purpose:
 *          describe an element (node) in a children/parent tree
 * Members:
 *     rft_routine - the routine represented by the node
 *     rft_calls   - calls between the routine and the owner 
 *     rft_cycles  - cycles passed between routine and owner 
 *
 ************************************************************/
struct CALL_INFO
{
    struct ROUTINE_INFO *rft_routine;
    unsigned long rft_calls;
    unsigned long rft_cycles;
};

/****************************************************************************
 *   General pair definition 
 *
 ****************************************************************************/
struct PAIR
{
    int x;
    int y;
};

/************************************************************
 * Type: RECTANGLE  
 *       for details see the graph algorithm in rggraph.c
 ************************************************************/
struct RECTANGLE
{
    struct PAIR dim;
    enum
    {
	UNTOUCHED, LOCATED, VISITED
    }
    state;
    struct PAIR location;
};

/************************************************************
 * Type: ROUTINE_INFO
 *
 * Purpose:
 *          information about a single subroutine
 * Members:
 *  rti_id           - routine ID number (a number unique to the routine)
 *  rti_name         - Explicit name of subroutine 
 *
 *  rti_entry_tree   - Tree of all instruction nodes that start the routine
 *  rti_call_tree    - Tree of all instruction nodes that call the routine
 * 
 *  rti_child_tree   - Tree of all routines that were called by the routine
 *  rti_parent_tree  - Tree of all routines that called this routine
 *
 *  rti_attr         - properties 
 *  rti_self_cycles  - number of cycles spent in the routine itself
 *  rti_rec_cycles   - number of cycles spent in the routine itself while
 *                     the subroutine was already on the subroutine stack    
 *  rti_total_cycles - number of cycles spent in the routine's descendants
 *  rti_calls        - number of times the subroutine was called
 *  rti_stamp        - last cycle in which the DFS merge traverse visited
 *                     the subroutine
 *  rti_tree_size    - number of subroutines that were merged to create this
 *                     subroutine
 *  rti_up           - (for routines that were merged and left out of the
 *                      linked list) the routine that represents this 
 *                      subroutine in the list 
 *                      
 *  rti_box          - (see ps graph) main caller (parent in the graph)
 *  rti_rect         - (see ps graph) location as a son (subrectangle) 
 *                                    in the box of parent
 *  rti_coordinates  - (see ps graph) final position in the report page
 ************************************************************/
struct ROUTINE_INFO
{
    int rti_id;
    char *rti_name;

    struct TREE *rti_entry_tree;
    struct TREE *rti_call_tree;

    struct TREE *rti_child_tree;
    struct TREE *rti_parent_tree;

    ROUTINE_ATT rti_attr;
    unsigned long rti_self_cycles;
    unsigned long rti_rec_cycles;
    unsigned long rti_total_cycles;
    unsigned long rti_calls;
    unsigned long rti_stamp;
    unsigned rti_tree_size;

    struct RECTANGLE rti_rect;
    struct ROUTINE_INFO *rti_box;
    struct PAIR rti_coordinates;
};

/************************************************************
 * Type: ROUTINE_STACK_ENTRY
 *
 * Purpose:
 *             an entry in the routines' stack
 * Members:
 *
 *   rse_routine      - pointer to the routine pushed 
 *   rse_entry_point  - memory address of entry point passed through 
 *                     in current invocation
 *   rse_start_cycle  - a total cycle count from which further cycles
 *                      will be concidered as the routine's cycles
 *   rse_as_son       - called routine's link in the children chain  
 *                     (not instansiated for top entry)
 *   rse_father       - caller's link at the parent chain
 *   rse_macro        - instruction node from which we can take macro
 *                      (which are the macro name and the 
 *                       source line invoking it)
 *   rse_joint_return - a flag indicating whether the call 
 *                      should return with the caller
 ************************************************************/
struct ROUTINE_STACK_ENTRY
{
    struct ROUTINE_INFO *rse_routine;
    DSP_ADDR rse_entry_point;
    unsigned long rse_start_cycle;
    struct CALL_INFO *rse_as_son;
    struct CALL_INFO *rse_father;
    struct INSTRUCTION_NODE *rse_macro;
    BOOL rse_joint_return;
};

/************************************************************
 * Type: SUBROUTINES
 *
 * Purpose:
 *          general information about the program's subroutines
 * Members:
 *  
 *   sub_tree           - actual routines
 *   sub_main           - main routine
 *   sub_id_max         - number of subroutines generated so far
 * 
 *   sub_stack          - array of subroutine stack elements
 *   sub_stack_top      - number of current top entry
 *   sub_stack_err      - details of error
 *
 *   sub_call_flag      - does the current instruction starts a call 
 *   sub_active_macro   - when control is in instructions
 *   sub_previous_cmd   - previous instruction executed
 *
 ************************************************************/
struct SUBROUTINES
{
    struct TREE *sub_tree;
    struct ROUTINE_INFO *sub_main;
    int sub_id_max;

    struct ROUTINE_STACK_ENTRY sub_stack[MAX_SUB_STACK_DEPTH];
    int sub_stack_top;
    struct
    {
	char *file;
	long line;
    }
    sub_stack_err;

    BOOL sub_call_flag;
    struct INSTRUCTION_NODE *sub_active_macro;
    struct INSTRUCTION_NODE *sub_previous_cmd;
};

/*
   $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$
   $                        INSTRUCTION PART
   $
   $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$
 */

struct INST_STATUS
{
    char *source_file;
    long source_line;
    char *macro_name;
    char *directive;
    BOOL dc;
};

/***************************************************************************
 * INSTRUCTION ATTRIBUTE enumeration. A data structure which contains
 * information used in the analysis and optimization operations.
 ***************************************************************************/

#define        INSTRUCTION_ATTRIBUTE_LIST       \
     IATR_DEF(EXEC_START)                       \
     IATR_DEF(EXEC_STOP)                        \
     IATR_DEF(TWO_WORD)                         \
     IATR_DEF(IFCC)                             \
     IATR_DEF(IFCCU)                            \
     IATR_DEF(MPY_NEGATIVE)                     \
     IATR_DEF(UNSIGNED_S1)                      \
     IATR_DEF(UNSIGNED_S2)                      \
     IATR_DEF(MOVE)                             \
     IATR_DEF(DALU)                             \
     IATR_DEF(CACHE)                            \
     IATR_DEF(OVLY)                             \
     IATR_DEF(DYNAMIC)                          \
     IATR_DEF(LAST)

enum INSTRUCTION_ATTRIBUTE_AUX
{
#define   IATR_DEF(X)    ishift_ ## X,
    INSTRUCTION_ATTRIBUTE_LIST
#undef IATR_DEF
    ishift_last
};

enum INSTRUCTION_ATTRIBUTE
{
#define   IATR_DEF(X)    IATR_ ## X = (1<<ishift_ ## X),
    INSTRUCTION_ATTRIBUTE_LIST
#undef IATR_DEF
    IATR_last
};

#undef    INSTRUCTION_ATTRIBUTE_LIST

/************************************************************
 * Type: INST_INFO
 *
 * Purpose:
 *          this structure reside in the instruction nodes and
 *          holds profiling information about the instruction
 * Members:
 *         pass               - number of times the instruction was executed
 *         cond_pass          - number of times condition was satisfied 
 *                                (relevant for conditional instructions)
 *         cycles             - number of cycles spent in the instruction
 *         loop_cycles        - total cycles spent in loop 
 *                                (relevant for instructions that start loops)
 *         directive_bit_flag - subroutine related attributes
 ************************************************************/
struct INST_INFO
{
    unsigned pass;
    unsigned cond_pass;
    unsigned loop_pass;
    unsigned cycles;
    unsigned stall;
    unsigned loop_cycles;

    ROUTINE_DIRECTIVE directive_bit_flag;
};

/************************************************************
 * Type:  INSTRUCTION NODE structure
 *
 * Purpose:
 *          holds one instruction that was either
 *          1) defined in the COFF  or
 *          2) was executed dynamically
 *           
 * Members:
 *     
 *    addr          - Absolute address of this instruction
 *                    in program memory space 
 *    word1         - Encoding of instruction 
 *    word2
 *    attributes    - Attributes of this instruction 
 * 
 *    op            - Operation for this instruction 
 *    opnd          - Array of operands 
 *    moves         - List of parallel moves 
 *    condition     - Condition for operation 
 *    val_sr        - Value of registers at creation time 
 *    val_omr
 * 
 *    enter_sub     - Subroutine which the node is an entry point for
 *    call_sub      - Subroutine which the node calls explicitly 
 *                    (by name defined in a subroutine directive)
 *
 *    macro_source  - String containing the macro invocation of the 
 *                    first instuction of the macro expansion, if any 
 *    source_file   - Source file name 
 *    source_line   - Source line number 
 * 
 *    overlay_sp    - Data space origin of node 
 *    overlay_addr  - Data address origin of node 
 *    last_load_cyc    - Last cycle when instruction was executed 
 * 
 *    line_order    - as in source file and COFF 
 * 
 *    profiler_info - Profiling data
 ***************************************************************************/
struct INSTRUCTION_NODE
{
    DSP_ADDR addr;

    DSP_DATA word1;
    DSP_DATA word2;

    INST_ATTRIBUTES attributes;

    OPERATION op;
    struct OPERAND opnd[NUM_OPND];
    struct LINK *moves;
    CONDITION condition;
    DSP_DATA val_sr;
    DSP_DATA val_omr;

    struct ROUTINE_INFO *call_sub;
    struct ROUTINE_INFO *enter_sub;

    struct SYMBOL *label;
    char *macro_source;
    char *source_file;
    unsigned source_line;

    ADDRESS_SPACE overlay_sp;
    DSP_DATA overlay_addr;
    long last_load_cyc;

    int section;
    unsigned line_order;

    struct INST_INFO profiler_info;
};

/*
   $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$
   $                        DATA DECLARATION PART
   $
   $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$
 */

/***************************************************************************
 * DATA ATTRIBUTE enumeration. A data structure which contains
 * information used in the analysis and optimization operations.
 ***************************************************************************/

#define        DATA_ATTRIBUTE_LIST      \
     DATR_DEF(L_ELEMENT)                \
     DATR_DEF(INITIALIZED)              \
     DATR_DEF(DYNAMIC)                  \
     DATR_DEF(FIRST_IN_BUFFER)          \
     DATR_DEF(DUMP_ORG_X)               \
     DATR_DEF(DUMP_ORG_Y)               \
     DATR_DEF(DUMP_ORG_P)               \
     DATR_DEF(DUMP_ORG_L)               \
     DATR_DEF(LAST)

enum DATA_ATTRIBUTE_AUX
{
#define   DATR_DEF(X)    dshift_ ## X,
    DATA_ATTRIBUTE_LIST
#undef DATR_DEF
    dshift_last
};

enum DATA_ATTRIBUTE
{
#define   DATR_DEF(X)    DATR_ ## X = (1<<dshift_ ## X),
    DATA_ATTRIBUTE_LIST
#undef DATR_DEF
    DATR_last
};

#undef    DATA_ATTRIBUTE_LIST

/************************************************************
 * Type: DATA_INFO
 *
 * Purpose:
 *          this structure reside in the data nodes and
 *          holds profiling information about the memory location
 * Members:
 *          accesss - number of reads/writes of address during execution 
 ************************************************************/
struct DATA_INFO
{
    unsigned access[MO_last];
};

/************************************************************
 * Type: DATA NODE  
 *
 * Purpose:
 *   Structure which describes a particular data element.
 *   There is one node for each data word allocated. 
 *
 * 
 * Members:
 *      space  - space to which this data refers 
 *      addr   - memory address of the data element 
 *      word   - value assigned to this element 
 *      attributes - attributes of this data 
 *      profiler_info
 ***************************************************************************/
struct DATA_NODE
{
    ADDRESS_SPACE space;	/* space to which this data refers */
    DSP_ADDR addr;		/* memory address of the data element */
    DSP_DATA word;		/* value assigned to this element */
    DATA_ATTRIBUTES attributes;	/* attributes of this data */
    struct DATA_INFO profiler_info;
};

/*
   $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$
   $
   $                PROGRAM
   $
   $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$
 */

#define READ_RING_SIZE 8
#define MAX_AM_GROUPS 20
#define MAX_OP_NUMBER 200

/************************************************************
 * Type: ERR_VECTOR
 *
 * Purpose:
 *       holds validity flags of several report section
 * Members:
 *       err_coff - error while reading coff file
 *       err_subr - subroutine error (stack overflow etc)
 *       err_inst - undecoded coff instruction (probably a result of DC)
 *       err_fatl - fatal error (such as memory allocation problems)
 ************************************************************/
struct ERR_VECTOR
{
    unsigned err_coff:1;
    unsigned err_subr:2;	/* 1 = overflow, 2 = underflow, 3 = other */
    unsigned err_inst:1;
    unsigned err_fatl:1;
};

/************************************************************
 * Type: PROFILE_INFO 
 *
 * Purpose:
 *       holds profiling data for a program  
 * Members:
 *           data_size_init       - initialized data size in words 
 *           data_size_noninit    - noninitialized data size in words 
 *           code_size_static     - code size in words 
 *           code_size_dynamic    - code size in words 
 *           instructions_static  - no. of instructions in the program 
 *           instructions_dynamic - no. of executed instructions 
 *           function_calls       - subroutine calls 
 *           cycles               - total cycle count for the run 
 *           stall                - total stall cycles for the run
 *           max_loop_nesting     - maximum loop nesting level (static)
 *           memory_access        - total no. of io accesses 
 *           cmd_parallelize      - does instruction allow parallel moves?
 *           cmd_static           - individual command occurrences (static)
 *           cmd_dynamic          - individual command occurrences (dynamic)
 *           cmd_static_loop_deepest 
 *                                - max loop nesting level in which instruction appears
 *           cmd_static_loop      - individual command occurrences in 
 *                                  deepest nesting level of a loop
 *           cmd_static_not_loop  - individual command occurrences outside loops
 *           (..same for dynamic)
 *           cmd_static_mv0/1/2   - individual parallel moves in commands
 *           cmd_dynamic_mv0/1/2  - individual parallel moves in commands
 *           move_cmd             - total move number (single/double/parallel)
 *           address_mode         - instruction breakdown by addressing mode
 ************************************************************/
struct PROFILE_INFO
{
    unsigned data_size_init[NUM_ADDR_SPACES];
    unsigned data_size_noninit[NUM_ADDR_SPACES];
    unsigned data_write_dynamic[NUM_ADDR_SPACES];
    unsigned code_size_static;
    unsigned code_size_dynamic;
    unsigned instructions_static;
    unsigned instructions_dynamic;
    unsigned function_calls;
    unsigned long cycles;
    unsigned long stall;
    unsigned max_loop_nesting;
    int      cmd_parallelize[MAX_OP_NUMBER];
    unsigned cmd_static[MAX_OP_NUMBER];
    unsigned cmd_dynamic[MAX_OP_NUMBER];
    unsigned cmd_static_loop[MAX_OP_NUMBER];
    unsigned cmd_static_loop_deepest[MAX_OP_NUMBER];
    unsigned cmd_static_not_loop[MAX_OP_NUMBER];
    unsigned cmd_dynamic_loop_deepest[MAX_OP_NUMBER];
    unsigned cmd_dynamic_loop[MAX_OP_NUMBER];
    unsigned cmd_dynamic_not_loop[MAX_OP_NUMBER];
    unsigned cmd_static_mv0[MAX_OP_NUMBER];
    unsigned cmd_static_mv1[MAX_OP_NUMBER];
    unsigned cmd_static_mv2[MAX_OP_NUMBER];
    unsigned cmd_dynamic_mv0[MAX_OP_NUMBER];
    unsigned cmd_dynamic_mv1[MAX_OP_NUMBER];
    unsigned cmd_dynamic_mv2[MAX_OP_NUMBER];
    unsigned memory_access[MO_last][MB_NUM];
    unsigned move_cmd[RGM_MOVE_NUM];
    unsigned address_mode[MAX_AM_GROUPS][AM_LAST_MODE];
};

/************************************************************
 * Type:  PROGRAM
 *
 * Purpose:
 *   This is the complete data structure 
 *
 * Members:
 * 
 *    instruction_tree - 
 *                     Tree whose nodes are all instructions 
 *                     (P space addresses) which were defined in the COFF or
 *                     executed during the run (sorted by addresses)
 *
 *    data_tree      - Tree whose nodes are all data addresses (X/Y space)
 *                     which were defined in the COFF or read/written during
 *                     program execution (sorted by space:address)
 *               
 *    symbol_tree    - Tree whose elements are all symbols defined in COFF
 * 
 *    reg_access     - Array of register access lists 
 *
 *    data_ring      - Ring of last READ_RING_SIZE locations read. 
 *                     used when trying to decide overlays.
 *    read_ring_top  - Current position in ring
 * 
 *    source_file    - Name of the user's assembly file 
 *    result_file    - Name of the user's result file 
 *    object_file    - Name of the executable file 
 *    object_date    - Time when executable was created 
 * 
 *    report_info    - General profiling information 
 *    err            - error bit field
 *    start          - Address where execution actually started 
 *    current_cycle  - Number of cycles executed so far 
 *    mem_anchor     - Handle for memory allocations 
 *    temp_mem       - MEM ALLOC flag 
 *                     (when FALSE - memory is allocated through the handle)
 *    cc_expand      - Code coverage expansion limit (-1 = flat) 
 *    sections       - Number of COFF sections 
 *    section_names  - Array of COFF section names 
 *    section_files  - Array of file names belonging to the COFF sections
 *    sub            - Subroutine information 
 *    state          - Profiling state
 ************************************************************/
struct PROGRAM
{
    DSP_ADDR start;		/* Start address */

    struct TREE *data_tree;
    struct TREE *instruction_tree;
    struct TREE *symbol_tree;

    struct LINK *reg_access;
    struct
    {
	ADDRESS_SPACE sp;
	DSP_ADDR addr;
    }
    data_ring[READ_RING_SIZE];
    int read_ring_top;

    char *source_file;
    char *result_file;
    char *object_file;
    time_t object_date;
    char *write_mode;

    struct PROFILE_INFO report_info;
    struct ERR_VECTOR err;
    unsigned long current_cycle;
    struct CALLOC mem_anchor;
    BOOL temp_mem;
    int cc_expand;
    int sections;
    char **section_names;
    char **section_files;
    struct SUBROUTINES sub;
    enum
    {
	PROF_DEAD, PROF_INERT, PROF_READY, PROF_GO, PROF_ABORTED
    }
    state;
};
