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

📄 i860.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 2 页
字号:
	    case 'c': /* next operand must be a control register */		if (strncmp(s, "fir", 3) == 0) {		    opcode |= 0x0 << 21;		    s += 3;		    continue;		}		if (strncmp(s, "psr", 3) == 0) {		    opcode |= 0x1 << 21;		    s += 3;		    continue;		}		if (strncmp(s, "dirbase", 7) == 0) {		    opcode |= 0x2 << 21;		    s += 7;		    continue;		}		if (strncmp(s, "db", 2) == 0) {		    opcode |= 0x3 << 21;		    s += 2;		    continue;		}		if (strncmp(s, "fsr", 3) == 0) {		    opcode |= 0x4 << 21;		    s += 3;		    continue;		}		if (strncmp(s, "epsr", 4) == 0) {		    opcode |= 0x5 << 21;		    s += 4;		    continue;		}		break;	    case '5':   /* 5 bit immediate in src1 */		bzero(&the_insn, sizeof(the_insn));		if ( !getExpression(s)) {		    s = expr_end;	    	    if (the_insn.exp.X_add_number & ~0x1f)		        as_warn("5-bit immediate too large");	    	    opcode |= (the_insn.exp.X_add_number & 0x1f) << 11;		    bzero(&the_insn, sizeof(the_insn));		    the_insn.reloc = NO_RELOC;		    continue;		}		break;	    case 'l':   /* 26 bit immediate, relative branch */		the_insn.reloc = BRADDR;		the_insn.pcrel = TRUE;		goto immediate;	    case 's':   /* 16 bit immediate, split relative branch */			/* upper 5 bits of offset in dest field */		the_insn.pcrel = TRUE;		the_insn.reloc = SPLIT0;		goto immediate;	    case 'S':   /* 16 bit immediate, split (st), aligned */		if (opcode & (1 << 28))		    if (opcode & 0x1)			the_insn.reloc = SPLIT2;		    else			the_insn.reloc = SPLIT1;		else		    the_insn.reloc = SPLIT0;		goto immediate;	    case 'I':   /* 16 bit immediate, aligned */		if (opcode & (1 << 28))		    if (opcode & 0x1)			the_insn.reloc = LOW2;		    else			the_insn.reloc = LOW1;		else		    the_insn.reloc = LOW0;		goto immediate;	    case 'i':   /* 16 bit immediate */		the_insn.reloc = LOW0;		/*FALLTHROUGH*/	    immediate:		if(*s==' ')		  s++;		if (strncmp(s, "ha%", 3) == 0) {		    the_insn.highlow = HIGHADJ;		    s += 3;		} else if (strncmp(s, "h%", 2) == 0) {		    the_insn.highlow = HIGH;		    s += 2;		} else if (strncmp(s, "l%", 2) == 0) {		    the_insn.highlow = PAIR;		    s += 2;		}		the_insn.expand = insn->expand; 		/* Note that if the getExpression() fails, we will still have		   created U entries in the symbol table for the 'symbols'		   in the input string.  Try not to create U symbols for		   registers, etc. */		if ( !getExpression(s)) {		    s = expr_end;		    continue;		}		break;	    default:		abort();	    }	    break;	}	error:	if (match == FALSE)	  {	    /* Args don't match.  */	    if (&insn[1] - i860_opcodes < NUMOPCODES		&& !strcmp(insn->name, insn[1].name))	      {		++insn;		s = argsStart;		continue;	      }	    else	      {		as_warn("Illegal operands");		return;	      }	  }	break;    }    the_insn.opcode = opcode;    return;}static intgetExpression(str)    char *str;{    char *save_in;    segT seg;    save_in = input_line_pointer;    input_line_pointer = str;    switch (seg = expression(&the_insn.exp)) {    case SEG_ABSOLUTE:    case SEG_TEXT:    case SEG_DATA:    case SEG_BSS:    case SEG_UNKNOWN:    case SEG_DIFFERENCE:    case SEG_BIG:    case SEG_NONE:	break;    default:	the_insn.error = "bad segment";	expr_end = input_line_pointer;	input_line_pointer=save_in;	return 1;    }    expr_end = input_line_pointer;    input_line_pointer = save_in;    return 0;}/*    This is identical to the md_atof in m68k.c.  I think this is right,    but I'm not sure.   Turn a string in input_line_pointer into a floating point constant of type   type, and store the appropriate bytes in *litP.  The number of LITTLENUMS   emitted is stored in *sizeP .  An error message is returned, or NULL on OK. *//* Equal to MAX_PRECISION in atof-ieee.c */#define MAX_LITTLENUMS 6char *md_atof(type,litP,sizeP)    char type;    char *litP;    int *sizeP;{    int	prec;    LITTLENUM_TYPE words[MAX_LITTLENUMS];    LITTLENUM_TYPE *wordP;    char	*t;    char	*atof_ieee();    switch(type) {    case 'f':    case 'F':    case 's':    case 'S':	prec = 2;	break;    case 'd':    case 'D':    case 'r':    case 'R':	prec = 4;	break;    case 'x':    case 'X':	prec = 6;	break;    case 'p':    case 'P':	prec = 6;	break;    default:	*sizeP=0;	return "Bad call to MD_ATOF()";    }    t=atof_ieee(input_line_pointer,type,words);    if(t)	input_line_pointer=t;    *sizeP=prec * sizeof(LITTLENUM_TYPE);    for(wordP=words;prec--;) {	md_number_to_chars(litP,(long)(*wordP++),sizeof(LITTLENUM_TYPE));	litP+=sizeof(LITTLENUM_TYPE);    }    return "";	/* Someone should teach Dean about null pointers */}/* * Write out big-endian. */voidmd_number_to_chars(buf,val,n)    char *buf;    long val;    int n;{    switch(n) {    case 4:	*buf++ = val >> 24;	*buf++ = val >> 16;    case 2:	*buf++ = val >> 8;    case 1:	*buf = val;	break;    default:	abort();    }    return;}voidmd_number_to_imm(buf,val,n, fixP, seg_type)    char *buf;    long val;    int n;    fixS *fixP;    int seg_type;{    enum reloc_type reloc = fixP->fx_r_type & 0xf;    enum highlow_type highlow = (fixP->fx_r_type >> 4) & 0x3;    assert(buf);    assert(n == 4);	/* always on i860 */    switch(highlow)    {    case HIGHADJ:	/* adjusts the high-order 16-bits */	if (val & (1 << 15))	    val += (1 << 16);	    /*FALLTHROUGH*/    case HIGH:	/* selects the high-order 16-bits */	val >>= 16;	break;    case PAIR:	/* selects the low-order 16-bits */	val = val & 0xffff;	break;    default:	break;    }    switch(reloc)    {    case BRADDR:	/* br,call,bc,bc.t,bnc,bnc.t w/26-bit immediate */	if (fixP->fx_pcrel != TRUE)	    as_warn("26-bit branch w/o pc relative set: 0x%08x", val);	val >>= 2;	/* align pcrel offset, see manual */	if (val >= (1 << 25) || val < -(1 << 25))	/* check for overflow */	    as_warn("26-bit branch offset overflow: 0x%08x", val);	buf[0] = (buf[0] & 0xfc) | ((val >> 24) & 0x3);	buf[1] = val >> 16;	buf[2] = val >> 8;	buf[3] = val;	break;    case SPLIT2:	/* 16 bit immediate, 4-byte aligned */	if (val & 0x3)	    as_warn("16-bit immediate 4-byte alignment error: 0x%08x", val);	val &= ~0x3;	/* 4-byte align value */	/*FALLTHROUGH*/    case SPLIT1:	/* 16 bit immediate, 2-byte aligned */	if (val & 0x1)	    as_warn("16-bit immediate 2-byte alignment error: 0x%08x", val);	val &= ~0x1;	/* 2-byte align value */	/*FALLTHROUGH*/    case SPLIT0:	/* st,bla,bte,btne w/16-bit immediate */	if (fixP->fx_pcrel == TRUE)	    val >>= 2;	/* align pcrel offset, see manual */	/* check for bounds */	if (highlow != PAIR && (val >= (1 << 16) || val < -(1 << 15)))	    as_warn("16-bit branch offset overflow: 0x%08x", val);	buf[1] = (buf[1] & ~0x1f) | ((val >> 11) & 0x1f);	buf[2] = (buf[2] & ~0x7) | ((val >> 8) & 0x7);	buf[3] |= val;	/* perserve bottom opcode bits */		break;    case LOW4:	/* fld,pfld,pst,flush 16-byte aligned */	if (val & 0xf)	    as_warn("16-bit immediate 16-byte alignment error: 0x%08x", val);	val &= ~0xf;	/* 16-byte align value */	/*FALLTHROUGH*/    case LOW3:	/* fld,pfld,pst,flush 8-byte aligned */	if (val & 0x7)	    as_warn("16-bit immediate 8-byte alignment error: 0x%08x", val);	val &= ~0x7;	/* 8-byte align value */	/*FALLTHROUGH*/    case LOW2:	/* 16 bit immediate, 4-byte aligned */	if (val & 0x3)	    as_warn("16-bit immediate 4-byte alignment error: 0x%08x", val);	val &= ~0x3;	/* 4-byte align value */	/*FALLTHROUGH*/    case LOW1:	/* 16 bit immediate, 2-byte aligned */	if (val & 0x1)	    as_warn("16-bit immediate 2-byte alignment error: 0x%08x", val);	val &= ~0x1;	/* 2-byte align value */	/*FALLTHROUGH*/    case LOW0:	/* 16 bit immediate, byte aligned */	/* check for bounds */	if (highlow != PAIR && (val >= (1 << 16) || val < -(1 << 15)))	    as_warn("16-bit immediate overflow: 0x%08x", val);	buf[2] = val >> 8;	buf[3] |= val;	/* perserve bottom opcode bits */		break;    case NO_RELOC:    default:	as_warn("bad relocation type: 0x%02x", reloc);	break;    }    return;}/* should never be called for i860 */voidmd_create_short_jump(ptr, from_addr, to_addr, frag, to_symbol)    char *ptr;    long from_addr, to_addr;{    fprintf(stderr, "i860_create_short_jmp\n");    abort();}/* should never be called for i860 */voidmd_number_to_disp(buf,val,n)    char	*buf;    long	val;{    fprintf(stderr, "md_number_to_disp\n");    abort();}/* should never be called for i860 */voidmd_number_to_field(buf,val,fix)    char *buf;    long val;    void *fix;{    fprintf(stderr, "i860_number_to_field\n");    abort();}/* the bit-field entries in the relocation_info struct plays hell    with the byte-order problems of cross-assembly.  So as a hack,   I added this mach. dependent ri twiddler.  Ugly, but it gets   you there. -KWK *//* on i860: first 4 bytes are normal unsigned long address, next three   bytes are index, most sig. byte first.  Byte 7 is broken up with   bit 7 as pcrel, bit 6 as extern, and the lower six bits as   relocation type (highlow 5-4).  Next 4 bytes are long int addend. *//* Thanx and a tip of the hat to Michael Bloom, mb@ttidca.tti.com */voidmd_ri_to_chars(ri_p, ri)     struct relocation_info *ri_p, ri;{#if 0  unsigned char the_bytes[sizeof(*ri_p)];    /* this is easy */  md_number_to_chars(the_bytes, ri.r_address, sizeof(ri.r_address));  /* now the fun stuff */  the_bytes[4] = (ri.r_index >> 16) & 0x0ff;  the_bytes[5] = (ri.r_index >> 8) & 0x0ff;  the_bytes[6] = ri.r_index & 0x0ff;  the_bytes[7] = ((ri.r_extern << 7)  & 0x80) | (0 & 0x60) | (ri.r_type & 0x1F);  /* Also easy */  md_number_to_chars(&the_bytes[8], ri.r_addend, sizeof(ri.r_addend));  /* now put it back where you found it, Junior... */  bcopy (the_bytes, (char *)ri_p, sizeof(*ri_p));#endif}/* should never be called for i860 */voidmd_convert_frag(fragP)    register fragS *fragP;{    fprintf(stderr, "i860_convert_frag\n");    abort();}/* should never be called for i860 */voidmd_create_long_jump(ptr, from_addr, to_addr, frag, to_symbol)    char	*ptr;    long	from_addr,	        to_addr;    fragS	*frag;    symbolS	*to_symbol;{    fprintf(stderr, "i860_create_long_jump\n");    abort();}/* should never be called for i860 */intmd_estimate_size_before_relax(fragP, segtype)    register fragS *fragP;{    fprintf(stderr, "i860_estimate_size_before_relax\n");    abort();    return 0;}/* for debugging only, must match enum reloc_type */static char *Reloc[] = {    "NO_RELOC",    "BRADDR",     "LOW0",     "LOW1",     "LOW2",     "LOW3",     "LOW4",     "SPLIT0",     "SPLIT1",     "SPLIT2",     "RELOC_32", };static char *Highlow[] = {    "NO_SPEC",    "PAIR",     "HIGH",     "HIGHADJ", };static voidprint_insn(insn)    struct i860_it *insn;{    if (insn->error) {	fprintf(stderr, "ERROR: %s\n");    }    fprintf(stderr, "opcode=0x%08x\t", insn->opcode);    fprintf(stderr, "expand=0x%08x\t", insn->expand);    fprintf(stderr, "reloc = %s\t", Reloc[insn->reloc]);    fprintf(stderr, "highlow = %s\n", Highlow[insn->highlow]);    fprintf(stderr, "exp =  {\n");    fprintf(stderr, "\t\tX_add_symbol = %s\n",	insn->exp.X_add_symbol ?	(insn->exp.X_add_symbol->sy_name ? 	insn->exp.X_add_symbol->sy_name : "???") : "0");    fprintf(stderr, "\t\tX_sub_symbol = %s\n",	insn->exp.X_subtract_symbol ?	    (insn->exp.X_subtract_symbol->sy_name ? 	        insn->exp.X_subtract_symbol->sy_name : "???") : "0");    fprintf(stderr, "\t\tX_add_number = %d\n",	insn->exp.X_add_number);    fprintf(stderr, "}\n");    return;}intmd_parse_option(argP,cntP,vecP)    char **argP;    int *cntP;    char ***vecP;{    return 1;}/* * I860 relocations are completely different, so it needs * this machine dependent routine to emit them. */voidemit_relocations(fixP, segment_address_in_file)    register fixS *fixP;    relax_addressT segment_address_in_file;{    struct reloc_info_i860 ri;    register symbolS *symbolP;    extern char *next_object_file_charP;    long add_number;    bzero((char *) &ri, sizeof(ri));    for (; fixP; fixP = fixP->fx_next) {	if (fixP->fx_r_type & ~0x3f) {	    fprintf(stderr, "fixP->fx_r_type = %d\n", fixP->fx_r_type);	    abort();	}	ri.r_pcrel = fixP->fx_pcrel;	ri.r_type = fixP->fx_r_type;	if ((symbolP = fixP->fx_addsy) != NULL) {	    ri.r_address = fixP->fx_frag->fr_address +	        fixP->fx_where - segment_address_in_file;	    if ((symbolP->sy_type & N_TYPE) == N_UNDF) {		ri.r_extern = 1;		ri.r_symbolnum = symbolP->sy_number;	    } else {		ri.r_extern = 0;		ri.r_symbolnum = symbolP->sy_type & N_TYPE;	    }	    if (symbolP && symbolP->sy_frag) {		ri.r_addend = symbolP->sy_frag->fr_address;	    }	    ri.r_type = fixP->fx_r_type;	    if (fixP->fx_pcrel) {		/* preserve actual offset vs. pc + 4 */		ri.r_addend -= (ri.r_address + 4);	    } else {		ri.r_addend = fixP->fx_addnumber;	    }	    md_ri_to_chars((char *) &ri, ri);	    append(&next_object_file_charP, (char *)& ri, sizeof(ri));	}    }    return;}

⌨️ 快捷键说明

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