home *** CD-ROM | disk | FTP | other *** search
- /* 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)(const void *,const 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 */
-
-
-