view lwasm/lwasm.h @ 185:b89adfb0d174

Added support for outputting a linkmap
author lost
date Sat, 21 Mar 2009 19:47:45 +0000
parents b061350c17e4
children 563adfccb645
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
// allow C-style escapes in fcc, fcs, and fcn directives
#define PRAGMA_CESCAPES			4

#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__