/* asm.h - global header file */
#pragma warning(disable:4057)
#pragma warning(disable:4244)

#ifndef asmH
#define asmH			/* Don't declare things twice. */

#include <stdio.h>
#include <ctype.h>
//#include <assert.h>
#include <time.h>
#ifndef __PTR_TO_INT
#define __PTR_TO_INT(P) ((P) - (char *)0)
#endif

#ifndef __INT_TO_PTR
#define __INT_TO_PTR(P) ((P) + (char *)0)
#endif
extern int atoi(char *);
extern void qsort(void *,int,int,int(*compare)(void *,void *));
#define index strchr
struct _obstack_chunk		/* Lives at front of each chunk. */
{
  char  *limit;			/* 1 past end of this chunk */
  struct _obstack_chunk *prev;	/* address of prior chunk or NULL */
  char	contents[4];		/* objects begin here */
};

struct obstack		/* control current object in current chunk */
{
  long	chunk_size;		/* preferred size to allocate chunks in */
  struct _obstack_chunk* chunk;	/* address of current struct obstack_chunk */
  char	*object_base;		/* address of object we are building */
  char	*next_free;		/* where to add next char to current object */
  char	*chunk_limit;		/* address of char after current chunk */
  int	temp;			/* Temporary for some macros.  */
  int   alignment_mask;		/* Mask of alignment for each object. */
  struct _obstack_chunk *(*chunkfun) (int); /* User's fcn to allocate a chunk.  */
  void (*freefun) (void *);		/* User's function to free a chunk.  */
};


/* Do the function-declarations after the structs
   but before defining the macros.  */

void obstack_init (struct obstack *obstack);

void * obstack_alloc (struct obstack *obstack, int size);

void * obstack_copy (struct obstack *obstack, void *address, int size);
void * obstack_copy0 (struct obstack *obstack, void *address, int size);

static void obstack_free (struct obstack *obstack, void *block);

void obstack_blank (struct obstack *obstack, int size);

void obstack_grow (struct obstack *obstack, void *data, int size);
void obstack_grow0 (struct obstack *obstack, void *data, int size);

void obstack_1grow (struct obstack *obstack, int data_char);
void obstack_ptr_grow (struct obstack *obstack, void *data);
void obstack_int_grow (struct obstack *obstack, int data);

void * obstack_finish (struct obstack *obstack);

int obstack_object_size (struct obstack *obstack);

int obstack_room (struct obstack *obstack);
void obstack_1grow_fast (struct obstack *obstack, int data_char);
void obstack_ptr_grow_fast (struct obstack *obstack, void *data);
void obstack_int_grow_fast (struct obstack *obstack, int data);
void obstack_blank_fast (struct obstack *obstack, int size);

void * obstack_base (struct obstack *obstack);
void * obstack_next_free (struct obstack *obstack);
int obstack_alignment_mask (struct obstack *obstack);
int obstack_chunk_size (struct obstack *obstack);


/* Non-ANSI C cannot really support alternative functions for these macros,
   so we do not declare them.  */

/* Pointer to beginning of object being allocated or to be allocated next.
   Note that this might not be the final address of the object
   because a new chunk might be needed to hold the final size.  */

#define obstack_base(h) ((h)->object_base)

/* Size for allocating ordinary chunks.  */

#define obstack_chunk_size(h) ((h)->chunk_size)

/* Pointer to next byte not yet allocated in current chunk.  */

#define obstack_next_free(h)	((h)->next_free)

/* Mask specifying low bits that should be clear in address of an object.  */

#define obstack_alignment_mask(h) ((h)->alignment_mask)

#define obstack_init(h) \
  _obstack_begin ((h), 0, 0, \
		  (void *(*) (int)) obstack_chunk_alloc, obstack_chunk_free)

#define obstack_begin(h, size) \
  _obstack_begin ((h), (size), 0, \
		  (void *(*) (int)) obstack_chunk_alloc, obstack_chunk_free)

#define obstack_1grow_fast(h,achar) (*((h)->next_free)++ = achar)

#define obstack_blank_fast(h,n) ((h)->next_free += (n))

#define obstack_room(h)		\
 (unsigned) ((h)->chunk_limit - (h)->next_free)

#define obstack_grow(h,where,length)					\
( (h)->temp = (length),							\
  (((h)->next_free + (h)->temp > (h)->chunk_limit)			\
   ? (_obstack_newchunk ((h), (h)->temp), 0) : 0),			\
  bcopy (where, (h)->next_free, (h)->temp),				\
  (h)->next_free += (h)->temp)

#define obstack_1grow(h,datum)						\
( (((h)->next_free + 1 > (h)->chunk_limit)				\
   ? (_obstack_newchunk ((h), 1), 0) : 0),				\
  *((h)->next_free)++ = (datum))

#define obstack_ptr_grow_fast(h,aptr) (*((char **)(h)->next_free)++ = (char *)aptr)
#define obstack_int_grow_fast(h,aint) (*((int *)(h)->next_free)++ = (int)aint)

#define obstack_blank(h,length)						\
( (h)->temp = (length),							\
  (((h)->chunk_limit - (h)->next_free < (h)->temp)			\
   ? (_obstack_newchunk ((h), (h)->temp), 0) : 0),			\
  (h)->next_free += (h)->temp)

#define obstack_alloc(h,length)						\
 (obstack_blank ((h), (length)), obstack_finish ((h)))

#define obstack_copy(h,where,length)					\
 (obstack_grow ((h), (where), (length)), obstack_finish ((h)))

#define obstack_finish(h)  						\
( (h)->temp = __PTR_TO_INT ((h)->object_base),				\
  (h)->next_free							\
    = __INT_TO_PTR ((__PTR_TO_INT ((h)->next_free)+(h)->alignment_mask)	\
		    & ~ ((h)->alignment_mask)),				\
  (((h)->next_free - (char *)(h)->chunk					\
    > (h)->chunk_limit - (char *)(h)->chunk)				\
   ? ((h)->next_free = (h)->chunk_limit) : 0),				\
  (h)->object_base = (h)->next_free,					\
  __INT_TO_PTR ((h)->temp))

#define bcopy(from,to,n) memcpy((to),(from),(n))
#define obstack_chunk_alloc	xmalloc
#define obstack_chunk_free	free

/* These defines are potentially useful */
#define FALSE	(0)
#define TRUE	(!FALSE)
#define ASSERT	assert


#ifdef SUSPECT
#define register		/* no registers: helps debugging */
#define know(p) ASSERT(p)	/* know() is less ugly than #ifdef SUSPECT/ */
				/* assert()/#endif. */
#else
#define know(p)			/* know() checks are no-op.ed */
#endif				/* #ifdef SUSPECT */

/* subsegs.c     Sub-segments. Also, segment(=expression type)s.*/
/*
 * This table describes the use of segments as EXPRESSION types.
 *
 *	X_seg	X_add_symbol  X_subtract_symbol	X_add_number
 * SEG_NONE						no (legal) expression
 * SEG_PASS1						no (defined) "
 * SEG_BIG					*	> 32 bits const.
 * SEG_ABSOLUTE				     	0
 * SEG_DATA		*		     	0
 * SEG_TEXT		*			0
 * SEG_BSS		*			0
 * SEG_UNKNOWN		*			0
 * SEG_DIFFERENCE	0		*	0
 *
 * The blank fields MUST be 0, and are nugatory.
 * The '0' fields MAY be 0. The '*' fields MAY NOT be 0.
 *
 * SEG_BIG: X_add_number is < 0 if the result is in
 *	generic_floating_point_number.  The value is -'c' where c is the
 *	character that introduced the constant.  e.g. "0f6.9" will have  -'f'
 *	as a X_add_number value.
 *	X_add_number > 0 is a count of how many littlenums it took to
 *	represent a bignum.
 * SEG_DIFFERENCE:
 * If segments of both symbols are known, they are the same segment.
 * X_add_symbol != X_sub_symbol (then we just cancel them, => SEG_ABSOLUTE).
 */

typedef enum
{
	SEG_ABSOLUTE,
	SEG_TEXT,
	SEG_DATA,
	SEG_BSS,
	SEG_UNKNOWN,
	SEG_NONE,		/* Mythical Segment: NO expression seen. */
	SEG_PASS1,		/* Mythical Segment: Need another pass. */
	SEG_GOOF,		/* Only happens if AS has a logic error. */
				/* Invented so we don't crash printing */
				/* error message involving weird segment. */
	SEG_BIG,			/* Bigger than 32 bits constant. */
	SEG_DIFFERENCE		/* Mythical Segment: absolute difference. */
}		segT;
#define SEG_MAXIMUM_ORDINAL (SEG_DIFFERENCE)

typedef unsigned char	subsegT;

typedef enum
{
	rs_fill,		/* Variable chars to be repeated fr_offset */
				/* times. Fr_symbol unused. */
				/* Used with fr_offset == 0 for a constant */
				/* length frag. */

	rs_align,		/* Align: Fr_offset: power of 2. */
				/* 1 variable char: fill character. */
	rs_org,			/* Org: Fr_offset, fr_symbol: address. */
				/* 1 variable char: fill character. */

	rs_machine_dependent,
}
relax_stateT;

typedef unsigned long int relax_substateT;

typedef unsigned long int relax_addressT;/* Enough bits for address. */
				/* Still an integer type. */

/* subsegs.h -> subsegs.c
 * For every sub-segment the user mentions in the ASsembler program,
 * we make one struct frchain. Each sub-segment has exactly one struct frchain
 * and vice versa.
 *
 * Struct frchain's are forward chained (in ascending order of sub-segment
 * code number). The chain runs through frch_next of each subsegment.
 * This makes it hard to find a subsegment's frags
 * if programmer uses a lot of them. Most programs only use text0 and
 * data0, so they don't suffer. At least this way:
 * (1)	There are no "arbitrary" restrictions on how many subsegments
 *	can be programmed;
 * (2)	Subsegments' frchain-s are (later) chained together in the order in
 *	which they are emitted for object file viz text then data.
 *
 * From each struct frchain dangles a chain of struct frags. The frags
 * represent code fragments, for that sub-segment, forward chained.
 */

struct frchain			/* control building of a frag chain */
{				/* FRCH = FRagment CHain control */
  struct frag *	frch_root;	/* 1st struct frag in chain, or NULL */
  struct frag *	frch_last;	/* last struct frag in chain, or NULL */
  struct frchain * frch_next;	/* next in chain of struct frchain-s */
  segT		frch_seg;	/* SEG_TEXT or SEG_DATA. */
  subsegT	frch_subseg;	/* subsegment number of this chain */
};

typedef struct frchain frchainS;
/*
 * A code fragment (frag) is some known number of chars, followed by some
 * unknown number of chars. Typically the unknown number of chars is an
 * instruction address whose size is yet unknown. We always know the greatest
 * possible size the unknown number of chars may become, and reserve that
 * much room at the end of the frag.
 * Once created, frags do not change address during assembly.
 * We chain the frags in (a) forward-linked list(s). The object-file address
 * of the 1st char of a frag is generally not known until after relax().
 * Many things at assembly time describe an address by {object-file-address
 * of a particular frag}+offset.

 BUG: it may be smarter to have a single pointer off to various different
notes for different frag kinds. See how code pans out.
 */
struct frag			/* a code fragment */
{
	long unsigned int fr_address; /* Object file address. */
	struct frag *fr_next;	/* Chain forward; ascending address order. */
				/* Rooted in frch_root. */

	long int fr_fix;	/* (Fixed) number of chars we know we have. */
				/* May be 0. */
	long int fr_var;	/* (Variable) number of chars after above. */
				/* May be 0. */
	struct AsmSymbol *fr_symbol; /* For variable-length tail. */
	long int fr_offset;	/* For variable-length tail. */
	char	*fr_opcode;	/*->opcode low addr byte,for relax()ation*/
	relax_stateT fr_type;   /* What state is my tail in? */
	relax_substateT	fr_subtype;
	char	fr_literal [1];	/* Chars begin here. */
				/* One day we will compile fr_literal[0]. */
};
#define SIZEOF_STRUCT_FRAG \
 ((int)zero_address_frag.fr_literal-(int)&zero_address_frag)
				/* We want to say fr_literal[0] above. */

typedef struct frag fragS;

#define N_UNDF 0
#define N_ABS 2
#define N_TEXT 4
#define N_DATA 6
#define N_BSS 8
#define N_FN 15

#define N_EXT 1
#define N_TYPE 036
#define N_STAB 0340
struct relocation_info
{
  /* Address (within segment) to be relocated.  */
  int r_address;
  unsigned int r_pcrel:1;
};

struct AsmSymbol
{
  struct AsmSymbol 		*Next;		/* forward chain, or NULL */
  char					*Name;
  unsigned long 		SymbolValue;
  struct frag			*sy_frag;	/* NULL or -> frag this symbol attaches to. */
  struct AsmSymbol 		*sy_forward;/* value is really that of this other symbol */
  int					SectionNumber;
  int					Type;
  int					StorageClass;
  int					NumberOfAuxSymbols;
  int					OrdinalNumber;
  int					StartLine;
  int					EndLine;
  int					Flags;
  struct tagCoffReloc 	*Relocations;
  struct tagCoffLine 	*Lines;
  struct tagCoffFn 		*FnInfo;
  unsigned char 		sy_type;
};

typedef struct AsmSymbol symbolS;

typedef unsigned valueT;	/* The type of n_value. Helps casting. */

typedef struct {
  char *	poc_name;	/* assembler mnemonic, lower case, no '.' */
  void		(*poc_handler)(void);	/* Do the work */
}
pseudo_typeS;

typedef struct
{
	long	rlx_forward;	/* Forward  reach. Signed number. > 0. */
	long	rlx_backward;	/* Backward reach. Signed number. < 0. */
	unsigned char rlx_length;	/* Bytes length of this address. */
	relax_substateT rlx_more;	/* Next longer relax-state. */
				/* 0 means there is no 'next' relax-state. */
}
relax_typeS;


/*
 * FixSs may be built up in any order.
 */

struct fix
{
  struct fix   *fx_next;	/* NULL or -> next fixS. */
  fragS  	   *fx_frag;	/* Which frag? */
  long int		fx_where;	/* Where is the 1st byte to fix up? */
  symbolS      *fx_addsy; /* NULL or Symbol whose value we add in. */
  symbolS      *fx_subsy; /* NULL or Symbol whose value we subtract. */
  long int		fx_offset;	/* Absolute number we add in. */
  short int		fx_size;	/* How many bytes are involved? */
  char			fx_pcrel;	/* TRUE: pc-relative. */
  struct        tagCoffReloc *CoffReloc;
};

typedef struct fix	fixS;

struct HASH_LIST {
	struct HASH_LIST *Next;
	char *Name;
	char *Data;
	short len;
};

typedef struct tagCoffReloc {
	struct tagCoffReloc *Next;
	int       Offset;
	symbolS *Symbol;
	fixS *pfixS;
	int Flags;
	short int Type;
	int TargetSegment;
} COFF_RELOC;

typedef struct tagCoffFn {
	int Tag;
	int Size;
	int NrOfLines;
	symbolS *Start;
	symbolS *End;
	int LineNumbersFileOffset;
	int NextFnIdx;
} COFF_FN;

typedef struct tagCoffLine {
	struct tagCoffLine *Next;
	fragS *Frag;
	int Line;
	int fragOffset;
} COFF_LINE;

#define IS_PCRELATIVE 1
#define IS_TEXT       2
#define IS_DATA       4
#define IS_BSS        8
#define IS_FUNCTION	  16
#define COUNTED		  32

#define SECTION_TEXT	1
#define SECTION_DATA	2
#define SECTION_BSS		3

typedef struct tagString {
	struct tagString *Next;
	int len;
	char *String;
} STRING;

typedef struct tagStringTable {
	int Size;
	STRING *Strings;
} STRING_TABLE;

/*
 * A macro to speed up appending exactly 1 char
 * to current frag.
 */
#define FRAG_APPEND_1_CHAR(datum)	\
{					\
	if (obstack_room( &frags ) <= 1) {\
		frag_wane (frag_now);	\
		frag_new (0);		\
	}				\
	obstack_1grow( &frags, datum );	\
}
#define hash_control HASH_LIST

#define symbol_table_lookup(name) ((symbolS *)(hash_find (sy_hash,name)))

/*#define SKIP_WHITESPACE() ASSERT( * InputPointer != ' ' )*/
#define SKIP_WHITESPACE() while (*InputPointer == ' ' || *InputPointer == '\t') InputPointer++;
#define	LEX_NAME	(1)	/* may continue a name */
#define LEX_BEGIN_NAME	(2)	/* may begin a name */

#define is_name_beginner(c)     ( lex_type[c] & LEX_BEGIN_NAME )
#define is_part_of_name(c)      ( lex_type[c] & LEX_NAME       )

/*
 * Abbreviations (mnemonics).
 *
 *	O	operator
 *	Q	quantity,  operand
 *	X	eXpression
  * By popular demand, we define a struct to represent an expression.
 * This will no doubt mutate as expressions become baroque.
 *
 * Currently, we support expressions like "foo-bar+42".
 * In other words we permit a (possibly undefined) minuend, a
 * (possibly undefined) subtrahend and an (absolute) augend.
 * RMS says this is so we can have 1-pass assembly for any compiler
 * emmissions, and a 'case' statement might emit 'undefined1 - undefined2'.
 *
 * To simplify table-driven dispatch, we also have a "segment" for the
 * entire expression. That way we don't require complex reasoning about
 * whether particular components are defined; and we can change component
 * semantics without re-working all the dispatch tables in the assembler.
 * In other words the "type" of an expression is its segment.
 */
typedef struct
{
	symbolS *X_add_symbol;		/* foo */
	symbolS *X_subtract_symbol;	/* bar */
	long int X_add_number;		/* 42.    Must be signed. */
	segT	X_seg;			/* What segment (expr type)? */
}
expressionS;

typedef struct tagNewSection {
	struct tagNewSection *Next;
	char Name[10];
	int HeaderPosition;
	int Number;
	int DataSize;
	char *data;
} NewSection;

				/* result should be type (expressionS *). */
#define expression(result) AsmExpression(0,result)

#endif				/* #ifdef asH */


