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

📄 gen68k.c

📁 一款拥有一定历史的C语言编译器
💻 C
📖 第 1 页 / 共 5 页
字号:
    case bt_char:    case bt_charu:    case bt_uchar:    case bt_schar:    case bt_short:    case bt_int16:	return TRUE;    default:	break;    }    if (ep->nodetype == en_cast) {	switch (ep->v.p[0]->etp->type) {	case bt_char:	case bt_charu:	case bt_uchar:	case bt_schar:	case bt_short:	case bt_int16:	    return TRUE;	default:	    return FALSE;	}    }    return FALSE;}void g_move P3 (ILEN, len, ADDRESS *, ap1, ADDRESS *, ap2){    switch (ap2->mode) {    case am_areg:	g_code (op_movea, len, ap1, ap2);	break;    default:	g_code (op_move, len, ap1, ap2);	break;    }}static void g_movem P2 (ADDRESS *, ap1, ADDRESS *, ap2){#ifdef COLDFIRE    if (is_coldfire ()) {	switch (ap1->mode) {	case am_ainc:	    ap1 = copy_addr (ap1, am_ind);	    g_code (op_movem, IL4, ap1, ap2);	    g_code (op_add, IL4,		    mk_immed (4L * count_registers (ap2->u.mask)),		    mk_reg (ap1->preg));	    return;	case am_adec:	    g_code (op_sub, IL4,		    mk_immed (4L * count_registers (ap2->u.mask)),		    mk_reg (ap1->preg));	    ap1 = copy_addr (ap1, am_ind);	    g_code (op_movem, IL4, ap1, ap2);	    return;	default:	    break;	}	switch (ap2->mode) {	case am_ainc:	    ap2 = copy_addr (ap2, am_ind);	    g_code (op_movem, IL4, ap1, ap2);	    g_code (op_add, IL4,		    mk_immed (4L * count_registers (ap1->u.mask)),		    mk_reg (ap2->preg));	    return;	case am_adec:	    g_code (op_sub, IL4,		    mk_immed (4L * count_registers (ap1->u.mask)),		    mk_reg (ap2->preg));	    ap2 = copy_addr (ap2, am_ind);	    g_code (op_movem, IL4, ap1, ap2);	    return;	default:	    break;	}    }#endif /* COLDFIRE */    g_code (op_movem, IL4, ap1, ap2);}#ifdef FLOAT_IEEEstatic void g_fmovem P2 (ADDRESS *, ap1, ADDRESS *, ap2){#ifdef COLDFIRE    if (is_coldfire ()) {	switch (ap1->mode) {	case am_ainc:	    ap1 = copy_addr (ap1, am_ind);	    g_fcode (op_fmovem, IL12, ap1, ap2);	    g_code (op_add, IL4,		    mk_immed (12L * count_registers (ap2->u.mask)),		    mk_reg (ap1->preg));	    return;	case am_adec:	    g_code (op_sub, IL4,		    mk_immed (12L * count_registers (ap2->u.mask)),		    mk_reg (ap1->preg));	    ap1 = copy_addr (ap1, am_ind);	    g_fcode (op_fmovem, IL12, ap1, ap2);	    return;	default:	    break;	}	switch (ap2->mode) {	case am_ainc:	    ap2 = copy_addr (ap2, am_ind);	    g_fcode (op_fmovem, IL12, ap1, ap2);	    g_code (op_add, IL4,		    mk_immed (12L * count_registers (ap1->u.mask)),		    mk_reg (ap2->preg));	    return;	case am_adec:	    g_code (op_sub, IL4,		    mk_immed (12L * count_registers (ap1->u.mask)),		    mk_reg (ap2->preg));	    ap2 = copy_addr (ap2, am_ind);	    g_fcode (op_fmovem, IL12, ap1, ap2);	    return;	default:	    break;	}    }#endif /* COLDFIRE */    g_fcode (op_fmovem, IL12, ap1, ap2);}#endif /* FLOAT_IEEE */static void g_call P1 (ADDRESS *, ap){    ADDRESS *ap1;    EXPR   *ep;    LABEL   label;
    if (ap == NIL_ADDRESS)
	return;
    switch (ap->mode) {
    case am_immed:
	g_code (op_trap, IL0, ap, NIL_ADDRESS);
	break;    case am_direct:	switch (codemodel_option) {	case model_absolute:	    g_code (op_jsr, IL0, ap, NIL_ADDRESS);	    break;	case model_small:	    label = nextlabel++;	    ap = copy_addr (ap, am_indxpc);	    ep = mk_node (en_sub, ap->u.offset, mk_lcon (label), tp_void);	    ap->u.offset =		mk_node (en_add, ep, mk_icon ((IVAL) 2L, tp_int), tp_void);	    g_label (label);	    g_code (op_jsr, IL0, ap, NIL_ADDRESS);	    break;	case model_large:	    ap1 = address_register ();	    label = nextlabel++;	    ap = copy_addr (ap, am_immed);	    ep = mk_node (en_sub, ap->u.offset, mk_lcon (label), tp_void);	    ap->u.offset =		mk_node (en_add, ep, mk_icon ((IVAL) 2L, tp_int), tp_void);	    g_move (IL4, ap, ap1);	    freeop (ap1);	    ap = copy_addr (ap1, am_indx2pc);	    ap->u.offset = mk_const ((IVAL) 0L);	    g_label (label);	    g_code (op_jsr, IL0, ap, NIL_ADDRESS);	    break;	default:	    CANNOT_REACH_HERE ();	}	break;    case am_ind:	g_code (op_jsr, IL0, ap, NIL_ADDRESS);	break;    default:	CANNOT_REACH_HERE ();    }}static void g_add P3 (ILEN, len, ADDRESS *, ap1, ADDRESS *, ap2){    switch (ap2->mode) {    case am_areg:	g_code (op_adda, len, ap1, ap2);	break;    default:	g_code (op_add, len, ap1, ap2);	break;    }}static void g_sub P3 (ILEN, len, ADDRESS *, ap1, ADDRESS *, ap2){    switch (ap2->mode) {    case am_areg:	g_code (op_suba, len, ap1, ap2);	break;    default:	g_code (op_sub, len, ap1, ap2);	break;    }}static void g_move8 P2 (ADDRESS *, ap1, ADDRESS *, ap2){    switch (ap1->mode) {    case am_mreg:	if (ap2->mode == am_mreg) {	    if (ap2->preg == ap1->preg && ap2->sreg == ap1->sreg) {		return;	    }	} else {	    if (ap1->preg < ap1->sreg) {		g_movem (mk_smask ((REGMASK)				   REGBIT (ap1->preg) | REGBIT (ap1->sreg)),			 ap2);		return;	    }	}	break;#ifdef FLOAT_IEEE    case am_freg:	g_fcode (op_fmove, IL8, ap1, ap2);	return;#endif /* FLOAT_IEEE */    default:	break;    }    if (ap2->mode == am_mreg && ap1->mode != am_immed) {	if (ap2->preg < ap2->sreg && ap1->mode != am_mreg) {	    g_movem (ap1, mk_rmask ((REGMASK)				    REGBIT (ap2->preg) | REGBIT (ap2->sreg)));	    return;	}    }    switch (ap2->mode) {    case am_adec:	g_move (IL4, mk_high (ap1), mk_high (ap2));	g_move (IL4, mk_low (ap1), mk_low (ap2));	break;#ifdef FLOAT_IEEE    case am_freg:	g_fcode (op_fmove, IL8, ap1, ap2);	break;#endif /* FLOAT_IEEE */    default:#ifdef COLDFIRE	if (is_coldfire ()) {	    ADDRESS *ap = data_register ();	    g_move (IL4, mk_high (ap1), ap);	    g_move (IL4, ap, mk_high (ap2));	    g_move (IL4, mk_low (ap1), ap);	    g_move (IL4, ap, mk_low (ap2));	    freeop (ap);	    return;	}#endif /* COLDIFRE */	g_move (IL4, mk_high (ap1), mk_high (ap2));	g_move (IL4, mk_low (ap1), mk_low (ap2));	break;    }}static void g_move12 P2 (ADDRESS *, ap1, ADDRESS *, ap2){    switch (ap1->mode) {    case am_xreg:	if (ap2->mode == am_xreg) {	    if (ap2->preg == ap1->preg &&		ap2->sreg == ap1->sreg && ap2->u.xreg == ap1->u.xreg)		return;	} else {	    if (ap1->preg < ap1->sreg && ap1->sreg < ap1->u.xreg) {		g_movem (mk_smask ((REGMASK)				   REGBIT (ap1->preg) |				   REGBIT (ap1->sreg) |				   REGBIT (ap1->u.xreg)), ap2);		return;	    }	}	break;#ifdef FLOAT_IEEE    case am_freg:	g_fcode (op_fmove, IL12, ap1, ap2);	return;#endif /* FLOAT_IEEE */    default:	break;    }    if (ap2->mode == am_xreg) {	if (ap2->preg < ap2->sreg &&	    ap2->sreg < ap2->u.xreg && ap1->mode != am_xreg) {	    g_movem (ap1, mk_rmask ((REGMASK)				    REGBIT (ap2->preg) |				    REGBIT (ap2->sreg) |				    REGBIT (ap2->u.xreg)));	    return;	}    }    switch (ap2->mode) {    case am_adec:	g_move (IL4, mk_top (ap1), mk_top (ap2));	g_move (IL4, mk_high (ap1), mk_high (ap2));	g_move (IL4, mk_low (ap1), mk_low (ap2));	break;#ifdef FLOAT_IEEE    case am_freg:	g_fcode (op_fmove, IL12, ap1, ap2);	break;#endif /* FLOAT_IEEE */    default:#ifdef COLDFIRE	if (is_coldfire ()) {	    ADDRESS *ap = data_register ();	    g_move (IL4, mk_top (ap1), ap);	    g_move (IL4, ap, mk_top (ap2));	    g_move (IL4, mk_high (ap1), ap);	    g_move (IL4, ap, mk_high (ap2));	    g_move (IL4, mk_low (ap1), ap);	    g_move (IL4, ap, mk_low (ap2));	    freeop (ap);	    return;	}#endif /* COLDFIRE */	g_move (IL4, mk_top (ap1), mk_top (ap2));	g_move (IL4, mk_high (ap1), mk_high (ap2));	g_move (IL4, mk_low (ap1), mk_low (ap2));	break;    }}/* * mk_legal will coerce the addressing mode in ap into a mode that is * satisfactory for the flag word. */static ADDRESS *mk_legal P3 (ADDRESS *, ap, FLAGS, flags, const TYP *, tp){    ADDRESS *ap2;    ILEN    ilen = (ILEN) tp->size;    if (flags & F_NOVALUE) {	freeop (ap);	return NIL_ADDRESS;    }    if (ap == NIL_ADDRESS) {	FATAL ((__FILE__, "mk_legal", "ap = 0"));    }#ifdef COLDFIRE    if ((flags & F_COLD) && (ilen < IL4) && is_coldfire ()) {	ap = g_extend (ap, tp, is_unsigned_type (tp) ? tp_ulong : tp_long);    }#endif /* COLDFIRE */    switch (ap->mode) {    case am_immed:	if (flags & F_IMMED) {	    return ap;		/* mode ok */	}	break;    case am_areg:	if (flags & F_AREG	    && (!(flags & F_VOL) || is_temporary_register (ap->preg))) {	    return ap;	}	break;    case am_dreg:	if (flags & F_DREG	    && (!(flags & F_VOL) || is_temporary_register (ap->preg))) {	    return ap;	}	break;    case am_mreg:	if (flags & F_DREG &&	    (!(flags & F_VOL) || (is_temporary_register (ap->sreg) &&				  is_temporary_register (ap->preg))) &&	    (tp->size > 4L)) {	    return ap;	}	break;    case am_xreg:	if (flags & F_DREG &&	    (!(flags & F_VOL) || (is_temporary_register (ap->u.xreg) &&				  is_temporary_register (ap->sreg) &&				  is_temporary_register (ap->preg)))) {	    return ap;	}	break;    case am_ind:    case am_indx:    case am_indx2:    case am_indx3:    case am_indx4:    case am_direct:    case am_ainc:	if (flags & F_MEM) {	    return ap;	}	break;    case am_freg:	if ((flags & F_FREG)	    && (!(flags & F_VOL) || is_temporary_register (ap->preg))) {	    return ap;	}	break;    default:	break;    }    if ((flags & (F_DREG | F_AREG)) == (F_DREG | F_AREG)) {	/* decide, which mode is better */	if (ap->mode == am_immed) {	    if (is_byte (ap->u.offset)) {		flags = (FLAGS) (flags & F_DREG);	    } else if (is_short (ap->u.offset) && ilen == IL4) {		flags = (FLAGS) (flags & F_AREG);	    }	}	if (is_free_data () && (flags & F_DREG) && tp->type != bt_pointer32) {	    freeop (ap);	/* maybe we can use it... */	    ap2 = data_register ();	/* allocate to dreg */	    switch (ap->mode) {#ifdef FLOAT_IEEE	    case am_freg:		g_fcode (op_fmove, ilen, ap, ap2);		break;#endif /* FLOAT_IEEE */	    case am_mreg:		g_move (ilen, mk_high (ap), ap2);		break;	    default:		switch (ilen) {		case IL8:		    g_code (op_move, IL4, mk_high (ap), ap2);		    break;		default:		    g_move (ilen, ap, ap2);		    break;		}	    }	    return ap2;	}	if (is_free_addr () && (flags & F_AREG)) {	    freeop (ap);	    ap2 = address_register ();	    g_move (ilen, ap, ap2);	    return ap2;	}    }    if (flags & F_DREG) {	freeop (ap);		/* maybe we can use it... */	switch (ilen) {	case IL1:	case IL2:	case IL4:	    ap2 = data_register ();	/* allocate to dreg */	    switch (ap->mode) {#ifdef FLOAT_IEEE	    case am_freg:		g_fcode (op_fmove, ilen, ap, ap2);		break;#endif /* FLOAT_IEEE */	    case am_mreg:		g_move (ilen, mk_high (ap), ap2);		break;	    default:		g_move (ilen, ap, ap2);		break;	    }	    return ap2;	case IL8:	    ap2 = mdata_register ();	    g_move8 (ap, ap2);	    return ap2;	case IL12:	    ap2 = xdata_register ();	    g_move12 (ap, ap2);	    return ap2;	default:	    break;	}    }    if (flags & F_AREG) {	if (ilen < IL2) {	    FATAL (		   (__FILE__, "mk_legal",		    "illegal size %d --> An, mode=%d, flags=0x%x", ilen,		    ap->mode, (int) flags));	} else {	    freeop (ap);	    ap2 = address_register ();	    g_move (ilen, ap, ap2);	    return ap2;	}    }#ifdef FLOAT_IEEE    if (flags & F_FREG) {	freeop (ap);		/* maybe we can use it... */	switch (tp->type) {	case bt_float:	case bt_double:	case bt_longdouble:	    ap2 = float_register ();	    g_fcode (op_fmove, ilen, ap, ap2);	    return ap2;	case bt_char:	case bt_schar:	case bt_short:	case bt_int16:	case bt_long:	case bt_int32:	    ap2 = float_register ();	    g_code (op_fmove, ilen, ap, ap2);	    return ap2;	default:	    break;	}    }#endif /* FLOAT_IEEE */    if (flags & F_MEM) {	freeop (ap);	ap2 = mk_scratch (tp->size);	switch (tp->size) {	case 1L:	case 2L:	case 4L:	    g_move (ilen, ap, ap2);	    break;	case 8L:	    g_move8 (ap, ap2);

⌨️ 快捷键说明

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