⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 genx86.h

📁 一款拥有一定历史的C语言编译器
💻 H
字号:
/*
 * C compiler
 * ==========
 *
 * Copyright 1989, 1990, 1991 Christoph van Wuellen.
 * Credits to Matthew Brandt.
 * All commercial rights reserved.
 *
 * This compiler may be redistributed as long there is no
 * commercial interest. The compiler must not be redistributed
 * without its full sources. This notice must stay intact.
 *
 * History:
 *
 * 1989   starting an 68000 C compiler, starting with material
 *        originally by M. Brandt
 * 1990   68000 C compiler further bug fixes
 *        started i386 port (December)
 * 1991   i386 port finished (January)
 *        further corrections in the front end and in the 68000
 *        code generator.
 *        The next port will be a SPARC port
 */

#ifndef _GENX86_H
#define _GENX86_H

typedef unsigned int FLAGS;

#define	F_NONE	((FLAGS) 0U)
#define	F_DREG	((FLAGS) 1U)	/* a data register, like %eax, %edx etc. */
#define	F_AREG	((FLAGS) 2U)	/* an address  register, like %esi, %edi */
#define	F_MEM	((FLAGS) 4U)	/* direct, indirect, indexed */
#define	F_IMMED	((FLAGS) 8U)	/* immediate */
#define	F_FREG	((FLAGS) 16U)	/* top of floating-point stack */
#define	F_NOVALUE ((FLAGS) 32U)	/* dont need result value */
#define	F_VOL	((FLAGS) 64U)	/* need value in scratch register */
#define	F_NOEDI	((FLAGS) 128U)	/* do not use %edi and %esi */
#define	F_NOECX	((FLAGS) 256U)	/* do not use %exc */
#define	F_EAXEDX ((FLAGS) 512U)	/* result needed in %eax */
#define	F_ECX	((FLAGS) 1024U)	/* use %ecx if a register is needed */

#define F_ALL	((FLAGS)(F_DREG | F_AREG | F_MEM | F_IMMED | F_FREG))	/* any mode */

/*
 *   The 80X86 OP codes.  This table does not contain all the OP codes
 *   supported by the 80X86 but only those which the compiler
 *   generates.
 */
enum e_op
{
    op_movsbl,
    op_movzbl,
    op_movswl,
    op_movzwl,
    op_movsbw,
    op_movzbw,
    op_cdq,
    op_cwd,
    op_cbw,
    op_mov,
    op_xchg,
    op_lea,
    op_not,
    op_neg,
    op_add,
    op_sub,
    op_adc,
    op_sbb,
    op_imul,
    op_idiv,
    op_div,
    op_and,
    op_or,
    op_xor,
    op_inc,
    op_dec,
    op_cmp,
    op_push,
    op_pop,
    op_jmp,
    op_loop,
    op_call,
    op_leave,
    op_enter,
    op_ret,
    op_test,
    op_bra,
    op_je,
    op_jne,
    op_jl,
    op_jle,
    op_jg,
    op_jge,
    op_ja,
    op_jae,
    op_jb,
    op_jbe,
    op_rep,
    op_smov,
    op_shl,
    op_shr,
    op_asl,
    op_asr,
    op_rol,
    op_ror,
    op_sahf,
    op_sete,
    op_setne,
    op_setb,
    op_setbe,
    op_seta,
    op_setae,
    op_setl,
    op_setle,
    op_setg,
    op_setge,
    op_nop,
#ifdef FLOAT_IEEE
    op_fadd,
    op_faddp,
    op_fsub,
    op_fsubp,
    op_fdiv,
    op_fdivp,
    op_fmul,
    op_fmulp,
    op_fsubr,
    op_fsubrp,
    op_fdivr,
    op_fdivrp,
    op_fld,
    op_fldz,
    op_fst,
    op_fstp,
    op_fpop,
    op_fild,
    op_fildl,
    op_fistp,
    op_fistpl,
    op_ftst,
    op_fchs,
    op_fcomp,
    op_fcompp,
    op_fnstsw,
    op_fwait,
#endif				/* FLOAT_IEEE */
#ifdef ASM
    op_asm,			/* pseudo OP code ... holds ASM string */
#endif				/* ASM */
    op_line,			/* pseudo OP code ... line number info */
    op_label			/* pseudo OP code ... label */
};

#define OP_MIN	op_movsbl
#define OP_MAX	op_label

/* addressing modes */
enum e_am
{
    am_dreg,			/* Rn */
    am_areg,			/* Rn */
    am_ind,			/* (Rn) */
    am_indx,			/* (disp,Rn) */
    am_indx2,			/* (disp,Rn,Rm) */
    am_direct,			/* (xxx) */
    am_immed,			/* #(data) */
    am_freg,			/* ST(n) */
    am_mreg,			/* Rn/Rm */
    am_str,			/* string */
    am_line			/* pseudo mode for line numbers */
};

#define	is_register_mode(mode)	((mode) == am_dreg || (mode) == am_areg || (mode) == am_mreg)

/* register naming, special registers */

#define EAX	((REG) 0)
#define EDX	((REG) 1)
#define ECX	((REG) 2)
#define EBX	((REG) 3)
#define ESI	((REG) 4)
#define EDI	((REG) 5)
#define ESP	((REG) 6)
#define EBP	((REG) 7)	/* frame pointer */
/* attention: same order as above */
#define	AX	((REG) 8)
#define DX	((REG) 9)
#define BX	((REG) 10)
#define CX	((REG) 11)
#define SI	((REG) 12)
#define DI	((REG) 13)
#define	SP	((REG) 14)
#define	BP	((REG) 15)
/* attention: same order as above */
#define AL	((REG) 16)
#define DL	((REG) 17)
#define BL	((REG) 18)
#define CL	((REG) 19)

#define	ST0	((REG) 20)
#define	ST1	((REG) 21)
#define	ST2	((REG) 22)
#define	ST3	((REG) 23)
#define	ST4	((REG) 24)
#define	ST5	((REG) 25)
#define	ST6	((REG) 26)
#define	ST7	((REG) 27)

#define	NUM_REGS	28	/* number of registers */

/*
 * The code generator does not distinguish between %eax, %ax, %al
 * because some assemblers want it strict, the real register names
 * are determined when the assembly instruction is PRINTED, e.g.
 * code generator produces movb junk,%eax,
 * assembly code printer prints movb junk,%al
 * The conversion is done by the following macros
 */
#define REG16(X) (((REG)(((int)X)-((int)EAX))+((int)AX)))
#define REG8(X)  (((REG)(((int)X)-((int)EAX))+((int)AL)))

#define NUMREG		((int)REG8(EBP))

#define STACKPTR	ESP	/* system stack pointer */
#define FRAMEPTR	EBP	/* frame pointer */
#define MAX_REG 	EBX	/* scratch registers: %eax..%edx */

#define	UNUSED		((DEEP)-1)	/* register stack entry unused */
#define	EMPTY		((DEEP)0)	/* register slot index */

/*
 *   Defines what the register can be used for
 */
#define	D_REG		((REGTYPE)1)	/* data register */
#define	A_REG		((REGTYPE)2)	/* address register */
#define	F_REG		((REGTYPE)4)	/* float register */
#define	T_REG		((REGTYPE)8)	/* temporary register */
#define	M_REG		((REGTYPE)16)	/* multiple data register */
#define	X_REG		((REGTYPE)32)	/* AX/DX register */
#define	Y_REG		((REGTYPE)64)	/* not AX/DX register */
#define	C_REG		((REGTYPE)128)	/* CX data register */
#define	is_data_register(r)		((regtypes[(int)r] & D_REG) != 0)
#define	is_address_register(r)		((regtypes[(int)r] & A_REG) != 0)
#define	is_float_register(r)		((regtypes[(int)r] & F_REG) != 0)
#define	is_data_or_address_register(r)	((regtypes[(int)r] & (D_REG | A_REG)) != 0)
#define	is_temporary_register(r)	((regtypes[(int)r] & T_REG) != 0)
#define	is_temporary_data_register(r)	((regtypes[(int)r] & (D_REG|T_REG)) == (D_REG|T_REG))
#define	is_temporary_address_register(r)	((regtypes[(int)r] & (A_REG|T_REG)) == (A_REG|T_REG))
typedef unsigned char REGTYPE;

#ifndef _CODE_DEFINED
#define _CODE_DEFINED
typedef struct ocode CODE;

#endif

/* instruction lengths */

enum ilength
{
    IL0 = 0,			/* no operands */
    IL1 = 1,			/* byte operands */
    IL2 = 2,			/* word operands */
    IL4 = 4,			/* double word operands / float operands */
    IL8 = 8,			/* long real */
    IL10 = 10			/* long double real */
};

#define	REGBIT(x)	(REGMASK)(1U << (int)x)

typedef enum e_am AMODE;	/* Addressing mode */
typedef struct amode ADDRESS;
typedef enum e_op OPCODE;
typedef enum ilength ILEN;
typedef unsigned int REGMASK;
typedef signed char DEEP;
typedef struct reglist REGLIST;

#define NIL_ADDRESS	((ADDRESS *) 0)
#define	NIL_CODE	((CODE *) 0)

/* stack optimisations */
#define	OPT_SAFE	0
#define	OPT_MINIMUM	1
#define	OPT_AVERAGE	2
#define	OPT_MAXIMUM	3


/* addressing mode structure */

struct amode
{
    AMODE   mode;		/* addressing mode */
    REG     preg;		/* primary register used in address */
    REG     sreg;		/* secondary register used in address */
    DEEP    deep;		/* position is "pushed" stack */
    union
    {
	EXPR   *offset;		/* expression used in address mode */
    } u;
};

/* output code structure */

struct ocode
{
    OPCODE  opcode;		/* opcode for this instruction */
    ILEN    length;		/* operand length of the instruction */
    ADDRESS *oper1;		/* first operand */
    ADDRESS *oper2;		/* second operand */
    CODE   *fwd;		/* next instruction */
    CODE   *back;		/* previous instruction */
};

struct reglist
{
    int     number;		/* number of registers in the list */
    REG    *reg;		/* register list */
};

/*
 *   The usage of registers is controlled by the information held
 *   within the following structure.
 */
struct reg_use
{
    REGLIST *parameter;		/* Registers used to pass parameters */
    REGLIST *save;		/* Registers saved by the function */
    REGLIST *result;		/* Registers used to return results */
};

#define BRANCH_COUNT	2	/* abandon branch optimisation if exceeded */

#define	PEEP_NONE		0
#define	PEEP_INSTRUCTION	0
#define	PEEP_JUMPS		1
#define	PEEP_FLOW		2
#define	PEEP_ALL		255
#define	is_peep_phase(l,x)	(((unsigned)l) & MEMBER(x))

#ifdef MULTIPLE_PROCESSORS
/*
 *   remap function names - it is necessary to change the names of
 *   functions if there are multiple code generators build into the
 *   compiler in order to prevent name clashes.
 *
 *   The following defines do the necessary renaming
 */
#define	checkstack		checkstackX86
#define	is_equal_address	is_equal_addressX86
#define	flush_peep		flush_peepX86
#define	freeop			freeopX86
#define	g_code			g_codeX86
#define	g_fcode			g_fcodeX86
#define	data_register		data_registerX86
#define	address_register	address_registerX86
#define	axdx_register		axdx_registerX86
#define	cx_register		cx_registerX86
#define	float_register		float_registerX86
#define	get_mregister		get_mregisterX86
#define	initstack		initstackX86
#define	is_register_used	is_register_usedX86
#define	mk_immed		mk_immedX86
#define	mk_label		mk_labelX86
#define	mk_reg			mk_regX86
#define	mk_mreg			mk_mregX86
#define	temp_inv		temp_invX86
#define	uses_temp		uses_tempX86
#define	validate		validateX86
#define	max_reg			max_regX86
#define	regtypes		regtypesX86
#define	reg_usage		reg_usageX86
#define	reglist_to_mask		reglist_to_maskX86
#endif /* MULTIPLE_PROCESSORS */

extern REGUSAGE *reg_usage;	/* register usage */
extern REGTYPE *regtypes;	/* register types */

/* gen?86.c */
ADDRESS *mk_reg P_ ((REG));
ADDRESS *mk_mreg P_ ((REG, REG));
ADDRESS *mk_label P_ ((LABEL));
ADDRESS *mk_immed P_ ((IVAL));

/* peepx86.c */
void g_code P_ ((OPCODE, ILEN, ADDRESS *, ADDRESS *));
void flush_peep P_ ((unsigned));
BOOL is_equal_address P_ ((ADDRESS *, ADDRESS *));

#ifdef FLOAT_SUPPORT
void g_fcode P_ ((OPCODE, ILEN, ADDRESS *, ADDRESS *));

#endif /* FLOAT_SUPPORT */

/* regx86.c */
ADDRESS *address_register P_ ((void));
ADDRESS *axdx_register P_ ((void));
ADDRESS *cx_register P_ ((void));
ADDRESS *data_register P_ ((void));
ADDRESS *mdata_register P_ ((void));
BOOL is_register_used P_ ((REG));
BOOL uses_temp P_ ((const ADDRESS *));
REGMASK reglist_to_mask P_ ((const REGLIST *));
void initstack P_ ((void));
void checkstack P_ ((void));
void validate P_ ((const ADDRESS *));
void freeop P_ ((const ADDRESS *));
void temp_inv P_ ((void));

#ifdef FLOAT_SUPPORT
ADDRESS *float_register P_ ((void));

#endif /* FLOAT_SUPPORT */

#endif /* _GENX86_H */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -