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

📄 gen86.c

📁 一款拥有一定历史的C语言编译器
💻 C
📖 第 1 页 / 共 5 页
字号:
#endif /* FLOAT_IEEE */    switch (ep->etp->type) {    case bt_char:    case bt_charu:    case bt_uchar:    case bt_schar:    case bt_short:    case bt_ushort:    case bt_int16:    case bt_uint16:    case bt_pointer16:	if (ep->v.p[0]->nodetype == en_fieldref) {	    return g_asbitfield (ep, flags, op, FALSE);	}	if (flags & F_NOVALUE) {	    ap2 = g_expr (ep->v.p[0], F_ALL);	    ap1 = NIL_ADDRESS;	} else {	    ap1 = data_register ();	    ap2 = g_expr (ep->v.p[0], (FLAGS) (F_MEM | F_DREG));	    validate (ap1);	    g_code (op_mov, (ILEN) ep->etp->size, ap2, ap1);	}	g_code (op, (ILEN) ep->etp->size, mk_immed (ep->v.p[1]->v.i), ap2);	freeop (ap2);	return mk_legal (ap1, flags, ep->etp);    case bt_int32:    case bt_uint32:    case bt_long:    case bt_ulong:    case bt_pointer32:	if (flags & F_NOVALUE) {	    ap1 = g_expr (ep->v.p[0], F_ALL);	    g_code (op, IL2, mk_immed (1L), mk_low (ap1));	    op = ((op == op_add) ? op_adc : op_sbb);	    g_code (op, IL2, mk_immed (0L), mk_high (ap1));	} else {	    ap1 = mdata_register ();	    ap2 = g_expr (ep->v.p[0], (FLAGS) (F_MEM | F_DREG));	    validate (ap1);	    g_code (op_mov, IL2, mk_low (ap2), mk_low (ap1));	    g_code (op_mov, IL2, mk_high (ap2), mk_high (ap1));	    g_code (op, IL2, mk_immed (1L), mk_low (ap2));	    op = ((op == op_add) ? op_adc : op_sbb);	    g_code (op, IL2, mk_immed (0L), mk_high (ap2));	    freeop (ap2);	}	return mk_legal (ap1, flags, ep->etp);#ifdef FLOAT_IEEE    case bt_float:    case bt_double:    case bt_longdouble:	if (flags & F_NOVALUE) {	    return g_asbin (ep, flags, op);	}	ap1 = g_expr (ep->v.p[0], F_MEM);	validate (ap1);	ilen = (ILEN) ep->etp->size;	g_fcode (op_fld, ilen, ap1, NIL_ADDRESS);	ap2 = g_expr (ep->v.p[1], F_FREG);	validate (ap1);	switch (op) {	case op_add:	    g_fcode (op_fadd, ilen, ap1, NIL_ADDRESS);	    break;	case op_sub:	    g_fcode (op_fsubr, ilen, ap1, NIL_ADDRESS);	    break;	default:	    FATAL ((__FILE__, "g_aincdec", "illegal op %d", op));	}	freeop (ap2);	freeop (ap1);	g_fcode (op_fstp, ilen, ap1, NIL_ADDRESS);	ap1 = float_register ();	return mk_legal (ap1, flags, ep->etp);#endif /* FLOAT_IEEE */    default:	FATAL ((__FILE__, "g_aincdec", "illegal type %d", ep->etp->type));	break;    }    return NIL_ADDRESS;}/* * generate code to evaluate a binary node and return the addressing mode of * the result. */static ADDRESS *g_bin P3 (const EXPR *, ep, FLAGS, flags, OPCODE, op){    ADDRESS *ap1, *ap2;    TYP    *tp = ep->etp;    OPCODE  op2;    FLAGS   f = F_ALL;    switch (tp->type) {    case bt_char:    case bt_charu:    case bt_uchar:    case bt_schar:	f = (FLAGS) (f | F_NOEDI);	/*FALLTHRU */    case bt_short:    case bt_ushort:    case bt_int16:    case bt_uint16:    case bt_pointer16:	ap1 = g_expr (ep->v.p[0], (FLAGS) (F_DREG | F_VOL));	ap2 = g_expr (ep->v.p[1], f);	validate (ap1);	g_code (op, (ILEN) tp->size, ap2, ap1);	freeop (ap2);	return mk_legal (ap1, flags, tp);    case bt_int32:    case bt_long:    case bt_uint32:    case bt_ulong:    case bt_pointer32:	switch (op) {	case op_add:	    op2 = op_adc;	    goto common;	case op_sub:	    op2 = op_sbb;	    goto common;	case op_and:	case op_or:	case op_xor:	    op2 = op;	  common:	    ap1 = g_expr (ep->v.p[0], (FLAGS) (F_DREG | F_VOL));	    ap2 = g_expr (ep->v.p[1], f);	    validate (ap1);	    g_code (op, IL2, mk_low (ap2), mk_low (ap1));	    g_code (op2, IL2, mk_high (ap2), mk_high (ap1));	    freeop (ap2);	    return mk_legal (ap1, flags, tp);	default:	    CANNOT_REACH_HERE ();	    break;	}	break;#ifdef FLOAT_IEEE    case bt_float:    case bt_double:    case bt_longdouble:	ap1 = g_expr (ep->v.p[0], F_MEM);	ap2 = g_expr (ep->v.p[1], F_FREG);	validate (ap1);	switch (op) {	case op_add:	    op = op_fadd;	    break;	case op_sub:	    op = op_fsubr;	    break;	case op_imul:	    op = op_fmul;	    break;	case op_idiv:	    op = op_fdivr;	    break;	default:	    FATAL ((__FILE__, "g_bin", "illegal op %d", op));	}	g_fcode (op, (ILEN) tp->size, ap1, NIL_ADDRESS);	freeop (ap2);	freeop (ap1);	ap1 = float_register ();	return mk_legal (ap1, flags, ep->etp);#endif /* FLOAT_IEEE */    default:	FATAL ((__FILE__, "g_bin", "illegal type %d", ep->etp->type));	break;    }    return NIL_ADDRESS;}/* * generate code to evaluate a binary as-node * the result. */static ADDRESS *g_asbin P3 (const EXPR *, ep, FLAGS, flags, OPCODE, op){    ADDRESS *ap1, *ap2, *ap3;    FLAGS   flagx = F_NONE;#ifdef FLOAT_IEEE    ILEN    ilen;#endif /* FLOAT_IEEE */    switch (ep->etp->type) {    case bt_char:    case bt_charu:    case bt_uchar:    case bt_schar:	flagx = (FLAGS) (flagx | F_NOEDI);	/*FALLTHRU */    case bt_short:    case bt_ushort:    case bt_int16:    case bt_uint16:    case bt_pointer16:	if (ep->v.p[0]->nodetype == en_fieldref) {	    return g_asbitfield (ep, flags, op, FALSE);	}	if (flags & F_NOVALUE) {	    ap1 = g_expr (ep->v.p[0], (FLAGS) (flagx | F_ALL));	    ap2 = g_expr (ep->v.p[1], (FLAGS) (flagx | F_DREG | F_IMMED));	    validate (ap1);	    g_code (op, (ILEN) ep->etp->size, ap2, ap1);	    freeop (ap2);	    freeop (ap1);	    /* void result */	    ap1 = NIL_ADDRESS;	} else {	    ap1 = g_expr (ep->v.p[0], (FLAGS) (flagx | F_MEM | F_DREG));	    ap2 = g_expr (ep->v.p[1], (FLAGS) (flagx | F_ALL));	    validate (ap1);	    ap3 = data_register ();	    g_code (op_mov, (ILEN) ep->etp->size, ap1, ap3);	    g_code (op, (ILEN) ep->etp->size, ap2, ap3);	    g_code (op_mov, (ILEN) ep->etp->size, ap3, ap1);	    freeop (ap3);	    freeop (ap2);	    freeop (ap1);	    /* need result */	    ap1 = data_register ();	    g_code (op_mov, IL2, ap3, ap1);	    ap1 = mk_legal (ap1, flags, ep->etp);	}	return ap1;    case bt_int32:    case bt_long:    case bt_uint32:    case bt_ulong:    case bt_pointer32:	if (flags & F_NOVALUE) {	    ap1 = g_expr (ep->v.p[0], (FLAGS) (flagx | F_ALL));	    ap2 = g_expr (ep->v.p[1], (FLAGS) (flagx | F_DREG | F_IMMED));	    validate (ap1);	    switch (op) {	    case op_add:		g_code (op, IL2, mk_low (ap2), mk_low (ap1));		g_code (op_adc, IL2, mk_high (ap2), mk_high (ap1));		break;	    case op_sub:		g_code (op, IL2, mk_low (ap2), mk_low (ap1));		g_code (op_sbb, IL2, mk_high (ap2), mk_high (ap1));		break;	    case op_or:	    case op_xor:	    case op_and:		g_code (op, IL2, mk_low (ap2), mk_low (ap1));		g_code (op, IL2, mk_high (ap2), mk_high (ap1));		break;	    default:		CANNOT_REACH_HERE ();		break;	    }	    freeop (ap2);	    freeop (ap1);	    /* void result */	    ap1 = NIL_ADDRESS;	} else {	    ap1 = g_expr (ep->v.p[0], (FLAGS) (flagx | F_DREG));	    ap2 = g_expr (ep->v.p[1], (FLAGS) (flagx | F_ALL));	    validate (ap1);	    switch (op) {	    case op_add:		g_code (op, IL2, mk_low (ap2), mk_low (ap1));		g_code (op_adc, IL2, mk_high (ap2), mk_high (ap1));		break;	    case op_sub:		g_code (op, IL2, mk_low (ap2), mk_low (ap1));		g_code (op_sbb, IL2, mk_high (ap2), mk_high (ap1));		break;	    case op_or:	    case op_xor:	    case op_and:		g_code (op, IL2, mk_low (ap2), mk_low (ap1));		g_code (op, IL2, mk_high (ap2), mk_high (ap1));		break;	    default:		CANNOT_REACH_HERE ();		break;	    }	    freeop (ap2);	    ap1 = mk_legal (ap1, flags, ep->etp);	}	return ap1;#ifdef FLOAT_IEEE    case bt_float:    case bt_double:    case bt_longdouble:	ap1 = g_expr (ep->v.p[0], F_MEM);	ap2 = g_expr (ep->v.p[1], F_FREG);	validate (ap1);	ilen = (ILEN) ep->etp->size;	switch (op) {	case op_add:	    op = op_fadd;	    break;	case op_sub:	    op = op_fsubr;	    break;	case op_imul:	    op = op_fmul;	    break;	case op_idiv:	    op = op_fdivr;	    break;	default:	    FATAL ((__FILE__, "g_asbin", "illegal op %d", op));	}	g_fcode (op, ilen, ap1, NIL_ADDRESS);	freeop (ap2);	freeop (ap1);	if (flags & F_NOVALUE) {	    g_fcode (op_fstp, ilen, ap1, NIL_ADDRESS);	    ap1 = NIL_ADDRESS;	} else {	    g_fcode (op_fst, ilen, ap1, NIL_ADDRESS);	    ap1 = float_register ();	}	return mk_legal (ap1, flags, ep->etp);#endif /* FLOAT_IEEE */    default:	FATAL ((__FILE__, "g_asbin", "illegal type %d", ep->etp->type));	break;    }    return NIL_ADDRESS;}/*---------------------------------------------------------------------------*//* * generate code to evaluate a shift node */static ADDRESS *g_shift P3 (const EXPR *, ep, FLAGS, flags, OPCODE, op){    EXPR   *ep1;    ADDRESS *ap1, *ap2;    FLAGS   flgs;    switch (ep->etp->type) {    case bt_int16:    case bt_char:    case bt_schar:    case bt_short:	if (op == op_shr) {	    op = op_asr;	}	/*FALLTHRU */    case bt_pointer16:    case bt_uint16:    case bt_uchar:    case bt_charu:    case bt_ushort:	ap1 = g_expr (ep->v.p[0], (FLAGS) (F_DREG | F_VOL | F_NOECX));	ep1 = ep->v.p[1];	if (target_option == target_8086 &&	    (ep1->nodetype == en_icon && ep1->v.i == 2)) {	    ap2 = mk_immed (1L);	    g_code (op, (ILEN) ep->etp->size, ap2, ap1);	} else {	    if (target_option >= target_80186 ||		(ep1->nodetype == en_icon && ep1->v.i == 1)) {		flgs = (FLAGS) (F_DREG | F_IMMED | F_ECX);	    } else {		flgs = (FLAGS) (F_DREG | F_ECX);	    }	    ap2 = g_expr (ep->v.p[1], flgs);	}	validate (ap1);	g_code (op, (ILEN) ep->etp->size, ap2, ap1);	freeop (ap2);	return mk_legal (ap1, flags, ep->etp);    default:	FATAL ((__FILE__, "g_shift", "illegal type %d", ep->etp->type));	break;    }    return NIL_ADDRESS;}/* * generate code to evaluate an assign shift node */static ADDRESS *g_asshift P3 (const EXPR *, ep, FLAGS, flags, OPCODE, op){    ADDRESS *ap1, *ap2;    switch (ep->etp->type) {    case bt_int16:    case bt_short:    case bt_char:    case bt_schar:	if (op == op_shr) {	    op = op_asr;	}	/*FALLTHRU */    case bt_pointer16:    case bt_uint16:    case bt_uchar:    case bt_charu:    case bt_ushort:	if (ep->v.p[0]->nodetype == en_fieldref) {	    return g_asbitfield (ep, flags, op, FALSE);	}	ap1 = g_expr (ep->v.p[0], (FLAGS) (F_MEM | F_DREG | F_NOECX));	ap2 = g_expr (ep->v.p[1], (FLAGS) (F_DREG | F_IMMED | F_ECX));	validate (ap1);	g_code (op, (ILEN) ep->etp->size, ap2, ap1);	freeop (ap2);	return mk_legal (ap1, flags, ep->etp);    default:	FATAL ((__FILE__, "g_asshift", "illegal type %d", ep->etp->type));	break;    }    return NIL_ADDRESS;}/* * generate code to evaluate a divide node (mod==0) or mod node (mod==1) */static ADDRESS *g_div P3 (const EXPR *, ep, FLAGS, flags, BOOL, mod){    ADDRESS *ap1, *ap2;    OPCODE  op = op_idiv;    switch (ep->etp->type) {    case bt_uint16:    case bt_ushort:    case bt_pointer16:	op = op_div;	/*FALLTHRU */    case bt_short:    case bt_int16:	temp_inv ();	ap1 = g_expr (ep->v.p[0], (FLAGS) (F_DREG | F_EAXEDX));	ap2 = g_expr (ep->v.p[1], (FLAGS) (F_DREG | F_MEM));	validate (ap1);	if (op == op_idiv) {	    g_code (op_cwd, IL0, NIL_ADDRESS, NIL_ADDRESS);	} else {	    g_code (op_xor, IL2, mk_high (ap1), mk_high (ap1));	}	g_code (op, IL2, ap2, NIL_ADDRESS);	freeop (ap2);	freeop (ap1);	ap1 = data_register ();	if (mod) {	    g_code (op_mov, IL2, &edx_reg, ap1);	} else {	    g_code (op_mov, IL2, &eax_reg, ap1);	}	return mk_legal (ap1, flags, ep->etp);    default:	return g_bin (ep, flags, op_idiv);    }}/* * generate code for /= node */static ADDRESS *g_asdiv P3 (const EXPR *, ep, FLAGS, flags, BOOL, mod){    ADDRESS *ap1, *ap2;    OPCODE  op = op_idiv;    switch (ep->etp->type) {    case bt_charu:    case bt_uchar:    case bt_ushort:    case bt_uint16:    case bt_pointer16:	op = op_div;	/*FALLTHRU */    case bt_char:    case bt_schar:    case bt_int16:    case bt_short:	if (ep->v.p[0]->nodetype == en_fieldref) {	    return g_asbitfield (ep, flags, op, mod);	}	ap1 = g_expr (ep->v.p[0], (FLAGS) (F_MEM | F_DREG | F_EAXEDX));	ap2 = g_expr (ep->v.p[1], (FLAGS) (F_DREG | F_MEM));	validate (ap1);	if (op == op_idiv) {	    g_code (op_cwd, IL0, NIL_ADDRESS, NIL_ADDRESS);	} else {	    g_code (op_xor, IL2, mk_high (ap1), mk_high (ap1));	}	g_code (op, (ILEN) ep->etp->size, ap2, NIL_ADDRESS);	freeop (ap2);	freeop (ap1);	ap2 = data_register ();	if (mod) {	    g_code (op_mov, (ILEN) ep->etp->size, mk_high (ap1), ap2);	} else {	    g_code (op_mov, (ILEN) ep->etp->size, mk_low (ap1), ap2);	}	return mk_legal (ap2, flags, ep->etp);    default:	return g_asbin (ep, flags, op_idiv);    }}/* * generate code to evaluate a multiply node */static ADDRESS *g_mul P2 (const EXPR *, ep, FLAGS, flags){    ADDRESS *ap1, *ap2;    OPCODE  op = op_imul;    switch (ep->etp->type) {    case bt_uint16:    case bt_ushort:    case bt_pointer16:	/*	 * unless the result is extended to 32 bit, there should	 * be no difference between imul and mul.	 * NB. There is no mul instruction unless 32-bit extension	 * is desired.	 */	/* op = op_mul; >>>This instruction does not exist<<< */	/*FALLTHRU */    case bt_int16:    case bt_short:	if (target_option >= target_80186 && is_icon (ep->v.p[1])) {	    ap1 = g_expr (ep->v.p[0], (FLAGS) (F_DREG | F_VOL));	    ap2 = g_expr (ep->v.p[1], F_IMMED);	    g_code (op, (ILEN) ep->etp->size, ap2, mk_low (ap1));	    freeop (ap2);	    return mk_legal (ap1, flags, ep->etp);	} else {	    ap1 = g_expr (ep->v.p[0], (FLAGS) (F_DREG | F_EAXEDX | F_VOL));

⌨️ 快捷键说明

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