/*
 * gencode.h  -  Definitions for code generator
 *
 * Copyright (C) 1997-2003 Gero Kuhlmann   <gero@gkminix.han.de>
 *
 *  This program 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 2 of the License, or
 *  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, write to the Free Software
 *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 *
 * $Id: gencode.h,v 1.4 2003/01/25 23:29:44 gkminix Exp $
 */


/*
 * When dealing with variables we have to consider the following cases:
 *
 *	1.) the variable is somewhere in memory, and addressed by:
 *		- absolute
 *		- relative to the current stack frame (BP) or another register
 *		- relative to an older stack frame
 *	2.) in a register for passing to another level of expression handling
 *
 * The following structure holds this information in terms of absolute/relative
 * addresses and the registers to be used. This includes the size information
 * for non-scalars. If the variable is a string, we consider the temporary
 * strings area at the beginning of the data segment a "register". Other
 * non-scalars cannot be represented as a register, so case 2.) doesn't apply.
 */
#define MEM_ADR_MASK	0x000f		/* mask for address field */
#define MEM_NOADDR	0x0000		/* expression doesn't return a result */
#define MEM_ABSOLUTE	0x0001		/* use address field */
#define MEM_RELATIVE	0x0002		/* use address and register field */
#define MEM_REGISTER	0x0003		/* use register field */

#define MEM_SIZE_MASK	0x00f0		/* mask for size field */
#define MEM_NOSIZE	0x0000		/* size field not used */
#define MEM_IMMEDIATE	0x0010		/* use immediate value for size */
#define MEM_SIZEREG	0x0020		/* use register for size */

#define MEM_RELOC_FLAG	0x0100		/* the immediate address is static */

struct memval {
	addr_t i;		/* immediate value */
	unsigned int r;		/* register identifier */
};

struct meminfo {
	int memtype;
	struct memval addr;	/* Adress of variable */
	struct memval size;	/* Size of variable */
	struct typesdef *t;	/* Type which made up this meminfo record */
};



/*
 * General memory layout
 */
#define STACKSIZE	4096
#define CODESIZE	65535
#define DATASIZE	65535
#define CONSTSIZE	(DATASIZE - STACKSIZE)
#define RELOCSIZE	(CODESIZE / 2)
#define DEBUGSIZE	(CODESIZE / 4)



/*
 * Definition of offsets into runtime module
 */
#define DATAOFS		0x0008
#define STARTOFS	DATAOFS + 0		/* Offset of start address */
#define CODESIZEOFS	DATAOFS + 2		/* Size of code segment */
#define CONSTSIZEOFS	DATAOFS + 4		/* Size of constant data */
#define DATASIZEOFS	DATAOFS + 6		/* Size of variable data */
#define DEBUGOFS	DATAOFS + 8		/* Offset of debugging table */
#define ENTRYOFS	DATAOFS + 10		/* Offset to runtime entry */



/*
 * Function codes for runtime module. The directly callable
 * internal functions have the same code as for the parser-code-
 * generator interface (see CMD_* in file mgl.h).
 */
#define FUNC_sprint	0x00		/* Print string data */
#define FUNC_iprint	0x01		/* Print integer data */
#define FUNC_cprint	0x02		/* Print character data */
#define FUNC_sget	0x03		/* Get string data */
#define FUNC_iget	0x04		/* Get integer data */
#define FUNC_cget	0x05		/* Get character data */
#define FUNC_getsel	0x06		/* Get a character for select */
#define FUNC_load	0x07		/* Load new bootimage */



/*
 * Define which registers are presently used
 */
extern int si_inuse;			/* SI register is in use */
extern int di_inuse;			/* DI register is in use */
extern int bx_inuse;			/* BX register is in use */
extern int cx_inuse;			/* CX register is in use */
extern int dx_inuse;			/* DX register is in use */



/*
 * External variables
 */
extern addr_t dataptr;				/* Current data pointer */
extern addr_t constptr;				/* Current constant pointer */
extern addr_t codeptr;				/* Current code pointer */
extern addr_t startadr;				/* Start address */
extern __u8 runtime_data[];			/* Runtime code buffer */
extern unsigned int runtime_data_size;		/* Size of runtime code */



/*
 * External routines in module: gencode.c
 */
extern void putcode __P((unsigned int c));
extern void putconst __P((unsigned int c));
extern addr_t putstring __P((char *str));
extern void putint __P((long val));
extern void setreloc __P((void));
extern void putjmp __P((addr_t dest, unsigned int jmpcode));
extern void putimmed __P((unsigned int op,
			unsigned int reg, long val, addr_t disp));
extern void putregop __P((unsigned int op,
			unsigned int srcreg, unsigned int destreg, addr_t disp));
extern void putlea __P((unsigned int destreg, unsigned int basereg, addr_t disp));
extern void putstackreg __P((unsigned int reg, int push, addr_t disp));
extern void putfunc __P((int func, addr_t stack));
extern void putbound __P((unsigned int srcreg, struct typesdef *tp));
extern void putsetbit __P((unsigned int reg, unsigned int cond));
extern unsigned int getmodrm __P((unsigned int basereg, addr_t disp));
extern void setmeminfo __P((struct expr *ep, struct meminfo *dp,
				unsigned int basereg, unsigned int sizereg));

#define putpush(reg)	putstackreg((reg), TRUE, 0);
#define putpop(reg)	putstackreg((reg), FALSE, 0);



/*
 * External routines in module: genexpr.c
 */
extern void putsaveintreg __P((unsigned int srcreg, struct meminfo *dp));
extern void putintexpr __P((struct expr *ep, struct meminfo *dp));
extern void putcharexpr __P((struct expr *ep, struct meminfo *dp));
extern void putboolexpr __P((struct expr *ep, struct meminfo *dp));
extern void putstrexpr __P((struct expr *ep, struct meminfo *dp, int rec));
extern void putcomplexexpr __P((struct expr *ep, struct meminfo *dp));
extern void putproc __P((struct expr *ep, struct meminfo *dp));



syntax highlighted by Code2HTML, v. 0.9.1