view lwasm/lwasm.h @ 159:71561c12b20b

Updated docs to reflect new cescapes pragma and discuss implicit assumption of the bss section flag for sections named bss and .bss
author lost
date Sat, 31 Jan 2009 06:32:27 +0000
parents 427e268e876b
children b061350c17e4
line wrap: on
line source

/*
lwasm.h
Copyright © 2008 William Astle

This file is part of LWASM.

LWASM is free software: you can redistribute it and/or modify it under the
terms of the GNU General Public License as published by the Free Software
Foundation, either version 3 of the License, or (at your option) any later
version.

This program is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
more details.

You should have received a copy of the GNU General Public License along with
this program. If not, see <http://www.gnu.org/licenses/>.

Contains the main defs used by the assembler
*/


#ifndef __lwasm_h_seen__
#define __lwasm_h_seen__

#include <stdio.h>
#include "expr.h"

#define OUTPUT_DECB		0	// DECB multirecord format
#define OUTPUT_RAW		1	// raw sequence of bytes
#define OUTPUT_OBJ		2	// proprietary object file format
#define OUTPUT_RAWREL	3	// raw bytes where ORG causes a SEEK in the file

// structure for tracking sections
typedef struct section_reloc_list_s section_reloc_list_t;
struct section_reloc_list_s
{
	int offset;						// offset into section
	lwasm_expr_stack_t *expr;		// value definition
	int context;					// symbol context (for local syms)
	section_reloc_list_t *next;		// next relocation
};

typedef struct export_list_s export_list_t;
struct export_list_s
{
	int offset;						// offset of symbol
	char *sym;						// name of symbol
	export_list_t *next;			// next export	
};

#define SECTION_BSS		1	// the section contains no actual code - just uninit vars
typedef struct sectiontab_s sectiontab_t;
struct sectiontab_s
{
	char *name;				// name of the section
	int offset;				// current offset in the section
	int flags;				// section flags
	sectiontab_t *next;		// next section
	// the following are used during code output
	unsigned char *obytes;	// output bytes
	int oblen;				// how many bytes output so far?
	int obsize;				// how big is output buffer so far?
	section_reloc_list_t *rl;	// relocation list
	export_list_t *exports;	// export list for the section
};

// structure for tracking macros
typedef struct macrotab_s macrotab_t;
struct macrotab_s
{
	char *name;
	char **lines;
	int numlines;
	macrotab_t *next;
};

// structure for tracking errors
typedef struct lwasm_error_s lwasm_error_t;
struct lwasm_error_s
{
	char *mess;				// the actual error message
	lwasm_error_t *next;	// ptr to next error
};

// structure for keeping track of lines
// it also as space for 4 expressions which is enough for all known
// instructions and addressing modes
// on pass 1, the expressions are parsed, on pass 2 they are re-evaluated
// to determine constancy
typedef struct lwasm_line_s lwasm_line_t;
struct lwasm_line_s {
	char *text;			// the actual text of the line
	int lineno;			// line number within the file
	char *filename;		// file name reference
	lwasm_line_t *next;	// next line
	lwasm_line_t *prev;	// previous line
	lwasm_error_t *err;	// error messages
	int fsize;			// forced size (0 = no forced size)
	char *sym;			// scratch area to record the presence of a symbol
	unsigned char *bytes;	// actual bytes emitted
	int codelen;		// number of bytes emitted
	int codesize;		// the size of the code buffer
	int codeaddr;		// address the code goes at
	int nocodelen;		// for "RMB" type instructions
	int addrset;		// set if this instruction sets the assembly address
	int symaddr;		// set if this instruction sets a symbol addr with EQU or the like
	int badop;			// bad operation - ignore it
	int context;		// the symbol context for this line
	
	// the following are used for obj format - for external references, inter-section
	// references, and intrasection relocations
	int relocoff;		// offset into insn where relocation value goes
	lwasm_expr_stack_t *exprs[4];	// non-constant expression values
	int exprvals[4];	// constant expression values
	char *exprends[4];	// pointer to character after end of expression
	
	sectiontab_t *sect;	// which section is the line in?
};

// for keeping track of symbols
#define	SYMBOL_SET		1	// the symbol was used for "SET"
#define SYMBOL_COMPLEX	2	// register symbol as a complex symbol (from l -> expr)
#define SYMBOL_FORCE	4	// force resetting the symbol value if it already exists on pass 2
#define SYMBOL_NORM		0	// no flags
#define SYMBOL_EXTERN	8	// the symbol is an external reference
typedef struct lwasm_symbol_ent_s lwasm_symbol_ent_t;
struct lwasm_symbol_ent_s
{
	char *sym;					// the symbol
	int context;				// the context number of the symbol (-1 for global)
	int value;					// the value of the symbol
	int flags;					// flags for the symbol
	char *externalname;			// for external references that are aliased locally
	sectiontab_t *sect;			// the section the symbol exists in; NULL for none
	lwasm_expr_stack_t *expr;	// expression for a symbol that is not constant NULL for const
	lwasm_symbol_ent_t *next;	// next symbol in the table
	lwasm_symbol_ent_t *prev;	// previous symbol in the table
};

// keep track of current assembler state
typedef struct {
	int dpval;					// current dp value (setdp)
	int addr;					// current address
	int context;				// context counter (for local symbols)
	int errorcount;				// error count
	int passnum;				// which pass are we on?
	int execaddr;				// execution address for the program (END ....)
	int pragmas;				// what pragmas are in effect?

	lwasm_line_t *lineshead;	// first line of source code
	lwasm_line_t *linestail;	// last line of source code
	
	lwasm_symbol_ent_t *symhead;	// first entry in symbol table
	lwasm_symbol_ent_t *symtail;	// last entry in symbol table
	
	macrotab_t *macros;			// macro table

	const char *infile;			// input file
	const char *outfile;		// output file
	const char *listfile;		// output listing file
	int outformat;				// output format type
	char **filelist;			// files that have been read
	int filelistlen;			// number of files in the list
	
	int endseen;				// set to true if "end" has been seen
	int skipcond;				// skipping a condition?
	int skipcount;				// how many?
	int skipmacro;				// skipping a macro?
	int inmacro;				// are we currently in a macro?
	int macroex;				// current depth of macro expansion
	int nextcontext;			// next context number
	int skiplines;				// number of lines to skip
	
	// items used only for the "object" target
	sectiontab_t *sections;		// pointer to section table
	sectiontab_t *csect;		// current section - NULL if not in one
} asmstate_t;

// do not rewrite XXX,r to ,r if XXX evaluates to 0
#define PRAGMA_NOINDEX0TONONE	1
// any undefined symbols are considered external
#define PRAGMA_UNDEFEXTERN	2

#ifndef __lwasm_c_seen__
#define __lwasm_E__ extern
#else
#define __lwasm_E__
#endif

__lwasm_E__ int debug_level;

__lwasm_E__ int register_error(asmstate_t *as, lwasm_line_t *l, int pass, const char *fmt, ...);
__lwasm_E__ void debug_message(int level, const char *fmt, ...);

__lwasm_E__ void lwasm_emit(asmstate_t *as, lwasm_line_t *l, int b);
__lwasm_E__ void lwasm_emitop(asmstate_t *as, lwasm_line_t *l, int o);
__lwasm_E__ int lwasm_lookupreg2(const char *reglist, char **str);
__lwasm_E__ int lwasm_lookupreg3(const char *rlist, const char **str);

__lwasm_E__ lwasm_expr_stack_t *lwasm_evaluate_expr(asmstate_t *as, lwasm_line_t *l, const char *inp, const char **outp, int flags);


// return next context number and update it
__lwasm_E__ int lwasm_next_context(asmstate_t *as);

// also throw an error on expression eval failure
// return 0 on ok, -1 on error, 1 if a complex expression was returned
#define EXPR_NOFLAG			0
#define EXPR_PASS1CONST		1	// no forward references on pass 1
#define EXPR_SECTCONST		2	// resolve symbols local to section
#define EXPR_REEVAL			4	// re-evaluate the expression
__lwasm_E__ int lwasm_expr_result(asmstate_t *as, lwasm_line_t *l, char **inp, int flag, int *val);
__lwasm_E__ int lwasm_expr_result2(asmstate_t *as, lwasm_line_t *l, char **inp, int flag, int *val, int slot);

#undef __lwasm_E__


#ifndef __symbol_c_seen__
#define __lwasm_E__ extern
#else
#define __lwasm_E__
#endif

__lwasm_E__ int lwasm_register_symbol(asmstate_t *as, lwasm_line_t *l, char *sym, int val, int flags);
__lwasm_E__ lwasm_symbol_ent_t *lwasm_find_symbol(asmstate_t *as, char *sym, int scontext);
__lwasm_E__ int lwasm_set_symbol(asmstate_t *as, char *sym, int scontext, int val);
__lwasm_E__ void lwasm_list_symbols(asmstate_t *as, FILE *f);
#undef __lwasm_E__



#endif //__lwasm_h_seen__