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

📄 genc30.c

📁 一款拥有一定历史的C语言编译器
💻 C
📖 第 1 页 / 共 5 页
字号:
    if (isanyreg (ap1)) {	ap2 = g_expr (ep->v.p[1], (FLAGS) (F_IALL | F_UNSIGNED));    } else {	ap2 = g_expr (ep->v.p[1], F_XREG);    }    validate (ap1);    if (isanyreg (ap1)) {	g_code (op, OP_INT, ap2, ap1);    } else {	ap2 = mk_legal (ap2, (FLAGS) (F_VOL | F_XREG), OP_INT);	g_code (op, OP_INT, ap1, ap2);	g_code (op_sti, OP_INT, ap2, ap1);    }    freeop (ap2);    return mk_legal (ap1, flags, OP_INT);}/*============================================================================*//* * generate code to evaluate a shift node and return the address mode of the * result. * Note: right shifts will have already been converted to negative left * shifts. */static ADDRESS *g_shift 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_shift", "inconsistency int "));	}	switch (op) {	case op_lsh:	    op = op_lsh3;	    break;	case op_ash:	    op = op_ash3;	    break;	default:	    FATAL ((__FILE__, "g_shift", "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 {	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);	g_code (op, OP_INT, ap2, ap1);	freeop (ap2);    }    return mk_legal (ap1, flags, OP_INT);}/* * generate shift equals operators. */static ADDRESS *g_asshift P3 (const EXPR *, ep, FLAGS, flags, OPCODE, op){    FLAGS   flagx;    ADDRESS *ap1, *ap2, *ap3;    switch (ep->etp->type) {    case bt_uchar:    case bt_schar:    case bt_char:    case bt_charu:    case bt_ushort:    case bt_short:    case bt_int16:    case bt_uint16:    case bt_int32:    case bt_uint32:    case bt_ulong:    case bt_long:    case bt_pointer32:	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);	ap2 = g_expr (ep->v.p[1], (FLAGS) (F_IALL));	validate (ap1);	if (isanyreg (ap1)) {	    g_code (op, OP_INT, ap2, ap1);	} else {	    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);    default:	FATAL ((__FILE__, "g_asshift", "illegal type %d", ep->etp->type));	break;    }    return NIL_ADDRESS;}/*============================================================================*//* * generate code to evaluate a divide operator */static ADDRESS *g_div P3 (const EXPR *, ep, FLAGS, flags, BOOL, mod){    BOOL    is_signed = FALSE;    ADDRESS *ap1, *ap2;    switch (ep->etp->type) {    case bt_char:    case bt_schar:    case bt_short:    case bt_int16:    case bt_int32:    case bt_long:	is_signed = TRUE;	/*FALLTHRU */    case bt_uchar:    case bt_charu:    case bt_ushort:    case bt_uint16:    case bt_uint32:    case bt_ulong:    case bt_pointer32:	temp_inv ();	ap1 = g_expr (ep->v.p[0], F_IALL);	ap2 = g_expr (ep->v.p[1], F_IALL);	validate (ap1);	freeop (ap2);	freeop (ap1);	if (ap2->preg == REG_R0) {	    /* bad luck, parameter is using space for ap1 */	    if (ap1->preg == REG_R1) {		/* its worse, a2 is in r0 and a1 is in r1 */		g_code (op_ldi, OP_INT, ap2, mk_reg (REG_AR0));		g_code (op_ldi, OP_INT, ap1, mk_reg (REG_R0));		g_code (op_ldi, OP_INT, mk_reg (REG_AR0), mk_reg (REG_R1));	    } else {		g_code (op_ldi, OP_INT, ap2, mk_reg (REG_R1));		g_code (op_ldi, OP_INT, ap1, mk_reg (REG_R0));	    }	} else {	    g_code (op_ldi, OP_INT, ap1, mk_reg (REG_R0));	    g_code (op_ldi, OP_INT, ap2, mk_reg (REG_R1));	}	if (is_signed == FALSE) {	    call_library_r0_r1 (mod ? psup_ulrem : psup_uldiv);	} else {	    call_library_r0_r1 (mod ? psup_lrem : psup_ldiv);	}	return func_result (flags, 0L, ep->etp);    case bt_float:    case bt_double:    case bt_longdouble:	temp_inv ();	ap1 = g_expr (ep->v.p[0], F_FALL);	ap2 = g_expr (ep->v.p[1], F_FALL);	validate (ap1);	freeop (ap2);	freeop (ap1);	if (ap2->preg == REG_R0) {	    /* bad luck, parameter is using space for ap1 */	    if (ap1->preg == REG_R1) {		/* its worse, a2 is in r0 and a1 is in r1 */		/* could be solved with parallel addressing */		g_code (op_ldf, OP_INT, ap2, mk_freg (REG_R2));		g_code (op_ldf, OP_INT, ap1, mk_freg (REG_R0));		g_code (op_ldf, OP_INT, mk_freg (REG_R2), mk_freg (REG_R1));	    } else {		g_code (op_ldf, OP_INT, ap2, mk_freg (REG_R1));		g_code (op_ldf, OP_INT, ap1, mk_freg (REG_R0));	    }	} else {	    g_code (op_ldf, OP_INT, ap1, mk_freg (REG_R0));	    g_code (op_ldf, OP_INT, ap2, mk_freg (REG_R1));	}	call_library_r0_r1 (mod ? psup_lrem : psup_fpdiv);	return func_result (flags, 0L, ep->etp);    default:	FATAL (	       (__FILE__, "g_div", "%d: illegal type %d", mod,		ep->etp->type));	break;    }    return NIL_ADDRESS;}/* * generate /= and %= nodes. */static ADDRESS *g_asdiv P3 (const EXPR *, ep, FLAGS, flags, BOOL, mod){    switch (ep->etp->type) {    case bt_char:    case bt_schar:    case bt_short:    case bt_int16:    case bt_int32:    case bt_long:	if (mod) {	    return as_fcall (ep, flags, psup_lrem, OP_INT);	} else {	    return as_fcall (ep, flags, psup_ldiv, OP_INT);	}    case bt_charu:    case bt_uchar:    case bt_ushort:    case bt_uint16:    case bt_uint32:    case bt_ulong:    case bt_pointer32:	if (mod) {	    return as_fcall (ep, flags, psup_ulrem, OP_INT);	} else {	    return as_fcall (ep, flags, psup_uldiv, OP_INT);	}    case bt_float:    case bt_double:    case bt_longdouble:	if (mod) {	    return as_fcall (ep, flags, psup_fprem, OP_FLOAT);	} else {	    return as_fcall (ep, flags, psup_fpdiv, OP_FLOAT);	}    default:	FATAL (	       (__FILE__, "asdiv", "%d: illegal type %d", mod,		ep->etp->type));	break;    }    return NIL_ADDRESS;}/*============================================================================*/static void g_inline_multiply P3 (ADDRESS *, ap1, ADDRESS *, ap2, int,				  is_signed){    ADDRESS *ap3, *ap4, *ap5;    ap3 = temporary_register (F_XREG);    ap4 = temporary_register (F_XREG);    if (is_signed == FALSE) {	/* get signum */	ap5 = temporary_register (F_XREG);	/*	 * validates are not nescessary, since there must be enough	 * registers availlable, if not, this is a compilererror	 * and the validates will catch it and produce a fatal-error 	 */	validate (ap2);	validate (ap1);	g_code3 (op_xor3, OP_INT, ap2, ap1, ap5);	g_code (op_absi, OP_INT, ap1, ap1);	g_code (op_absi, OP_INT, ap2, ap2);    }    g_code (op_ldi, OP_INT, mk_immed (-16), ap4);    g_code3 (op_lsh3, OP_INT, ap4, ap1, ap3);    g_code3 (op_lsh3, OP_INT, ap4, ap2, ap4);    g_code (op_and, OP_INT, mk_uimmed (0xFFFFL), ap1);    g_code (op_and, OP_INT, mk_uimmed (0XFFFFL), ap2);    g_code (op_mpyi, OP_INT, ap1, ap4);    g_code (op_mpyi, OP_INT, ap2, ap3);    g_code (op_mpyi, OP_INT, ap1, ap2);    g_code (op_addi, OP_INT, ap4, ap3);    g_code (op_lsh, OP_INT, mk_immed (16), ap3);    g_code3 (op_addi3, OP_INT, ap3, ap2, ap1);    if (is_signed == FALSE) {	/* get signum */	g_code (op_negi, OP_INT, ap1, ap2);	g_code3 (op_tstb3, OP_INT, ap5, ap5, NIL_ADDRESS);	g_code (op_ldin, OP_INT, ap2, ap1);	freeop (ap5);    }    freeop (ap4);    freeop (ap3);}static ADDRESS *g_mul P2 (const EXPR *, ep, FLAGS, flags){    int     is_signed = TRUE;    ADDRESS *ap1, *ap2, *ap3;    switch (ep->etp->type) {    case bt_uint32:    case bt_ulong:    case bt_pointer32:	is_signed = FALSE;	/*FALLTHRU */    case bt_long:    case bt_int32:	if (opt_true_long != OPT_NO) {	    ap1 =		g_expr (ep->v.p[0],			(FLAGS) (F_VOL | best_flags (flags, F_XREG)));	    ap2 = g_expr (ep->v.p[1], (FLAGS) (F_VOL | F_XREG));	    validate (ap1);	    g_inline_multiply (ap1, ap2, is_signed);	    freeop (ap2);	    return mk_legal (ap1, flags, OP_INT);	}	/*FALLTHRU */    case bt_char:    case bt_schar:    case bt_charu:    case bt_uchar:    case bt_short:    case bt_int16:    case bt_ushort:    case bt_uint16:	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_mul", "inconsistency int "));	    }	    freeop (ap2);	    freeop (ap1);	    ap3 = temporary_register (best_flags (flags, F_XREG));	    g_code3 (op_mpyi3, 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);	    } 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_mpyi, OP_INT, ap2, ap1);	    freeop (ap2);	}	return mk_legal (ap1, flags, OP_INT);    case bt_float:    case bt_double:    case bt_longdouble:	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));	    validate (ap1);	    /* Just to be sure... check again for correct op3-operands */	    if (is_op3_violated (ap1) || is_op3_violated (ap2)) {		FATAL ((__FILE__, "g_mul", "inconsistency float "));	    }	    freeop (ap2);	    freeop (ap1);	    ap3 = temporary_register (F_FREG);	    g_code3 (op_mpyf3, 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);	    } 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_mpyf, OP_FLOAT, ap2, ap1);	    freeop (ap2);	}	return mk_legal (ap1, flags, OP_FLOAT);    default:	FATAL ((__FILE__, "g_mul", "illegal type %d", ep->etp->type));	break;    }    return NIL_ADDRESS;}/* * generate a *= node. */static ADDRESS *g_asmul P2 (const EXPR *, ep, FLAGS, flags){    int     is_signed = TRUE;    ADDRESS *ap1, *ap2, *ap3, *ap6;    switch (ep->etp->type) {    case bt_int32:    case bt_long:	is_signed = FALSE;	/*FALLTHRU */    case bt_uint32:    case bt_ulong:    case bt_pointer32:	if (opt_true_long != OPT_NO) {	    if (ep->v.p[0]->nodetype == en_fieldref)		return g_asbitfield (ep, flags, op_mpyi, FALSE);	    ap1 = g_expr (ep->v.p[0], (FLAGS) (F_IALL | F_USES));	    ap2 = g_expr (ep->v.p[1], (FLAGS) (F_XREG | F_VOL));	    if (isanyreg (ap1)) {		validate (ap1);		ap6 = NULL;	    } else {		ap6 = ap1;		ap1 = temporary_register (F_XREG);		validate (ap6);		g_code (op_ldi, OP_INT, ap6, ap1);	    }	    validate (ap2);	    g_inline_multiply (ap1, ap2, is_signed);	    if (ap6 != NULL) {		freeop (ap1);		validate (ap6);		g_code (op_sti, OP_INT, ap1, ap6);		ap1 = ap6;	    }	    freeop (ap2);	    return mk_legal (ap1, flags, OP_INT);	}	/*FALLTHRU */    case bt_char:    case bt_schar:    case bt_charu:    case bt_uchar:    case bt_short:    case bt_int16:    case bt_ushort:    case bt_uint16:	if (ep->v.p[0]->nodetype == en_fieldref)	    return g_asbitfield (ep, flags, op_mpyi, FALSE);	ap1 = g_expr (ep->v.p[0], (FLAGS) (F_IALL | F_USES));	ap2 = g_expr (ep->v.p[1], (FLAGS) (F_IALL));	if (isanyreg (ap1)) {	    validate (ap1);	    g_code (op_mpyi, OP_INT, ap2, ap1);	    freeop (ap2);	} else {	    ap3 = temporary_register (F_XREG);	    validate (ap1);	    g_code (op_ldi, OP_INT, ap1, ap3);	    g_code (op_mpyi, 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:	ap1 =	    g_expr (ep->v.p[0], (FLAGS) (F_FREG | F_MEM | F_IMMED | F_USES));	ap2 = g_expr (ep->v.p[1], (FLAGS) (F_FREG | F_MEM | F_IMMED));	if ((ap1->mode != am_freg)) {	    ap3 = data_register (F_FREG);	    validate (ap1);	    g_code (op_ldf, OP_FLOAT, ap1, ap3);	    g_code (op_mpyf, OP_FLOAT, ap2, ap3);	    g_code (op_stf, OP_FLOAT, ap3, ap1);	    freeop (ap3);	    freeop (ap2);	} else {	    validate (ap1);	    g_code (op_mpyf, OP_FLOAT, ap2, ap1);	    freeop (ap2);	}	return mk_legal (ap1, flags, OP_FLOAT);    default:	FATAL ((__FILE__, "asmul", "illegal type %d", ep->etp->typ

⌨️ 快捷键说明

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