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

📄 gexpr386.c

📁 本程序集是Allen I. Holub所写的《Compiler Design in C》一书的附随软件
💻 C
📖 第 1 页 / 共 5 页
字号:
 */
{       AMODE    *ap1, *ap2, *ap3;
        int             ssize,rsize;
        ssize = natural_size(node->v.p[0]);
        rsize = natural_size(node->v.p[1]);
				if (rsize == 0)
					rsize = ssize;
				if (rsize > 4) {
					ap2 = gen_expr(node->v.p[0],F_FREG,rsize);
					ap3 = gen_expr(node->v.p[0],F_MEM,ssize);
					ap1 = gen_expr(node->v.p[1],F_FREG | F_MEM,rsize);
					if (ap1->mode == am_freg)
						gen_code(fop,0,0,0);
					else {
						if (rsize <= 4)
							if (fop == op_fadd)
								fop = op_fiadd;
							else
								fop = op_fisub;
						gen_f10code(fop,rsize,ap1,0);
					}
					floatstore(ap3,ssize,flags);
					gen_codef(op_fwait,0,0,0);
					if (!(flags & F_NOVALUE)) {
						ap2 = fstack();
						do_extend(ap2,ssize,size,flags);
						make_legal(ap2,flags,size);
					}
					return ap2;
				}
        if (chksize( ssize ,rsize ))
                rsize = ssize;
      	  ap2 = gen_expr(node->v.p[0],F_ALL | F_NOBIT | F_DEST,ssize);
				mark();
        ap1 = gen_expr(node->v.p[1],F_DREG | F_IMMED,rsize);
				if (node->v.p[0]->nodetype == en_bits)
					ap3= get_bitval(ap2,node->v.p[0],ssize);
				if (node->v.p[0]->nodetype == en_bits) {
					gen_code(op,ssize,ap3,ap1);
					bit_move(ap2,ap3,node->v.p[0],flags, ssize,rsize);
					freeop(ap3);
				}
				else
       		gen_code(op,ssize,ap2,ap1);
				freeop(ap1);
				release();
				if (flags & F_NOVALUE)
					freeop(ap2);
				else {
					do_extend(ap2,ssize,size,flags);
       		make_legal(ap2,flags,4);
				}
        return ap2;
}

AMODE    *gen_aslogic(ENODE *node, int flags, int size, int op)
/*
 *      generate a and equal or a or equal node.
 */
{       AMODE    *ap1, *ap2;
        int             ssize,rsize;
        ssize = natural_size(node->v.p[0]);
        rsize = natural_size(node->v.p[1]);
        if (chksize( ssize , rsize ))
                rsize = ssize;
			
      	  ap2 = gen_expr(node->v.p[0],F_ALL | F_NOBIT | F_DEST,ssize);
				mark();
        ap1 = gen_expr(node->v.p[1],F_DREG | F_IMMED,rsize);
				if (node->v.p[0]->nodetype == en_bits) {
					if (ap1->mode == am_immed) {
						ap1->offset->v.i &= bittab[node->v.p[0]->bits-1];
						ap1->offset->v.i <<= node->v.p[0]->startbit;
						gen_code(op,ssize,ap2,ap1);
					}
					else {
					  gen_code(op_and,ssize,ap1,make_immed(bittab[node->v.p[0]->bits-1]));
						if (node->v.p[0]->startbit)
					  	gen_code(op_shl,ssize,ap1,make_immed(node->v.p[0]->startbit));
						gen_code(op,ssize,ap2,ap1);
						if (!(flags & F_NOVALUE)) {
							freeop(ap1);
							release();
							if (node->v.p[0]->startbit)
					  		gen_code(op_shr,ssize,ap2,make_immed(node->v.p[0]->startbit));
        			do_extend(ap2,ssize,size,0);
							make_legal(ap2,F_DREG,size);
							return(ap2);
						}
					}
				}
				else
        	gen_code(op,ssize,ap2,ap1);
				freeop(ap1);
				release();
				if (flags & F_NOVALUE)
					freeop(ap2);
				else {
					do_extend(ap2,ssize,size,flags);
        	make_legal(ap2,flags,4);
				}
        return ap2;
}

AMODE *gen_asshift(ENODE *node, int flags, int size, int op)
/*
 *      generate shift equals operators.
 */
{       
        AMODE    *ap1, *ap2, *ap3;
        int ssize = natural_size(node->v.p[0]);
        int rsize = natural_size(node->v.p[1]);
        if (chksize( ssize , rsize ))
                rsize = rsize;
      	  ap2 = gen_expr(node->v.p[0],F_ALL | F_NOBIT | F_DEST,ssize);
				mark();
        ap1 = gen_expr(node->v.p[1],F_DREG | F_IMMED,rsize);
				if (node->v.p[0]->nodetype == en_bits)
					ap3 = get_bitval(ap2,node->v.p[0],ssize);
				else
					ap3 = ap2;

				doshift(ap3,ap1,ssize,op);
				if (node->v.p[0]->nodetype == en_bits)
					bit_move(ap2,ap3,node->v.p[0],flags,ssize,rsize);
				freeop(ap1);
				release();
				if (ap3 != ap1)
					freeop(ap3);
				if (flags & F_NOVALUE)
					freeop(ap2);
				else {
					do_extend(ap2,ssize,size,flags);
       		make_legal(ap2,flags,4);
				}
        	return ap2;
}

AMODE    *gen_asmul(ENODE *node, int flags, int size,int op)
/*
 *      generate a *= node.
 */
{       AMODE    *ap1, *ap2,*ap3;
        int             ssize, lsize,rsize;
        ssize = natural_size(node->v.p[0]);
        rsize = natural_size(node->v.p[1]);
				if (rsize == 0)
					rsize = ssize;
				if (rsize > 4) {
					int fop = op_fmul;
					ap2 = gen_expr(node->v.p[0],F_FREG,rsize);
					ap3 = gen_expr(node->v.p[0],F_MEM,ssize);
					ap1 = gen_expr(node->v.p[1],F_FREG | F_MEM,rsize);
					if (ap1->mode == am_freg)
						gen_code(fop,0,0,0);
					else {
						if (rsize <= 4)
							fop = op_fimul;
						gen_f10code(fop,ssize,ap1,0);
					}
					floatstore(ap3,ssize,flags);
					gen_codef(op_fwait,0,0,0);
					if (!(flags & F_NOVALUE)) {
						ap2 = fstack();
						do_extend(ap2,ssize,size,flags);
						make_legal(ap2,flags,size);
					}
					return ap2;
				}
				if (op == op_imul)
					lsize= -4;
				else
					lsize = 4;
      	ap2 = gen_expr(node->v.p[0],F_ALL | F_NOBIT | F_DEST,ssize);
				mark();
    	  ap1 = gen_expr(node->v.p[1],F_ALL,lsize);
				ap3 = xalloc(sizeof(AMODE));
				ap3->mode = ap2->mode;
				ap3->preg = ap2->preg;
				ap3->sreg = ap2->sreg;
				ap3->scale = ap2->scale;
				ap3->offset = ap2->offset;
				if (node->v.p[0]->nodetype == en_bits)
					ap2 = get_bitval(ap2,node->v.p[0],ssize);
				else {
        	make_legal(ap2,F_DREG | F_VOL,4);
					do_extend(ap2,ssize,lsize,F_DREG);
				}
				domul(ap2,ap1,lsize,op);
				freeop(ap1);
				release();
				if (!equal_address(ap2,ap3))
					if (node->v.p[0]->nodetype == en_bits)
						bit_move(ap3,ap2,node->v.p[0],flags,ssize,rsize);
					else
						gen_code(op_mov,ssize,ap3,ap2);
				if (flags & F_NOVALUE)
					freeop(ap2);
				else {
					do_extend(ap2,ssize,size,flags);
       		make_legal(ap2,flags,4);
				}
        return ap2;
}

AMODE    *gen_asmodiv(ENODE *node, int flags, int size, int op, int modflag)
/*
 *      generate /= and %= nodes.
 */
{       AMODE    *ap1, *ap2,*ap3;
        int             ssize,lsize,rsize;
        ssize = natural_size(node->v.p[0]);
        rsize = natural_size(node->v.p[1]);
				if (rsize == 0)
					rsize = ssize;
				if (rsize > 4) {
					int fop = op_fdiv;
					ap2 = gen_expr(node->v.p[0],F_FREG,rsize);
					ap3 = gen_expr(node->v.p[0],F_MEM,ssize);
					ap1 = gen_expr(node->v.p[1],F_FREG | F_MEM,rsize);
					if (ap1->mode == am_freg)
						gen_code(fop,0,0,0);
					else {
						if (rsize <= 4)
							fop = op_fidiv;
						gen_f10code(fop,ssize,ap1,0);
					}
					floatstore(ap3,ssize,flags);
					gen_codef(op_fwait,0,0,0);
					if (!(flags & F_NOVALUE)) {
						ap2 = fstack();
						do_extend(ap2,ssize,size,flags);
						make_legal(ap2,flags,size);
					}
					return ap2;
				}                                                   
				if (op == op_idiv)                                  
					lsize= -4;                                        
				else                                                
					lsize = 4;                                        
			                                                      
     	  ap2 = gen_expr(node->v.p[0],F_ALL | F_NOBIT | F_DEST, ssize);         
				mark();
   	    ap1 = gen_expr(node->v.p[1],F_ALL,lsize);         
				ap3 = xalloc(sizeof(AMODE));                      
				ap3->mode = ap2->mode;                            
				ap3->preg = ap2->preg;                            
				ap3->sreg = ap2->sreg;                            
				ap3->scale = ap2->scale;                          
				ap3->offset = ap2->offset;
				if (node->v.p[0]->nodetype == en_bits)
					ap2 = get_bitval(ap2,node->v.p[0],ssize);
				else {
        	make_legal(ap2,F_DREG | F_VOL,4);
					do_extend(ap2,ssize,lsize,F_DREG);
				}
				dodiv(ap2,ap1,ssize,op,modflag);                  
				freeop(ap1);
				release();
				if (!equal_address(ap2,ap3))
					if (node->v.p[0]->nodetype == en_bits)
						bit_move(ap3,ap2,node->v.p[0],flags,ssize,rsize);
					else
						gen_code(op_mov,ssize,ap3,ap2);
				if (flags & F_NOVALUE)                              
					freeop(ap2);                                      
				else {
					do_extend(ap2,ssize,size,flags);
       		make_legal(ap2,flags,4);
				}
       	return ap2;                                       
}
AMODE *gen_moveblock(ENODE *node, int flags, int size)      
{                                                           
	AMODE *ap1, *ap2;                                         
	if (!node->size)                                          
		return(0);
	ap2 = gen_expr(node->v.p[1],F_DREG | F_VOL,4);                     
	mark();
	ap1 = gen_expr(node->v.p[0],F_DREG | F_VOL,4);                     
	gen_push(ESI,am_dreg,0);                                  
	gen_push(EDI,am_dreg,0);                                  
	if (regs[1])                                              
		gen_push(ECX,am_dreg,0);                                
	gen_code(op_mov,4,makedreg(ESI),ap2);		                  
	gen_code(op_mov,4,makedreg(EDI),ap1);                     
	gen_code(op_mov,4,makedreg(ECX),make_immed(node->size));  
	gen_code(op_cld,0,0,0);
	gen_code(op_rep,1,0,0);                                   
	gen_code(op_movsb,1,0,0);		                              
	if (regs[1])                                              
		gen_pop(ECX,am_dreg,0);
	gen_pop(EDI,am_dreg,0);
	gen_pop(ESI,am_dreg,0);
	freeop(ap2);
	freeop(ap1);
	release();
	return(ap2);
}
AMODE    *gen_assign(ENODE *node, int flags, int size)
/*
 *      generate code for an assignment node. if the size of the
 *      assignment destination is larger than the size passed then
 *      everything below this node will be evaluated with the
 *      assignment size.
 */
{       AMODE    *ap1, *ap2, *ap3,*ap4 = 0;
        int             ssize,rsize;
				rsize = natural_size(node->v.p[1]);
        switch( node->v.p[0]->nodetype )
                {
								case en_bits:
												ssize = natural_size(node->v.p[0]);
												break;
                case en_ub_ref:
								case en_cub:
                        ssize = 1;
                        break;
                case en_b_ref:
								case en_cb:
                        ssize = -1;
                        break;
                case en_uw_ref:
								case en_cuw:
                        ssize = 2;
                        break;
                case en_w_ref:
								case en_cw:
                        ssize = -2;
                        break;
                case en_l_ref:
								case en_cl:
												ssize = -4;
												break;
                case en_ul_ref:
								case en_cul:
								case en_cp:
                        ssize = 4;
                        break;
                case en_tempref:
                case en_regref:
												ssize = node->v.p[0]->v.i >> 8;
												break;
								case en_floatref:
								case en_cf:
												ssize = 6;
												break;
								case en_doubleref:
								case en_cd:
												ssize = 8;
												break;
								case en_longdoubleref:
								case en_cld:
												ssize = 10;
												break;
								default:
												ssize = -4;
                }
        if (chksize( ssize , rsize ))
                rsize = ssize;
        ap2 = gen_expr(node->v.p[1],F_DREG | F_FREG | F_IMMED,rsize);
				mark();
        ap1 = gen_expr(node->v.p[0],F_ALL | F_NOBIT | F_DEST,ssize);
				if (!equal_address(ap1,ap2)	) {
					if (rsize > 4) {
						floatstore(ap1,ssize,flags);
						gen_codef(op_fwait,0,0,0);
					}
					else {
						if (node->v.p[0]->nodetype == en_bits) {
							bit_move(ap1,ap2,node->v.p[0],flags,ssize,rsize);
						}
						else {
							if (ap2->mode != am_dreg && ap2->mode != am_immed
										&& ap1->mode != am_dreg) {
								freeop(ap2);
								ap3 = temp_data();
								gen_code(op_mov,ssize,ap3,ap2);
								gen_code(op_mov,ssize,ap1,ap3);
							}
							else {
  	      			gen_code(op_mov,ssize,ap1,ap2);
							}
						}
					}
				}
				release();
				if (flags & F_NOVALUE)
					freeop(ap2);
				else {
					do_extend(ap2,ssize,size,flags);
					make_legal(ap2,flags,size);
				}
        return ap2;
}
AMODE    *gen_refassign(ENODE *node, int flags, int size)
/*
 *      generate code for an assignment node. if the size of the
 *      assignment destination is larger than the size passed then
 *      everything below this node will be evaluated with the
 *      assignment size.
 */
{       AMODE    *ap1, *ap2, *ap3,*ap4;
        int             ssize,rsize;
				rsize = natural_size(node->v.p[1]);
        switch( node->v.p[0]->nodetype )
                {
								case en_bits:
												ssize = natural_size(node->v.p[0]);
												break;
                case en_ub_ref:
								case en_cub:
                        ssize = 1;
                        break;
                case en_b_ref:
								case en_cb:
                        ssize = -1;
                        break;
                case en_uw_ref:
								case en_cuw:
                        ssize = 2;
                        break;
                case en_w_ref:
								case en_cw:
                        ssize = -2;
                        break;
                case en_l_ref:
								case en_cl:
												ssize = -4;
												break;
                case en_ul_ref:

⌨️ 快捷键说明

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