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

📄 genc30.c

📁 一款拥有一定历史的C语言编译器
💻 C
📖 第 1 页 / 共 5 页
字号:
	    && ep->v.p[0]->nodetype == en_register	    && is_address_register (ep->v.p[0]->v.r)	    && !(flags & F_USES)) {	    /* (An)+ */	    ap1 = mk_amode (am_ainc);	    ap1->preg = ep->v.p[0]->v.r;	    ap1->u.offset = mk_const (ep->v.p[1]->v.i);	    return ap1;	}	break;    case en_adec:	/* special TMS320C30 instructions */	if (ep->v.p[1]->v.i <= 255L	/* if size less than max autoincrement */	    && ep->v.p[1]->v.i >= 0L	/* and if size positive */	    && ep->v.p[0]->nodetype == en_register	    && is_address_register (ep->v.p[0]->v.r)	    && !(flags & F_USES)) {	    /* (An)- */	    ap1 = mk_amode (am_adec);	    ap1->preg = ep->v.p[0]->v.r;	    ap1->u.offset = mk_const (ep->v.p[1]->v.i);	    return ap1;	}	break;    case en_asadd:	/* special TMS320C30 instructions */	if (is_icon (ep->v.p[1])	    && ep->v.p[1]->v.i <= 255L	/* if size less than max autoincrement */	    && ep->v.p[1]->v.i >= 0L	/* and if size positive */	    && ep->v.p[0]->nodetype == en_register	    && is_address_register (ep->v.p[0]->v.r)	    && !(flags & F_USES)) {	    /* ++(An) */	    ap1 = mk_amode (am_preinc);	    ap1->preg = ep->v.p[0]->v.r;	    ap1->u.offset = mk_const (ep->v.p[1]->v.i);	    return ap1;	}	break;    case en_assub:	/* special TMS320C30 instructions */	if (is_icon (ep->v.p[1])	    && ep->v.p[1]->v.i <= 255L	/* if size less than max autoincrement */	    && ep->v.p[1]->v.i >= 0L	/* and if size positive */	    && ep->v.p[0]->nodetype == en_register	    && is_address_register (ep->v.p[0]->v.r)	    && !(flags & F_USES)) {	    /* --(An) */	    ap1 = mk_amode (am_predec);	    ap1->preg = ep->v.p[0]->v.r;	    ap1->u.offset = mk_const (ep->v.p[1]->v.i);	    return ap1;	}	break;    default:	break;    }    /*     * F_DIRECT Supresses to make a doubleindirection for     * immediates, sinc it will be converted in an direct-reference     */    ap1 = g_expr (ep, (FLAGS) (F_AREG | F_IMMED | F_DIRECT));	/* generate address */    if (ap1->mode == am_areg) {	return copy_addr (ap1, am_ind);    }    return copy_addr (ap1, am_direct);}/* * get a bitfield value */static ADDRESS *g_fderef P2 (const EXPR *, ep, FLAGS, flags){    ADDRESS *ap;    ap = g_deref (ep->v.p[0], ep->etp, (FLAGS) (F_IALL));    ap = mk_legal (ap, (FLAGS) (F_XREG | F_VOL), OP_INT);    g_rotate (ap, (int) ep->v.bit.offset, ep->etp, (int) ep->v.bit.width);    return mk_legal (ap, flags, OP_INT);}/*============================================================================*//* * generate code to evaluate a unary minus or complement. float: unary minus * calls a library function */static ADDRESS *g_unary P3 (const EXPR *, ep, FLAGS, flags, OPCODE, op){    ADDRESS *ap, *ap2;    switch (ep->etp->type) {    case bt_uchar:    case bt_schar:    case bt_char:    case bt_charu:    case bt_short:    case bt_ushort:    case bt_int16:    case bt_uint16:    case bt_int32:    case bt_uint32:    case bt_long:    case bt_ulong:    case bt_pointer32:	ap =	    g_expr (ep->v.p[0],		    (FLAGS) (op == op_not ? F_IALL | F_UNSIGNED : F_IALL));	/* maybe we can use ap... */	freeop (ap);	ap2 = temporary_register (best_flags (flags, F_XREG));	g_code (op, OP_INT, ap, ap2);	return mk_legal (ap2, flags, OP_INT);    case bt_float:    case bt_double:    case bt_longdouble:	if (op == op_negi) {	    ap = g_expr (ep->v.p[0], (FLAGS) (F_FALL));	    /* maybe we can use ap... */	    freeop (ap);	    ap2 = temporary_register (F_FREG);	    g_code (op_negf, OP_FLOAT, ap, ap2);	    return mk_legal (ap2, flags, OP_FLOAT);	}	/* Fall through */    default:	FATAL (	       (__FILE__, "g_unary", "illegal type %d or operation %d",		ep->etp->type, op));	break;    }    return NIL_ADDRESS;}/*============================================================================*//* * generate an auto increment or decrement node. op should be either op_add * (for increment) or op_sub (for decrement). */static ADDRESS *g_aincdec P3 (const EXPR *, ep, FLAGS, flags, OPCODE, op){    ADDRESS *ap1, *ap2, *ap3;    switch (ep->etp->type) {    case bt_uchar:    case bt_schar:    case bt_char:    case bt_charu:    case bt_short:    case bt_ushort:    case bt_int16:    case bt_uint16:    case bt_int32:    case bt_uint32:    case bt_long:    case bt_ulong:    case bt_pointer32:	if (ep->v.p[0]->nodetype == en_fieldref)	    return g_asbitfield (ep, flags, op, TRUE);	if (flags & F_NOVALUE) {	/* dont need result */	    ap1 = g_expr (ep->v.p[0], (FLAGS) (F_IALL));	    /* if ap1 is in register we can modify it directly */	    if (isanyreg (ap1)) {		g_immed (op, ep->v.p[1]->v.i, ap1);	    } else {		/* else we must get ap1 in a register, modify it and store it again */		ap2 = temporary_register (F_XREG);		g_code (op_ldi, OP_INT, ap1, ap2);		g_immed (op, ep->v.p[1]->v.i, ap2);		g_code (op_sti, OP_INT, ap2, ap1);		freeop (ap2);	    }	    return mk_legal (ap1, flags, OP_INT);	}	ap1 = temporary_register (best_flags (flags, F_XREG));	ap2 = g_expr (ep->v.p[0], (FLAGS) (F_IALL | F_USES));	validate (ap1);	g_code (op_ldi, OP_INT, ap2, ap1);	/* if ap2 is in register we can modify it directly */	if (isanyreg (ap2)) {	    g_immed (op, ep->v.p[1]->v.i, ap2);	} else {	    /* else we must get ap2 in a register, modify it and store it again */	    ap3 = temporary_register (F_XREG);	    g_code (op_ldi, OP_INT, ap1, ap3);	    g_immed (op, ep->v.p[1]->v.i, ap3);	    g_code (op_sti, OP_INT, ap3, ap2);	    freeop (ap3);	}	freeop (ap2);	return mk_legal (ap1, flags, OP_INT);#ifdef FLOAT_SUPPORT    case bt_float:    case bt_double:    case bt_longdouble:	if (flags & F_NOVALUE) {	/* dont need result */	    ap1 = g_expr (ep->v.p[0], F_FALL);	    /* if ap1 is in register we can modify it directly */	    if (ap1->mode == am_freg) {		g_code (op, OP_FLOAT,			mk_immedfloat ((double) ep->v.p[1]->v.f), ap1);	    } else {		/* else we must get ap1 in a register, modify it and store it again */		ap2 = temporary_register (F_FREG);		g_code (op_ldf, OP_FLOAT, ap1, ap2);		g_code (op, OP_FLOAT,			mk_immedfloat ((double) ep->v.p[1]->v.f), ap2);		g_code (op_stf, OP_FLOAT, ap2, ap1);		freeop (ap2);	    }	    return mk_legal (ap1, flags, OP_FLOAT);	}	ap1 = temporary_register (F_FREG);	ap2 = g_expr (ep->v.p[0], (FLAGS) (F_FALL | F_USES));	validate (ap1);	g_code (op_ldf, OP_FLOAT, ap2, ap1);	/* if ap2 is in register we can modify it directly */	if (ap2->mode == am_freg) {	    g_code (op, OP_FLOAT, mk_immedfloat ((double) ep->v.p[1]->v.f),		    ap2);	} else {	    /* else we must get ap2 in a register, modify it and store it again */	    ap3 = temporary_register (F_FREG);	    g_code (op_ldf, OP_FLOAT, ap1, ap3);	    g_code (op, OP_FLOAT, mk_immedfloat ((double) ep->v.p[1]->v.f),		    ap3);	    g_code (op_stf, OP_FLOAT, ap3, ap2);	    freeop (ap3);	}	freeop (ap2);	return mk_legal (ap1, flags, OP_FLOAT);#endif /* FLOAT_SUPPORT */    default:	FATAL (	       (__FILE__, "g_aincdec", "illegal type %d or float",		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_addsub P3 (const EXPR *, ep, FLAGS, flags, OPCODE, op){    ADDRESS *ap1, *ap2, *ap3;    switch (ep->etp->type) {    case bt_uchar:    case bt_schar:    case bt_char:    case bt_charu:    case bt_short:    case bt_ushort:    case bt_int16:    case bt_uint16:    case bt_int32:    case bt_uint32:    case bt_long:    case bt_ulong:    case bt_pointer32:	if (is_op3_possible (ep->v.p[0])	    && is_op3_possible (ep->v.p[1])) {	    ap1 = g_expr (ep->v.p[0], (FLAGS) (F_XREG | F_MEM));	    ap2 = g_expr (ep->v.p[1], (FLAGS) (F_XREG | F_MEM));	    /* Just to be sure... check again for correct op3-operands */	    if (is_op3_violated (ap1) || is_op3_violated (ap2)) {		FATAL ((__FILE__, "g_addsub", "inconsistency int "));	    }	    validate (ap1);	    freeop (ap2);	    freeop (ap1);	    ap3 = temporary_register (best_flags (flags, F_XREG));	    g_code3 ((op == op_addi ? op_addi3 : op_subi3), OP_INT, ap2, ap1,		     ap3);	    ap1 = ap3;	} else {	    if (tst_iconst (ep->v.p[0])) {		ap1 =		    g_expr (ep->v.p[1],			    (FLAGS) (F_VOL | best_flags (flags, F_XREG)));		ap2 = g_expr (ep->v.p[0], F_IALL);		if (op == op_subi)		    op = op_subri;	    } else {		ap1 =		    g_expr (ep->v.p[0],			    (FLAGS) (F_VOL | best_flags (flags, F_XREG)));		ap2 = g_expr (ep->v.p[1], F_IALL);	    }	    validate (ap1);	/* in case push occurred */	    g_code (op, OP_INT, ap2, ap1);	    freeop (ap2);	}	return mk_legal (ap1, flags, OP_INT);    case bt_longdouble:    case bt_double:    case bt_float:	op = (op == op_addi) ? op_addf : op_subf;	if (is_op3_possible (ep->v.p[0])	    && is_op3_possible (ep->v.p[1])) {	    ap1 = g_expr (ep->v.p[0], (FLAGS) (F_FREG | F_MEM));	    ap2 = g_expr (ep->v.p[1], (FLAGS) (F_FREG | F_MEM));	    /* Just to be sure... check again for correct op3-operands */	    if (is_op3_violated (ap1) || is_op3_violated (ap2)) {		FATAL ((__FILE__, "g_addsub", "inconsistency float "));	    }	    validate (ap1);	    freeop (ap2);	    freeop (ap1);	    ap3 = temporary_register (F_FREG);	    g_code3 ((op == op_addf ? op_addf3 : op_subf3), OP_FLOAT, ap2,		     ap1, ap3);	    ap1 = ap3;	} else {	    if (ep->v.p[0]->nodetype == en_fcon) {		ap1 = g_expr (ep->v.p[1], (FLAGS) (F_VOL | F_FREG));		ap2 = g_expr (ep->v.p[0], F_FALL);		if (op == op_subf)		    op = op_subrf;	    } else {		ap1 = g_expr (ep->v.p[0], (FLAGS) (F_VOL | F_FREG));		ap2 = g_expr (ep->v.p[1], F_FALL);	    }	    validate (ap1);	/* in case push occurred */	    g_code (op, OP_FLOAT, ap2, ap1);	    freeop (ap2);	}	return mk_legal (ap1, flags, OP_FLOAT);    default:	FATAL ((__FILE__, "g_addsub", "illegal type %d", ep->etp->type));	break;    }    return NIL_ADDRESS;}/* * generate a plus equal or a minus equal node. */static ADDRESS *g_asadd P3 (const EXPR *, ep, FLAGS, flags, OPCODE, op){    FLAGS   flagx;    ADDRESS *ap1, *ap2, *ap3;    switch (ep->etp->type) {    case bt_char:    case bt_charu:    case bt_schar:    case bt_uchar:    case bt_short:    case bt_ushort:    case bt_int16:    case bt_uint16:    case bt_int32:    case bt_uint32:    case bt_long:    case bt_ulong:    case bt_pointer32:	if (ep->v.p[0]->nodetype == en_fieldref)	    return g_asbitfield (ep, flags, op, FALSE);	if (flags & F_NOVALUE)	    flagx = F_IALL;	else	    flagx = (FLAGS) (F_IALL | F_USES);	ap1 = g_expr (ep->v.p[0], flagx);	if (isanyreg (ap1)) {	    ap2 = g_expr (ep->v.p[1], (FLAGS) (F_IALL));	    validate (ap1);	    g_code (op, OP_INT, ap2, ap1);	} else {	    ap2 = g_expr (ep->v.p[1], (FLAGS) (F_IALL));	    validate (ap1);	    ap3 = temporary_register (F_XREG);	    g_code (op_ldi, OP_INT, ap1, ap3);	    g_code (op, OP_INT, ap2, ap3);	    g_code (op_sti, OP_INT, ap3, ap1);	    freeop (ap3);	}	freeop (ap2);	return mk_legal (ap1, flags, OP_INT);    case bt_float:    case bt_double:    case bt_longdouble:	op = (op == op_addi) ? op_addf : op_subf;	flagx = (flags & F_NOVALUE) ? F_FALL : (FLAGS) (F_FALL | F_USES);	ap1 = g_expr (ep->v.p[0], flagx);	if (ap1->mode == am_freg) {	    ap2 = g_expr (ep->v.p[1], (FLAGS) (F_FREG | F_MEM | F_IMMED));	    validate (ap1);	    g_code (op, OP_FLOAT, ap2, ap1);	} else {	    ap2 = g_expr (ep->v.p[1], (FLAGS) (F_FREG | F_MEM | F_IMMED));	    validate (ap1);	    ap3 = temporary_register (F_FREG);	    g_code (op_ldf, OP_FLOAT, ap1, ap3);	    g_code (op, OP_FLOAT, ap2, ap3);	    g_code (op_stf, OP_FLOAT, ap3, ap1);	    freeop (ap3);	}	freeop (ap2);	return mk_legal (ap1, flags, OP_FLOAT);    default:	FATAL ((__FILE__, "asadd", "illegal type %d", ep->etp->type));	break;    }    return NIL_ADDRESS;}/*============================================================================*//* * generate code to evaluate a restricted binary node and return the * addressing mode of the result. */static ADDRESS *g_logic P3 (const EXPR *, ep, FLAGS, flags, OPCODE, op){    ADDRESS *ap1, *ap2, *ap3;    if (is_op3_possible (ep->v.p[0])	&& is_op3_possible (ep->v.p[1])) {	ap1 = g_expr (ep->v.p[0], (FLAGS) (F_XREG | F_MEM));	ap2 = g_expr (ep->v.p[1], (FLAGS) (F_XREG | F_MEM));	validate (ap1);	/* Just to be sure... check again for correct op3-operands */	if (is_op3_violated (ap1) || is_op3_violated (ap2)) {	    FATAL ((__FILE__, "g_logic", "inconsistency int "));	}	switch (op) {	case op_and:	    op = op_and3;	    break;	case op_andn:	    op = op_andn3;	    break;	case op_or:	    op = op_or3;	    break;	case op_xor:	    op = op_xor3;	    break;	default:	    FATAL ((__FILE__, "g_logic", "illegal opcode %d", op));	    break;	}	freeop (ap2);	freeop (ap1);	ap3 = temporary_register (best_flags (flags, F_XREG));	g_code3 (op, OP_INT, ap2, ap1, ap3);	ap1 = ap3;    } else {	if (tst_iconst (ep->v.p[0])) {	    ap1 =		g_expr (ep->v.p[1],			(FLAGS) (F_VOL | best_flags (flags, F_XREG)));	    ap2 = g_expr (ep->v.p[0], (FLAGS) (F_IALL | F_UNSIGNED));	} else {	    ap1 =		g_expr (ep->v.p[0],			(FLAGS) (F_VOL | best_flags (flags, F_XREG)));	    ap2 = g_expr (ep->v.p[1], (FLAGS) (F_IALL | F_UNSIGNED));	}	validate (ap1);		/* in case push occurred */	g_code (op, OP_INT, ap2, ap1);	freeop (ap2);    }    return mk_legal (ap1, flags, OP_INT);}/* * generate a &= or a |= node. */static ADDRESS *g_aslogic P3 (const EXPR *, ep, FLAGS, flags, OPCODE, op){    FLAGS   flagx;    ADDRESS *ap1, *ap2;    if (ep->v.p[0]->nodetype == en_fieldref)	return g_asbitfield (ep, flags, op, FALSE);    flagx = (flags & F_NOVALUE) ? F_IALL : (FLAGS) (F_IALL | F_USES);    ap1 = g_expr (ep->v.p[0], flagx);

⌨️ 快捷键说明

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