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

📄 dt_cg.c

📁 Sun Solaris 10 中的 DTrace 组件的源代码。请参看: http://www.sun.com/software/solaris/observability.jsp
💻 C
📖 第 1 页 / 共 4 页
字号:
		dt_cg_compare_op(dnp, dlp, drp,		    dt_cg_compare_signed(dnp) ? DIF_OP_BL : DIF_OP_BLU);		break;	case DT_TOK_LE:		dt_cg_compare_op(dnp, dlp, drp,		    dt_cg_compare_signed(dnp) ? DIF_OP_BLE : DIF_OP_BLEU);		break;	case DT_TOK_GT:		dt_cg_compare_op(dnp, dlp, drp,		    dt_cg_compare_signed(dnp) ? DIF_OP_BG : DIF_OP_BGU);		break;	case DT_TOK_GE:		dt_cg_compare_op(dnp, dlp, drp,		    dt_cg_compare_signed(dnp) ? DIF_OP_BGE : DIF_OP_BGEU);		break;	case DT_TOK_LSH:		dt_cg_arithmetic_op(dnp, dlp, drp, DIF_OP_SLL);		break;	case DT_TOK_RSH:		dt_cg_arithmetic_op(dnp, dlp, drp,		    (dnp->dn_flags & DT_NF_SIGNED) ? DIF_OP_SRA : DIF_OP_SRL);		break;	case DT_TOK_ADD:		dt_cg_arithmetic_op(dnp, dlp, drp, DIF_OP_ADD);		break;	case DT_TOK_SUB:		dt_cg_arithmetic_op(dnp, dlp, drp, DIF_OP_SUB);		break;	case DT_TOK_MUL:		dt_cg_arithmetic_op(dnp, dlp, drp, DIF_OP_MUL);		break;	case DT_TOK_DIV:		dt_cg_arithmetic_op(dnp, dlp, drp,		    (dnp->dn_flags & DT_NF_SIGNED) ? DIF_OP_SDIV : DIF_OP_UDIV);		break;	case DT_TOK_MOD:		dt_cg_arithmetic_op(dnp, dlp, drp,		    (dnp->dn_flags & DT_NF_SIGNED) ? DIF_OP_SREM : DIF_OP_UREM);		break;	case DT_TOK_LNEG:		dt_cg_logical_neg(dnp, dlp, drp);		break;	case DT_TOK_BNEG:		dt_cg_node(dnp->dn_child, dlp, drp);		dnp->dn_reg = dnp->dn_child->dn_reg;		instr = DIF_INSTR_NOT(dnp->dn_reg, dnp->dn_reg);		dt_irlist_append(dlp, dt_cg_node_alloc(DT_LBL_NONE, instr));		break;	case DT_TOK_PREINC:		dt_cg_prearith_op(dnp, dlp, drp, DIF_OP_ADD);		break;	case DT_TOK_POSTINC:		dt_cg_postarith_op(dnp, dlp, drp, DIF_OP_ADD);		break;	case DT_TOK_PREDEC:		dt_cg_prearith_op(dnp, dlp, drp, DIF_OP_SUB);		break;	case DT_TOK_POSTDEC:		dt_cg_postarith_op(dnp, dlp, drp, DIF_OP_SUB);		break;	case DT_TOK_IPOS:		dt_cg_node(dnp->dn_child, dlp, drp);		dnp->dn_reg = dnp->dn_child->dn_reg;		break;	case DT_TOK_INEG:		dt_cg_node(dnp->dn_child, dlp, drp);		dnp->dn_reg = dnp->dn_child->dn_reg;		instr = DIF_INSTR_FMT(DIF_OP_SUB, DIF_REG_R0,		    dnp->dn_reg, dnp->dn_reg);		dt_irlist_append(dlp, dt_cg_node_alloc(DT_LBL_NONE, instr));		break;	case DT_TOK_DEREF:		dt_cg_node(dnp->dn_child, dlp, drp);		dnp->dn_reg = dnp->dn_child->dn_reg;		if (!(dnp->dn_flags & DT_NF_REF)) {			uint_t ubit = dnp->dn_flags & DT_NF_USERLAND;			/*			 * Save and restore DT_NF_USERLAND across dt_cg_load():			 * we need the sign bit from dnp and the user bit from			 * dnp->dn_child in order to get the proper opcode.			 */			dnp->dn_flags |=			    (dnp->dn_child->dn_flags & DT_NF_USERLAND);			instr = DIF_INSTR_LOAD(dt_cg_load(dnp, ctfp,			    dnp->dn_type), dnp->dn_reg, dnp->dn_reg);			dnp->dn_flags &= ~DT_NF_USERLAND;			dnp->dn_flags |= ubit;			dt_irlist_append(dlp,			    dt_cg_node_alloc(DT_LBL_NONE, instr));		}		break;	case DT_TOK_ADDROF: {		uint_t rbit = dnp->dn_child->dn_flags & DT_NF_REF;		dnp->dn_child->dn_flags |= DT_NF_REF; /* force pass-by-ref */		dt_cg_node(dnp->dn_child, dlp, drp);		dnp->dn_reg = dnp->dn_child->dn_reg;		dnp->dn_child->dn_flags &= ~DT_NF_REF;		dnp->dn_child->dn_flags |= rbit;		break;	}	case DT_TOK_SIZEOF: {		size_t size = dt_node_sizeof(dnp->dn_child);		if ((dnp->dn_reg = dt_regset_alloc(drp)) == -1)			longjmp(yypcb->pcb_jmpbuf, EDT_NOREG);		assert(size != 0);		dt_cg_setx(dlp, dnp->dn_reg, size);		break;	}	case DT_TOK_STRINGOF:		dt_cg_node(dnp->dn_child, dlp, drp);		dnp->dn_reg = dnp->dn_child->dn_reg;		break;	case DT_TOK_XLATE:		dt_cg_node(dnp->dn_right, dlp, drp);		dnp->dn_reg = dnp->dn_right->dn_reg;		break;	case DT_TOK_LPAR:		dt_cg_node(dnp->dn_right, dlp, drp);		dnp->dn_reg = dnp->dn_right->dn_reg;		dt_cg_typecast(dnp->dn_right, dnp, dlp, drp);		break;	case DT_TOK_PTR:	case DT_TOK_DOT:		assert(dnp->dn_right->dn_kind == DT_NODE_IDENT);		dt_cg_node(dnp->dn_left, dlp, drp);		/*		 * If the left-hand side of PTR or DOT is a dynamic variable,		 * we expect it to be the output of a D translator.   In this		 * case, we look up the parse tree corresponding to the member		 * that is being accessed and run the code generator over it.		 * We then cast the result as if by the assignment operator.		 */		if (dt_node_is_dynamic(dnp->dn_left)) {			dt_ident_t *idp;			dt_xlator_t *dxp;			dt_node_t *mnp;			idp = dt_ident_resolve(dnp->dn_left->dn_ident);			assert(idp->di_kind == DT_IDENT_XLSOU ||			    idp->di_kind == DT_IDENT_XLPTR);			dxp = idp->di_data;			mnp = dt_xlator_member(dxp, dnp->dn_right->dn_string);			assert(mnp != NULL);			dxp->dx_ident->di_flags |= DT_IDFLG_CGREG;			dxp->dx_ident->di_id = dnp->dn_left->dn_reg;			dt_cg_node(mnp->dn_membexpr, dlp, drp);			dnp->dn_reg = mnp->dn_membexpr->dn_reg;			dt_cg_typecast(mnp->dn_membexpr, dnp, dlp, drp);			dxp->dx_ident->di_flags &= ~DT_IDFLG_CGREG;			dxp->dx_ident->di_id = 0;			dt_regset_free(drp, dnp->dn_left->dn_reg);			break;		}		ctfp = dnp->dn_left->dn_ctfp;		type = ctf_type_resolve(ctfp, dnp->dn_left->dn_type);		if (dnp->dn_op == DT_TOK_PTR) {			type = ctf_type_reference(ctfp, type);			type = ctf_type_resolve(ctfp, type);		}		if ((ctfp = dt_cg_membinfo(octfp = ctfp, type,		    dnp->dn_right->dn_string, &m)) == NULL) {			yypcb->pcb_hdl->dt_ctferr = ctf_errno(octfp);			longjmp(yypcb->pcb_jmpbuf, EDT_CTF);		}		if (m.ctm_offset != 0) {			if ((reg = dt_regset_alloc(drp)) == -1)				longjmp(yypcb->pcb_jmpbuf, EDT_NOREG);			/*			 * If the offset is not aligned on a byte boundary, it			 * is a bit-field member and we will extract the value			 * bits below after we generate the appropriate load.			 */			dt_cg_setx(dlp, reg, m.ctm_offset / NBBY);			instr = DIF_INSTR_FMT(DIF_OP_ADD,			    dnp->dn_left->dn_reg, reg, dnp->dn_left->dn_reg);			dt_irlist_append(dlp,			    dt_cg_node_alloc(DT_LBL_NONE, instr));			dt_regset_free(drp, reg);		}		if (!(dnp->dn_flags & DT_NF_REF)) {			uint_t ubit = dnp->dn_flags & DT_NF_USERLAND;			/*			 * Save and restore DT_NF_USERLAND across dt_cg_load():			 * we need the sign bit from dnp and the user bit from			 * dnp->dn_left in order to get the proper opcode.			 */			dnp->dn_flags |=			    (dnp->dn_left->dn_flags & DT_NF_USERLAND);			instr = DIF_INSTR_LOAD(dt_cg_load(dnp,			    ctfp, m.ctm_type), dnp->dn_left->dn_reg,			    dnp->dn_left->dn_reg);			dnp->dn_flags &= ~DT_NF_USERLAND;			dnp->dn_flags |= ubit;			dt_irlist_append(dlp,			    dt_cg_node_alloc(DT_LBL_NONE, instr));			if (dnp->dn_flags & DT_NF_BITFIELD)				dt_cg_field_get(dnp, dlp, drp, ctfp, &m);		}		dnp->dn_reg = dnp->dn_left->dn_reg;		break;	case DT_TOK_STRING:		if ((dnp->dn_reg = dt_regset_alloc(drp)) == -1)			longjmp(yypcb->pcb_jmpbuf, EDT_NOREG);		assert(dnp->dn_kind == DT_NODE_STRING);		stroff = dt_strtab_insert(yypcb->pcb_strtab, dnp->dn_string);		if (stroff == -1L)			longjmp(yypcb->pcb_jmpbuf, EDT_NOMEM);		if (stroff > DIF_STROFF_MAX)			longjmp(yypcb->pcb_jmpbuf, EDT_STR2BIG);		instr = DIF_INSTR_SETS((ulong_t)stroff, dnp->dn_reg);		dt_irlist_append(dlp, dt_cg_node_alloc(DT_LBL_NONE, instr));		break;	case DT_TOK_IDENT:		/*		 * If the specified identifier is a variable on which we have		 * set the code generator register flag, then this variable		 * has already had code generated for it and saved in di_id.		 * Allocate a new register and copy the existing value to it.		 */		if (dnp->dn_kind == DT_NODE_VAR &&		    (dnp->dn_ident->di_flags & DT_IDFLG_CGREG)) {			if ((dnp->dn_reg = dt_regset_alloc(drp)) == -1)				longjmp(yypcb->pcb_jmpbuf, EDT_NOREG);			instr = DIF_INSTR_MOV(dnp->dn_ident->di_id,			    dnp->dn_reg);			dt_irlist_append(dlp,			    dt_cg_node_alloc(DT_LBL_NONE, instr));			break;		}		/*		 * Identifiers can represent function calls, variable refs, or		 * symbols.  First we check for inlined variables, and handle		 * them by generating code for the inline parse tree, and then		 * casting the result to the inline's output type.		 */		if (dnp->dn_kind == DT_NODE_VAR &&		    (dnp->dn_ident->di_flags & DT_IDFLG_INLINE)) {			dt_idnode_t *inp = dnp->dn_ident->di_data;			dt_cg_node(inp->din_root, dlp, drp);			dnp->dn_reg = inp->din_root->dn_reg;			dt_cg_typecast(inp->din_root, dnp, dlp, drp);			break;		}		switch (dnp->dn_kind) {		case DT_NODE_FUNC: {			dt_ident_t *idp = dnp->dn_ident;			if (idp->di_kind != DT_IDENT_FUNC) {				yylineno = dnp->dn_line;				xyerror(D_CG_EXPR, "%s %s( ) may not be "				    "called from a D expression (D program "				    "context required)\n",				    dt_idkind_name(idp->di_kind), idp->di_name);			}			dt_cg_arglist(dnp->dn_ident, dnp->dn_args, dlp, drp);			if ((dnp->dn_reg = dt_regset_alloc(drp)) == -1)				longjmp(yypcb->pcb_jmpbuf, EDT_NOREG);			instr = DIF_INSTR_CALL(			    dnp->dn_ident->di_id, dnp->dn_reg);			dt_irlist_append(dlp,			    dt_cg_node_alloc(DT_LBL_NONE, instr));			break;		}		case DT_NODE_VAR:			if (dnp->dn_ident->di_kind == DT_IDENT_XLSOU ||			    dnp->dn_ident->di_kind == DT_IDENT_XLPTR) {				/*				 * This can only happen if we have translated				 * args[].				 */				assert(dnp->dn_ident->di_id == DIF_VAR_ARGS);				dt_cg_array_op(dnp, dlp, drp);				break;			}			if (dnp->dn_ident->di_kind == DT_IDENT_ARRAY) {				if (dnp->dn_ident->di_id > DIF_VAR_ARRAY_MAX)					dt_cg_assoc_op(dnp, dlp, drp);				else					dt_cg_array_op(dnp, dlp, drp);				break;			}			if ((dnp->dn_reg = dt_regset_alloc(drp)) == -1)				longjmp(yypcb->pcb_jmpbuf, EDT_NOREG);			if (dnp->dn_ident->di_flags & DT_IDFLG_LOCAL)				op = DIF_OP_LDLS;			else if (dnp->dn_ident->di_flags & DT_IDFLG_TLS)				op = DIF_OP_LDTS;			else				op = DIF_OP_LDGS;			dnp->dn_ident->di_flags |= DT_IDFLG_DIFR;			instr = DIF_INSTR_LDV(op,			    dnp->dn_ident->di_id, dnp->dn_reg);			dt_irlist_append(dlp,			    dt_cg_node_alloc(DT_LBL_NONE, instr));			break;		case DT_NODE_SYM: {			dtrace_hdl_t *dtp = yypcb->pcb_hdl;			dtrace_syminfo_t *sip = dnp->dn_ident->di_data;			GElf_Sym sym;			if (dtrace_lookup_by_name(dtp,			    sip->dts_object, sip->dts_name, &sym, NULL) == -1) {				xyerror(D_UNKNOWN, "cg failed for symbol %s`%s:"				    " %s\n", sip->dts_object, sip->dts_name,				    dtrace_errmsg(dtp, dtrace_errno(dtp)));			}			if ((dnp->dn_reg = dt_regset_alloc(drp)) == -1)				longjmp(yypcb->pcb_jmpbuf, EDT_NOREG);			dt_cg_xsetx(dlp, dnp->dn_ident,			    DT_LBL_NONE, dnp->dn_reg, sym.st_value);			if (!(dnp->dn_flags & DT_NF_REF)) {				instr = DIF_INSTR_LOAD(dt_cg_load(dnp, ctfp,				    dnp->dn_type), dnp->dn_reg, dnp->dn_reg);				dt_irlist_append(dlp,				    dt_cg_node_alloc(DT_LBL_NONE, instr));			}			break;		}		default:			xyerror(D_UNKNOWN, "internal error -- node type %u is "			    "not valid for an identifier\n", dnp->dn_kind);		}		break;	case DT_TOK_INT:		if ((dnp->dn_reg = dt_regset_alloc(drp)) == -1)			longjmp(yypcb->pcb_jmpbuf, EDT_NOREG);		dt_cg_setx(dlp, dnp->dn_reg, dnp->dn_value);		break;	default:		xyerror(D_UNKNOWN, "internal error -- token type %u is not a "		    "valid D compilation token\n", dnp->dn_op);	}}voiddt_cg(dt_pcb_t *pcb, dt_node_t *dnp){	dif_instr_t instr;	if (pcb->pcb_regs == NULL && (pcb->pcb_regs =	    dt_regset_create(pcb->pcb_hdl->dt_conf.dtc_difintregs)) == NULL)		longjmp(pcb->pcb_jmpbuf, EDT_NOMEM);	dt_regset_reset(pcb->pcb_regs);	(void) dt_regset_alloc(pcb->pcb_regs); /* allocate %r0 */	if (pcb->pcb_inttab != NULL)		dt_inttab_destroy(pcb->pcb_inttab);	if ((pcb->pcb_inttab = dt_inttab_create(yypcb->pcb_hdl)) == NULL)		longjmp(pcb->pcb_jmpbuf, EDT_NOMEM);	if (pcb->pcb_strtab != NULL)		dt_strtab_destroy(pcb->pcb_strtab);	if ((pcb->pcb_strtab = dt_strtab_create(BUFSIZ)) == NULL)		longjmp(pcb->pcb_jmpbuf, EDT_NOMEM);	dt_irlist_destroy(&pcb->pcb_ir);	dt_irlist_create(&pcb->pcb_ir);	assert(pcb->pcb_dret == NULL);	pcb->pcb_dret = dnp;	if (dt_node_is_dynamic(dnp)) {		dnerror(dnp, D_CG_DYN, "expression cannot evaluate to result "		    "of dynamic type\n");	}	dt_cg_node(dnp, &pcb->pcb_ir, pcb->pcb_regs);	instr = DIF_INSTR_RET(dnp->dn_reg);	dt_regset_free(pcb->pcb_regs, dnp->dn_reg);	dt_irlist_append(&pcb->pcb_ir, dt_cg_node_alloc(DT_LBL_NONE, instr));}

⌨️ 快捷键说明

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