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

📄 outarm_a.c

📁 一款拥有一定历史的C语言编译器
💻 C
字号:
/* * C compiler * ========== * * Copyright 1989, 1990, 1991 Christoph van Wuellen. * Credits to Matthew Brandt. * All commercial rights reserved. * * This compiler may be redistributed as long there is no * commercial interest. The compiler must not be redistributed * without its full sources. This notice must stay intact. * * History: * * 1989   starting an 68000 C compiler, starting with material *        originally by M. Brandt * 1990   68000 C compiler further bug fixes *        started i386 port (December) * 1991   i386 port finished (January) *        further corrections in the front end and in the 68000 *        code generator. *        The next port will be a SPARC port *//*****************************************************************************/#include "config.h"#ifdef ARM#ifdef TARGET_ARM#define	OUT_MODULE#include "chdr.h"#include "expr.h"#include "cglbdec.h"#include "proto.h"#include "genarm.h"#include "outproto.h"#include "version.h"/********************************************************** Type Definitions */enum e_gt{    bytegen, wordgen, longgen, longlonggen, stringgen, nogen};enum e_sg{    noseg, codeseg, dataseg, bssseg};/*********************************************** Static Function Definitions */static void putop P_ ((OPCODE, CONDITION));static void putconst P_ ((const EXPR *));static void putamode P_ ((const ADDRESS *));static void put_header P_ ((enum e_gt, SIZE));static void put_align P_ ((SIZE));static void nl P_ ((void));static void seg P_ ((enum e_sg, const char *, SIZE));static void put_bseg P_ ((SIZE));/*********************************************** Global Function Definitions */PRIVATE void put_name P_ ((SYM *));PRIVATE void put_dword P_ ((UVAL));PRIVATE void put_cseg P_ ((SIZE));PRIVATE void put_dseg P_ ((SIZE));PRIVATE void put_kseg P_ ((SIZE));PRIVATE void put_rseg P_ ((SIZE));PRIVATE void put_label P_ ((LABEL));PRIVATE void put_reference P_ ((SYM *));PRIVATE void put_byte P_ ((UVAL));/********************************************************** Static Variables *//* variable initialization */static enum e_gt gentype = nogen;static enum e_sg curseg = noseg;static int outcol = 0;static SIZE align_type = 0L;static const char *prefix = "I_";static const char *comment = ";";static const char *regname[] = {    "r0",			/* 0 */    "r1",			/* 1 */    "r2",			/* 2 */    "r3",			/* 3 */    "r4",			/* 4 */    "r5",			/* 5 */    "r6",			/* 6 */    "r7",			/* 7 */    "r8",			/* 8 */    "r9",			/* 9 */    "r10",			/* 10 */    "r11",			/* 11 */    "r12",			/* 12 */    "sp",			/* 13 */    "lr",			/* 14 */    "pc"			/* 15 */};/*****************************************************************************/static void putop P2 (OPCODE, op, CONDITION, cc){    static const char *opl[] = {	"adc%s",		/* op_adc  */	"add%s",		/* op_add  */	"adc%ss",		/* op_adcs */	"add%ss",		/* op_adds */	"sbc%s",		/* op_sbc  */	"sub%s",		/* op_sub  */	"sbc%ss",		/* op_sbcs */	"sub%ss",		/* op_subs */	"rsb%s",		/* op_rsb  */	"rsb%ss",		/* op_rsbs */	"and%s",		/* op_and  */	"and%ss",		/* op_ands */	"bic%s",		/* op_bic  */	"bic%ss",		/* op_bics */	"orr%s",		/* op_orr  */	"orr%ss",		/* op_orrs */	"eor%s",		/* op_eor  */	"eor%ss",		/* op_eors */	"mov%s",		/* op_mov  */	"mov%ss",		/* op_movs */	"mvn%s",		/* op_mvn  */	"mvn%ss",		/* op_mvns */	"cmn%ss",		/* op_cmns */	"cmp%ss",		/* op_cmps */	"teq%ss",		/* op_teqs */	"tst%ss",		/* op_tsts */	"mul%s",		/* op_mul  */	"mla%s",		/* op_mla  */	"b%s",			/* op_b    */	"bl%s",			/* op_bl   */	"ldr%s",		/* op_ldr  */	"str%s",		/* op_str  */	"ldm%sea",		/* op_ldmea */	"stm%sfd",		/* op_stmfd */	"swi%s",		/* op_swi  */	(char *) NULL,		/* op_label */#ifdef ASM	"",			/* op_asm */#endif				/* ASM */	(char *) NULL,    };    static const char *ccodes[] = {	"",			/* cc_al */	"cc",			/* cc_cc */	"cs",			/* cc_cs */	"eq",			/* cc_eq */	"ge",			/* cc_ge */	"gt",			/* cc_gt */	"hi",			/* cc_hi */	"le",			/* cc_le */	"ls",			/* cc_ls */	"lt",			/* cc_lt */	"mi",			/* cc_mi */	"ne",			/* cc_ne */	"nv",			/* cc_nv */	"pl",			/* cc_pl */	"vc",			/* cc_vc */	"vs"			/* cc_vs */    };    if (op >= OP_MIN && op <= OP_MAX && opl[op] != (char *) 0) {	oprintf ("\t");	oprintf (opl[op], ccodes[cc]);    } else {	FATAL ((__FILE__, "putop", "illegal opcode %d", op));    }}/* * put a constant to the output file. */static void putconst P1 (const EXPR *, ep){    switch (ep->nodetype) {    case en_autocon:    case en_icon:	oprintf ("%ld", ep->v.i);	break;#ifdef FLOAT_MFFP    case en_fcon:	oprintf ("0x%lx", genffp (ep->v.f));	break;#endif /* FLOAT_MFFP */    case en_labcon:	oprintf ("%s%u", prefix, (unsigned) ep->v.l);	break;    case en_nacon:	oprintf ("%s", outlate (ep->v.str));	break;    case en_sym:	oprintf ("%s", outlate (nameof (ep->v.sp)));	break;    case en_add:	putconst (ep->v.p[0]);	oprintf ("+");	putconst (ep->v.p[1]);	break;    case en_sub:	putconst (ep->v.p[0]);	oprintf ("-");	putconst (ep->v.p[1]);	break;    case en_uminus:	oprintf ("-");	/*lint -fallthrough */    case en_cast:	putconst (ep->v.p[0]);	break;    case en_str:	oprintf ("%s", ep->v.str);	break;    default:	FATAL (	       (__FILE__, "putconst", "illegal constant node %d",		ep->nodetype));	break;    }}static void putreg P1 (REG, reg){    oprintf ("%s", regname[reg]);}static void put_mask P1 (REGMASK, mask){    REG     reg;    BOOL    pending = FALSE;    oprintf ("{");    if (mask & (REGMASK) 1) {	putreg (R0);	pending = TRUE;    }    for (reg = R1; reg <= R15; reg++) {	if ((mask = mask >> 1) & (REGMASK) 1) {	    if (pending) {		oprintf (",");	    }	    putreg (reg);	    pending = TRUE;	}    }    oprintf ("}");}/* * output a general addressing mode. */static void putamode P1 (const ADDRESS *, ap){    IVAL    i_val;    switch (ap->mode) {    case am_immed:	oprintf ("#");	/*	 * Suppress overflow in immediate arguments -	 * which may occur due to optimization of constants	 */	if (is_icon (ap->offset)) {	    i_val = ap->offset->v.i;	    oprintf ("%ld", i_val);	    break;	}	putconst (ap->offset);	break;    case am_direct:	putconst (ap->offset);	break;    case am_reg:	oprintf ("%s", regname[ap->preg]);	break;    case am_lsl:	oprintf ("%s, LSL #", regname[ap->preg]);	putconst (ap->offset);	break;    case am_lsr:	oprintf ("%s, LSR #", regname[ap->preg]);	putconst (ap->offset);	break;    case am_asr:	oprintf ("%s, ASR #", regname[ap->preg]);	putconst (ap->offset);	break;    case am_ror:	oprintf ("%s, ROR #", regname[ap->preg]);	putconst (ap->offset);	break;    case am_lslr:	oprintf ("%s, LSL %s", regname[ap->preg], regname[ap->sreg]);	break;    case am_lsrr:	oprintf ("%s, LSR %s", regname[ap->preg], regname[ap->sreg]);	break;    case am_asrr:	oprintf ("%s, ASR %s", regname[ap->preg], regname[ap->sreg]);	break;    case am_rorr:	oprintf ("%s, ROR %s", regname[ap->preg], regname[ap->sreg]);	break;    case am_pre:	oprintf ("[%s,#", regname[ap->preg]);	putconst (ap->offset);	oprintf ("]");	break;    case am_prelsl:	oprintf ("[%s, %s, LSL #", regname[ap->preg], regname[ap->sreg]);	putconst (ap->offset);	oprintf ("]");	break;    case am_prelsr:	oprintf ("[%s, %s, LSR #", regname[ap->preg], regname[ap->sreg]);	putconst (ap->offset);	oprintf ("]");	break;    case am_preasr:	oprintf ("[%s, %s, ASR #", regname[ap->preg], regname[ap->sreg]);	putconst (ap->offset);	oprintf ("]");	break;    case am_preror:	oprintf ("[%s, %s, ROR #", regname[ap->preg], regname[ap->sreg]);	putconst (ap->offset);	oprintf ("]");	break;    case am_post:	oprintf ("[%s], #", regname[ap->preg]);	putconst (ap->offset);	break;    case am_postlsl:	oprintf ("[%s], %s, LSL #", regname[ap->preg], regname[ap->sreg]);	putconst (ap->offset);	break;    case am_postlsr:	oprintf ("[%s], %s, LSR #", regname[ap->preg], regname[ap->sreg]);	putconst (ap->offset);	break;    case am_postasr:	oprintf ("[%s], %s, ASR #", regname[ap->preg], regname[ap->sreg]);	putconst (ap->offset);	break;    case am_postror:	oprintf ("[%s], %s, ROR #", regname[ap->preg], regname[ap->sreg]);	putconst (ap->offset);	break;    case am_mask:	put_mask ((REGMASK) ap->offset->v.i);	break;    case am_line:    case am_str:	putconst (ap->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){    putop (ip->opcode, ip->cc);    if (ip->oper1 != NIL_ADDRESS) {	oprintf ("\t");	putamode (ip->oper1);	if (ip->oper2 != NIL_ADDRESS) {	    oprintf (", ");	    putamode (ip->oper2);	    if (ip->oper3 != NIL_ADDRESS) {		oprintf (", ");		putamode (ip->oper3);	    }	}    }    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[] = {	"DCB\t",		/* bytegen */	"DCW\t",		/* wordgen */	"DCD\t",		/* longgen */	"DCD\t",		/* longlonggen */	"DCB\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){    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;}#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, TRUE);    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, TRUE);    put_dword ((UVAL) ul[0]);    put_dword ((UVAL) ul[1]);    put_dword ((UVAL) ul[2]);}#endif /* FLOAT_IEEE */PRIVATE 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;}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 (longgen, alignment_of_type (tp_pointer));    putconst (ep);    outcol += 10;}PRIVATE void put_storage P1 (SYM *, sp){    put_bseg (alignment_of_type (typeof (sp)));    if (is_static (sp)) {	put_label (sp->value.l);    } else {	put_name (sp);    }    oprintf ("\t%%\t%ld%s", typeof (sp)->size, newline);}/* * dump the string literal pool. * if we are producing single copies of strings (which should therefore * be read only we put them in the text segment - else in the data segment. */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) 0);    }    nl ();}PRIVATE void put_reference P1 (SYM *, sp){    if (!is_symbol_output (sp)) {	switch (storageof (sp)) {	case sc_global:	    oprintf ("\tEXPORT\t|%s|%s", nameof (sp), newline);	    break;	case sc_external:	    oprintf ("\tIMPORT\t|%s|%s", 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 1:	    break;	case 2:	    oprintf ("\tALIGN\t1%s", newline);	    break;	case 4:	    oprintf ("\tALIGN\t2%s", 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 */}static void nl P0 (void){    if (outcol > 0) {	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 ("%s, %ld%s", segname, al, newline);	curseg = segtype;	align_type = al;    } else {	put_align (al);    }}PRIVATE void put_cseg P1 (SIZE, al){    seg (codeseg, "\tAREA |C$$code|, CODE, READONLY", al);}PRIVATE void put_dseg P1 (SIZE, al){    seg (dataseg, "\tAREA |C$$data|, DATA, NOINIT", al);}static void put_bseg P1 (SIZE, al){    seg (bssseg, "\tAREA |C$$bss|, DATA", 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){    nl ();    oprintf ("\tEND%s", newline);}PRIVATE void put_start P0 (void){    oprintf ("%s Generated by %s %s %s (%s) from \"%s\"%s",	     comment, PROGNAME, VERSION, LAST_CHANGE_DATE, __DATE__, 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 */}#ifdef MULTIPLE_ASSEMBLERSstruct funcs armarm_funcs = {    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_ARM */#endif /* ARM */

⌨️ 快捷键说明

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