outx86_b.c

来自「一款拥有一定历史的C语言编译器」· C语言 代码 · 共 1,018 行 · 第 1/2 页

C
1,018
字号
	}    }#ifdef FLOAT_IEEE    if (sa & FP) {	/* assume that st(n) never appears explicitly as an operand here */	switch (len) {	case IL2 + 1:	    /*lint !e408*/  /* type mismatch with switch expression */	    oprintf (" word ptr ");	    break;	case IL4 + 1:	    /*lint !e408*/  /* type mismatch with switch expression */	    oprintf (" dword ptr ");	    break;	case IL8 + 1:	    /*lint !e408*/  /* type mismatch with switch expression */	    oprintf (" qword ptr ");	    break;	default:	    /* else fnstsw should not need a length? */	    len = IL2;	    break;	}    }#endif /* FLOAT_IEEE */    switch (ap->mode) {    case am_immed:	oprintf ("#");	if (is_icon (ap->u.offset)) {	    IVAL    i_val = ap->u.offset->v.i;	    switch (len) {	    case IL1:		i_val &= (IVAL) 0x000000ffL;		break;	    case IL2:		i_val &= (IVAL) 0x0000ffffL;		break;	    default:		break;	    }	    oprintf ("%ld", i_val);	} else {	    putconst (ap->u.offset);	}	break;    case am_direct:	if (sa & BI) {	    oprintf ("[");	    putconst (ap->u.offset);	    oprintf ("]");	} else {	    putconst (ap->u.offset);	}	break;    case am_dreg:    case am_areg:	reg = ap->preg;	switch (len) {	case IL1:	    reg = REG8 (reg);	    break;	case IL0:	case IL2:	    reg = REG16 (reg);	    break;	default:	    break;	}	oprintf ("%s", regname[reg]);	break;    case am_indx:	if (ap->u.offset != NIL_EXPR) {	    putconst (ap->u.offset);	}	/*lint -fallthrough */    case am_ind:	oprintf ("[%s]", regname[small_option ? REG16 (ap->preg) : ap->preg]);	break;    case am_indx2:	if (ap->u.offset != NIL_EXPR) {	    putconst (ap->u.offset);	}	oprintf ("[%s+%s]",		 regname[small_option ? REG16 (ap->preg) : ap->preg],		 regname[small_option ? REG16 (ap->sreg) : ap->sreg]);	break;    case am_freg:	oprintf ("%s", regname[ap->preg]);	break;    case am_line:    case am_str:	putconst (ap->u.offset);	break;    default:	FATAL ((__FILE__, "putamode", "illegal address mode %d", ap->mode));	break;    }}/* * output a generic instruction. */PRIVATE void put_code P1 (const CODE *, ip){    ILEN    len1 = ip->length, len2 = ip->length;    unsigned int sa = putop (ip->opcode);    /*     * this is expensive, but some assemblers require it     * this is to be moved to the peephole optimizer     */    switch (ip->opcode) {    case op_shl:    case op_shr:    case op_asl:    case op_asr:	len1 = IL1;	break;    case op_movsbw:    case op_movzbw:	len2 = IL2;	/*lint -fallthrough */    case op_movsbl:    case op_movzbl:	len1 = IL1;	break;    case op_movswl:    case op_movzwl:	len1 = IL2;	break;    case op_smov:	switch (ip->length) {	case IL1:	    oprintf ("b");	    break;	case IL2:	    oprintf ("w");	    break;	case IL4:	    oprintf ("d");	    break;	default:	    FATAL (		   (__FILE__, "putcode", "illegal length field %d",		    (int) ip->length));	    break;	}	break;    default:	break;    }    /*     * Bas uses the INTEL syntax:     * The destination comes first     * The source comes second     */    if (ip->oper1 != NIL_ADDRESS) {	oprintf ("\t");	if (ip->oper2 != NIL_ADDRESS && ip->opcode != op_line) {	    putamode (ip->oper2, len2, sa);	    oprintf (", ");	}	putamode (ip->oper1, len1, sa);	if (ip->oper2 != NIL_ADDRESS && ip->opcode == op_line) {	    oprintf (", ");	    putamode (ip->oper2, len2, sa);	}    }    oprintf ("%s", newline);}/* * generate a named label. */PRIVATE void put_name P1 (SYM *, sp){    put_reference (sp);    oprintf ("%s:%s", outlate (nameof (sp)), newline);}/* * output a compiler generated label. */PRIVATE void put_label P1 (LABEL, lab){    oprintf ("%s%u:%s", prefix, (unsigned int) lab, newline);}static void put_header P2 (enum e_gt, gtype, SIZE, al){    static const char *directive[] = {	".byte\t",		/* bytegen */	".word\t",		/* wordgen */	".long\t",		/* longgen */	".long\t",		/* longlonggen */	".ascii\t\"",		/* stringgen */    };    if (gentype != gtype || outcol >= MAX_WIDTH) {	put_align (al);	gentype = gtype;	outcol = 15;	oprintf ("\t%s", directive[gtype]);    } else if (gentype != stringgen) {	oprintf (",");    }}PRIVATE void put_byte P1 (UVAL, val){    if (val >= (UVAL) 32 && val <= (UVAL) 126 && val != (UVAL) '\\'	&& val != (UVAL) '"') {	put_header (stringgen, alignment_of_type (tp_char));	oprintf ("%c", (int) val);	outcol++;    } else {	put_header (bytegen, alignment_of_type (tp_char));	oprintf ("0x%lx", val & OxffUL);	outcol += 4;    }}PRIVATE void put_word P1 (UVAL, val){    put_header (wordgen, alignment_of_type (tp_short));    oprintf ("0x%lx", val & OxffffUL);    outcol += 6;}PRIVATE void put_dword P1 (UVAL, val){    put_header (longgen, alignment_of_type (tp_long));    oprintf ("0x%lx", val);    outcol += 10;}#ifndef FLOAT_BOOTSTRAP#ifdef FLOAT_IEEE/* * Generate IEEE single and double numbers */PRIVATE void put_float P1 (const RVAL *, vp){    unsigned long ul;    ieee_single (vp, &ul);    put_dword ((UVAL) ul);}PRIVATE void put_double P1 (const RVAL *, vp){    unsigned long ul[2];    ieee_double (vp, ul, FALSE);    put_dword ((UVAL) ul[0]);    put_dword ((UVAL) ul[1]);}PRIVATE void put_longdouble P1 (const RVAL *, vp){    unsigned long ul[3];    ieee_longdouble (vp, ul, FALSE);    put_dword ((UVAL) ul[0]);    put_dword ((UVAL) ul[1]);    put_dword ((UVAL) ul[2]);}#endif /* FLOAT_IEEE */#endif /* FLOAT_BOOTSTRAP */#ifndef RELOC_BUGPRIVATE void put_char P1 (const EXPR *, ep){    put_header (bytegen, alignment_of_type (tp_char));    putconst (ep);    outcol += 10;}PRIVATE void put_short P1 (const EXPR *, ep){    put_header (wordgen, alignment_of_type (tp_short));    putconst (ep);    outcol += 10;}#endif /* RELOC_BUG */PRIVATE void put_long P1 (const EXPR *, ep){    put_header (longgen, alignment_of_type (tp_long));    putconst (ep);    outcol += 10;}PRIVATE void put_longlong P1 (const EXPR *, ep){    put_header (longlonggen, alignment_of_type (tp_longlong));    putconst (ep);    outcol += 10;}PRIVATE void put_pointer P1 (const EXPR *, ep){    put_header ((tp_pointer->size == 2L ? wordgen : longgen),		alignment_of_type (tp_pointer));    putconst (ep);    outcol += 10;}/*ARGSUSED */PRIVATE void put_storage P1 (const SYM *, sp){    SIZE    size = typeof (sp)->size;    put_bseg (alignment_of_type (typeof (sp)));    if (is_static (sp)) {	oprintf ("\t.lcomm\t%s%u,%ld%s", prefix, (unsigned) sp->value.l, size,		 newline);    } else {	oprintf ("\t.comm\t%s,%ld%s", outlate (nameof (sp)), size, newline);	symbol_output ((SYM *) sp);    }}/* * dump the string literal pool. */PRIVATE void put_literals P0 (void){    const CHAR *cp;    size_t  len;    if (lang_option == LANG_KANDR) {	put_dseg (alignment_of_type (tp_char));    } else {	put_kseg (alignment_of_type (tp_char));    }    for (; strtab != NIL_STRING; strtab = strtab->next) {	nl ();	put_label (strtab->label);	cp = strtab->str;	for (len = strtab->len; len--;)	    put_byte ((UVAL) *cp++);	put_byte ((UVAL) Ox0UL);    }    nl ();}PRIVATE void put_reference P1 (SYM *, sp){    if (!is_symbol_output (sp)) {	switch (storageof (sp)) {	case sc_global:	    nl ();	    oprintf ("\t.globl\t%s%s", outlate (nameof (sp)), newline);	    break;	case sc_external:	    nl ();	    oprintf ("\t.globl\t%s%s", outlate (nameof (sp)), newline);	    break;	default:	    break;	}	symbol_output (sp);    }}/* align the following data */static void put_align P1 (SIZE, al){    nl ();    if (al > align_type) {	switch (al) {	case 1L:	case 0L:	    break;	case 2L:	case 4L:	    oprintf ("\t.align\t%d%s", (int) al, newline);	    break;	default:	    FATAL ((__FILE__, "put_align", "align == %ld", al));	}    }    align_type = al;}/* * output any function epilogue code */PRIVATE void put_epilogue P2 (SYM *, sp, LABEL, label){    sp = sp;			/* keep the compiler quiet */    label = label;		/* keep the compiler quiet */}PRIVATE void nl P0 (void){    if (outcol > 0) {	if (gentype == stringgen) {	    oprintf ("\"");	}	oprintf ("%s", newline);	gentype = nogen;	outcol = 0;    }}static void seg P3 (enum e_sg, segtype, const char *, segname, SIZE, al){    nl ();    if (curseg != segtype) {	oprintf ("\t%s%s", segname, newline);	curseg = segtype;	align_type = 0L;    }    put_align (al);}PRIVATE void put_cseg P1 (SIZE, al){    seg (codeseg, ".text", al);}PRIVATE void put_dseg P1 (SIZE, al){    seg (dataseg, ".data", al);}static void put_bseg P1 (SIZE, al){    put_dseg (al);}PRIVATE void put_kseg P1 (SIZE, al){    if (IandD_option) {	put_dseg (al);    } else {	put_cseg (al);    }}PRIVATE void put_rseg P1 (SIZE, al){    put_cseg (al);}PRIVATE void put_finish P0 (void){}PRIVATE void put_start P0 (void){    oprintf ("%s Generated by %s (bas) %s from %s%s",	     comment, PROGNAME, VERSION, in_file, newline);#ifdef VERBOSE    {	time_t  time_of_day;	VOIDCAST time (&time_of_day);	oprintf ("%s Compilation date/time: %s%s",		 comment, ctime (&time_of_day), newline);    }#endif /* VERBOSE */    oprintf ("c386_compiled.:%s", newline);}#ifdef MULTIPLE_ASSEMBLERSstruct funcs basx86_func = {    put_code,    put_name,    put_label,    put_byte,    put_word,    put_dword,#ifndef RELOC_BUG    put_char,    put_short,#endif				/* RELOC_BUG */    put_long,    put_longlong,    put_pointer,    put_storage,    put_literals,    put_finish,    put_start,    put_reference,    put_epilogue,    put_cseg,    put_dseg,    put_kseg,    put_rseg, #ifndef FLOAT_BOOTSTRAP#ifdef FLOAT_SUPPORT	put_float,    put_double,    put_longdouble,#endif	/* FLOAT_SUPPORT */#endif	/* FLOAT_BOOTSTRAP */    NULL};#endif /* MULTIPLE_ASSEMBLERS */#endif /* TARGET_BAS */#endif /* INTEL */

⌨️ 快捷键说明

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