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

📄 genarm.c

📁 一款拥有一定历史的C语言编译器
💻 C
📖 第 1 页 / 共 3 页
字号:
	if (ap2->mode == am_immed) {	    ap3 = copy_addr (ap1, am_lsl);	    ap3->offset = ap2->offset;	} else {	    ap3 = copy_addr (ap1, am_lslr);	    ap3->sreg = ap2->preg;	}	g_code (op_mov, cc_al, ap1, ap3, NIL_ADDRESS);	return mk_legal (ap1, flags);    default:	FATAL ((__FILE__, "g_lshift", "typ = %d", ep->etp->type));	break;    }    return NIL_ADDRESS;}#if 0static ADDRESS *g_aslshift P2 (const EXPR *, ep, FLAGS, flags){    FATAL ((__FILE__, "g_aslshift", "typ = %d", ep->etp->type));    return NIL_ADDRESS;}#endifstatic ADDRESS *g_rshift P2 (const EXPR *, ep, FLAGS, flags){    ADDRESS *ap1, *ap2, *ap3;    BOOL    sign = FALSE;    switch (ep->etp->type) {    case bt_int32:    case bt_long:	sign = TRUE;	/*FALLTHRU */    case bt_uint32:    case bt_ulong:    case bt_pointer32:	ap1 = g_expr (ep->v.p[0], F_REG);	ap2 = g_expr (ep->v.p[1], (FLAGS) (F_REG | F_IMMED));	validate (ap1);	freeop (ap2);	if (ap2->mode == am_immed) {	    ap3 = copy_addr (ap1, sign ? am_asr : am_lsr);	    ap3->offset = ap2->offset;	} else {	    ap3 = copy_addr (ap1, sign ? am_asrr : am_lsrr);	    ap3->sreg = ap2->preg;	}	g_code (op_mov, cc_al, ap1, ap3, NIL_ADDRESS);	return mk_legal (ap1, flags);    default:	FATAL ((__FILE__, "g_rshift", "typ = %d", ep->etp->type));	break;    }    return NIL_ADDRESS;}#if 0static ADDRESS *g_asrshift P2 (const EXPR *, ep, FLAGS, flags){    FATAL ((__FILE__, "g_asrshift", "typ = %d", ep->etp->type));    return NIL_ADDRESS;}#endif/* * Generate the code to extend the value in the register described by * 'ap' from type 'tp1' to the type 'tp2'. */static ADDRESS *g_extend P3 (ADDRESS *, ap, TYP *, tp1, TYP *, tp2){    ADDRESS *ap1;    AMODE   mode;    assert (ap->mode == am_reg);    switch (tp2->type) {    case bt_int16:    case bt_uint16:    case bt_short:    case bt_ushort:    case bt_int32:    case bt_uint32:    case bt_long:    case bt_ulong:    case bt_pointer32:	switch (tp1->type) {	case bt_char:	case bt_schar:	case bt_short:	case bt_int16:	    mode = am_asr;	    ap1 = mk_address (am_lsl, ap->preg, (4L - tp1->size) * 8L);	    g_code (op_mov, cc_al, ap, ap1, NIL_ADDRESS);	    ap1 = mk_address (mode, ap->preg, (4L - tp1->size) * 8L);	    g_code (op_mov, cc_al, ap, ap1, NIL_ADDRESS);	    return ap;	case bt_uchar:	case bt_charu:	case bt_ushort:	case bt_uint16:	    mode = am_lsr;	    ap1 = mk_address (am_lsl, ap->preg, (4L - tp1->size) * 8L);	    g_code (op_mov, cc_al, ap, ap1, NIL_ADDRESS);	    ap1 = mk_address (mode, ap->preg, (4L - tp1->size) * 8L);	    g_code (op_mov, cc_al, ap, ap1, NIL_ADDRESS);	    return ap;	case bt_int32:	case bt_long:	case bt_uint32:	case bt_ulong:	case bt_pointer32:	    return ap;	default:	    break;	}	break;    default:	break;    }    FATAL (	   (__FILE__, "g_extend", "typ1 = %d, typ2 = %d", tp1->type,	    tp2->type));    return NIL_ADDRESS;}static ADDRESS *g_cast P4 (ADDRESS *, ap, TYP *, tp1, TYP *, tp2, FLAGS,			   flags){    if (flags & F_NOVALUE) {	freeop (ap);	return NIL_ADDRESS;    }    switch (tp2->type) {    case bt_char:    case bt_charu:    case bt_uchar:    case bt_schar:	ap = mk_legal (ap, (FLAGS) (F_REG | F_VOL));	ap = g_extend (ap, tp1, tp2);	return mk_legal (ap, flags);    case bt_short:    case bt_int16:    case bt_ushort:    case bt_uint16:	ap = mk_legal (ap, (FLAGS) (F_REG | F_VOL));	ap = g_extend (ap, tp1, tp2);	return mk_legal (ap, flags);    case bt_int32:    case bt_long:    case bt_uint32:    case bt_ulong:    case bt_pointer32:    case bt_func:	ap = mk_legal (ap, (FLAGS) (F_REG | F_VOL));	ap = g_extend (ap, tp1, tp2);	return mk_legal (ap, flags);    default:	FATAL (	       (__FILE__, "g_cast", "typ1 = %d, typ2 = %d", tp1->type,		tp2->type));	break;    }    return NIL_ADDRESS;}/* * generate code for the assignment expression */static ADDRESS *g_assign P2 (const EXPR *, ep, FLAGS, flags){    ADDRESS *ap1;    ADDRESS *ap2;    switch (ep->v.p[0]->nodetype) {    case en_register:	ap1 = g_expr (ep->v.p[0], F_ALL);	ap2 = g_expr (ep->v.p[1], F_REG);	validate (ap1);	freeop (ap2);	return mk_legal (ap1, flags);    case en_ref:	ap1 = g_expr (ep->v.p[0], F_ALL);	ap2 = g_expr (ep->v.p[1], F_REG);	validate (ap1);	g_code (op_str, cc_al, ap1, ap2, NIL_ADDRESS);	freeop (ap2);	return mk_legal (ap1, flags);    default:	FATAL ((__FILE__, "g_assign", "nodetype = %d", ep->v.p[0]->nodetype));	break;    }    return NIL_ADDRESS;}/* * generate code to evaluate a condition operator node (?:) */static ADDRESS *g_hook P2 (const EXPR *, ep, FLAGS, flags){    ADDRESS *ap1, *ap2;    LABEL   false_label, end_label;    TYP    *tp = ep->etp;    SIZE    offset;    FLAGS   flagx;    switch (tp->type) {    case bt_void:	flagx = (FLAGS) (F_ALL | F_NOVALUE);	break;    case bt_struct:    case bt_union:	tp = tp_pointer;	/*FALLTHROUGH */    default:	flagx = (FLAGS) (F_REG | F_VOL);    }    false_label = nextlabel++;    end_label = nextlabel++;    temp_inv ();		/* I do not think I can avoid that */    offset = stack_offset;    stack_offset = 0L;    /* all registers are void */    g_falsejp (ep->v.p[0], false_label);    ep = ep->v.p[1];    /* all registers are void */    ap1 = g_expr (ep->v.p[0], flagx);    freeop (ap1);    /* all registers are void */    g_branch (end_label);    g_label (false_label);    ap2 = g_expr (ep->v.p[1], flagx);    g_label (end_label);    g_stack (stack_offset);    stack_offset = offset;    return mk_legal (ap2, flags);}/*--------------------------------------------------------------------------*/static SIZE push_param P1 (const EXPR *, ep){    (void) ep;    return 0L;}/* * generate the function return addressing mode */static ADDRESS *func_result P3 (FLAGS, flags, SIZE, size, const EXPR *, ep){    ADDRESS *ap;    (void) size;    (void) ep;    if (flags & F_NOVALUE) {	return NIL_ADDRESS;    }    ap = data_register ();    return ap;}/* * generate the parameters for a function call */static SIZE g_parms P1 (const EXPR *, ep){    SIZE    size;    for (size = 0L; ep != NIL_EXPR; ep = ep->v.p[1]) {	size += push_param (ep->v.p[0]);    }    return size;}/* * generate a function call node and return the addressing mode of the result */static ADDRESS *g_fcall P2 (const EXPR *, ep, FLAGS, flags){    ADDRESS *ap;    SIZE    size;    EXPR   *ep0 = ep->v.p[0];    if (!is_parameter) {	switch (stackopt_option) {	case 1:	    /*	     *               "Safe" stack optimisation.  Perform a stack optimisation	     *               unless:	     *               1.  The alloca() routine is called	     *               2.  The function call is via a variable	     *               3.  The function starts with an underscore character	     */	    if ((ep0->nodetype != en_nacon) ||		(ep0->v.str[0] == (CHAR) '_') || (ep0->v.str == alloca_name)) {		g_stack (stack_offset);	    }	    break;	case 2:	    /*	     *               "Forced" stack optimisation.   This will not suppress	     *               the optimisation on encountering calls to functions	     *               whose names begin with underscore.	     */	    if ((ep0->nodetype != en_nacon) || (ep0->v.str == alloca_name)) {		g_stack (stack_offset);	    }	    break;	default:	case 0:	    /*	     *               no stack optimisation	     */	    g_stack (stack_offset);	    break;	}    }    temp_inv ();		/* push any used temporary registers */    size = g_parms (ep0);	/* generate parameters */    switch (ep0->nodetype) {    case en_nacon:    case en_labcon:	ap = mk_direct (ep0);	g_code (op_bl, cc_al, ap, NIL_ADDRESS, NIL_ADDRESS);	break;    default:	ap = g_expr (ep0, F_REG);	g_code (op_mov, cc_al, mk_reg (R15), ap, NIL_ADDRESS);	break;    }    return func_result (flags, size, ep);}#ifdef ASMstatic ADDRESS *g_asm P1 (const EXPR *, ep){    ADDRESS *ap = mk_amode (am_str);    ap->offset = copynode (ep);    g_code (op_asm, cc_al, ap, NIL_ADDRESS, NIL_ADDRESS);    return NIL_ADDRESS;}#endif /* ASM *//*--------------------------------------------------------------------------*//* * general expression evaluation.  returns the addressing mode of the result */static ADDRESS *g_expr P2 (const EXPR *, ep, FLAGS, flags){    ADDRESS *ap1;    LABEL   lab0, lab1;    CONDITION cc;    static CONDITION reverse_cc[] = {	cc_nv,			/* cc_al */	cc_cs,			/* cc_cc */	cc_cc,			/* cc_cs */	cc_ne,			/* cc_eq */	cc_lt,			/* cc_ge */	cc_le,			/* cc_gt */	cc_ls,			/* cc_hi */	cc_gt,			/* cc_le */	cc_hi,			/* cc_ls */	cc_ge,			/* cc_lt */	cc_pl,			/* cc_mi */	cc_eq,			/* cc_ne */	cc_al,			/* cc_nv */	cc_mi,			/* cc_pl */	cc_vs,			/* cc_vc */	cc_vc			/* cc_vs */    };    if (tst_const (ep)) {	ap1 = mk_amode (am_immed);	ap1->offset = copynode (ep);	return mk_legal (ap1, flags);    }    switch (ep->nodetype) {    case en_register:	ap1 = mk_reg (ep->v.r);	return mk_legal (ap1, flags);    case en_ref:	ap1 = g_deref (ep->v.p[0], flags);	return mk_legal (ap1, flags);    case en_uminus:	return g_uminus (ep, flags);    case en_compl:	return g_negate (ep, flags);    case en_add:	return g_add (ep, flags, op_add);    case en_sub:	return g_add (ep, flags, op_sub);    case en_mul:	return g_mul (ep, flags);    case en_div:	return g_div (ep, flags);    case en_mod:	return g_mod (ep, flags);    case en_and:	return g_logic (ep, flags, op_and);    case en_or:	return g_logic (ep, flags, op_orr);    case en_xor:	return g_logic (ep, flags, op_eor);    case en_lsh:	return g_lshift (ep, flags);    case en_rsh:	return g_rshift (ep, flags);    case en_asadd:	return g_asadd (ep, flags, op_add);    case en_assub:	return g_asadd (ep, flags, op_sub);    case en_asmul:	return g_asmul (ep, flags);    case en_asdiv:	return g_asdiv (ep, flags);    case en_asmod:	return g_asmod (ep, flags);    case en_asand:	return g_aslogic (ep, flags, op_and);    case en_asor:	return g_aslogic (ep, flags, op_orr);    case en_asxor:	return g_aslogic (ep, flags, op_eor);    case en_aslsh:	return g_lshift (ep, flags);    case en_asrsh:	return g_rshift (ep, flags);    case en_assign:	return g_assign (ep, flags);    case en_comma:	freeop (g_expr (ep->v.p[0], (FLAGS) (F_ALL | F_NOVALUE)));	return g_expr (ep->v.p[1], flags);    case en_cast:	return g_cast (g_expr (ep->v.p[0], F_ALL),		       ep->v.p[0]->etp, ep->etp, flags);    case en_eq:	cc = cc_eq;	VOIDCAST g_compare (ep);	goto cont1;    case en_ne:	cc = cc_eq;	VOIDCAST g_compare (ep);	goto cont1;    case en_lt:	cc = g_compare (ep) ? cc_cc : cc_lt;	goto cont1;    case en_le:	cc = g_compare (ep) ? cc_ls : cc_le;	goto cont1;    case en_gt:	cc = g_compare (ep) ? cc_hi : cc_gt;	goto cont1;    case en_ge:	cc = g_compare (ep) ? cc_cs : cc_ge;      cont1:	ap1 = data_register ();	g_code (op_mov, cc, ap1, mk_immed (1L), NIL_ADDRESS);	g_code (op_mov, reverse_cc[cc], ap1, mk_immed (0L), NIL_ADDRESS);	return mk_legal (ap1, flags);    case en_land:    case en_lor:    case en_not:	lab0 = nextlabel++;	lab1 = nextlabel++;	g_falsejp (ep, lab0);	ap1 = data_register ();	g_code (op_mov, cc_al, ap1, mk_immed (1L), NIL_ADDRESS);	g_branch (lab1);	g_code (op_mov, cc_al, ap1, mk_immed (0L), NIL_ADDRESS);	g_label (lab1);	return mk_legal (ap1, flags);    case en_cond:	return g_hook (ep, flags);    case en_fcall:    case en_call:
    case en_usercall:	return g_fcall (ep, flags);#ifdef ASM    case en_str:	return g_asm (ep);#endif /* ASM */    default:	FATAL ((__FILE__, "g_expr", "uncoded ep %d", ep->nodetype));	break;    }    return NIL_ADDRESS;}PRIVATE void g_expression P1 (const EXPR *, ep){    initstack ();    if (ep != NIL_EXPR) {	VOIDCAST g_expr (ep, (FLAGS) (F_ALL | F_NOVALUE));    }    checkstack ();}/* * generate code to do a comparison of the two operands of node. returns 1 if * it was an unsigned comparison */static BOOL g_compare P1 (const EXPR *, ep){    ADDRESS *ap1, *ap2;    BOOL    sign = FALSE;    switch (ep->v.p[0]->etp->type) {    case bt_char:    case bt_schar:    case bt_short:    case bt_int16:    case bt_int32:    case bt_long:	sign = TRUE;	/*FALLTHRU */    case bt_uchar:    case bt_charu:    case bt_ushort:    case bt_uint16:    case bt_uint32:    case bt_ulong:    case bt_pointer32:	ap2 = g_expr (ep->v.p[1], F_ALL);	ap1 = g_expr (ep->v.p[0], F_REG);	validate (ap2);	g_code (op_cmps, cc_al, ap1, ap2, NIL_ADDRESS);	freeop (ap1);	freeop (ap2);	return sign;    default:	FATAL ((__FILE__, "g_compare", "typ = %d", ep->etp->type));	break;    }    return FALSE;}/* * Test the expression and set the condition codes accordingly

⌨️ 快捷键说明

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