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

📄 tc-vax.c

📁 基于4个mips核的noc设计
💻 C
📖 第 1 页 / 共 5 页
字号:
  switch (fragP->fr_subtype)    {    case ENCODE_RELAX (STATE_PC_RELATIVE, STATE_BYTE):      know (*addressP == 0 || *addressP == 0x10);	/* '@' bit.  */      addressP[0] |= 0xAF;	/* Byte displacement.  */      addressP[1] = target_address - (address_of_var + 2);      extension = 2;      break;    case ENCODE_RELAX (STATE_PC_RELATIVE, STATE_WORD):      know (*addressP == 0 || *addressP == 0x10);	/* '@' bit.  */      addressP[0] |= 0xCF;	/* Word displacement.  */      md_number_to_chars (addressP + 1, target_address - (address_of_var + 3), 2);      extension = 3;      break;    case ENCODE_RELAX (STATE_PC_RELATIVE, STATE_LONG):      know (*addressP == 0 || *addressP == 0x10);	/* '@' bit.  */      addressP[0] |= 0xEF;	/* Long word displacement.  */      md_number_to_chars (addressP + 1, target_address - (address_of_var + 5), 4);      extension = 5;      break;    case ENCODE_RELAX (STATE_CONDITIONAL_BRANCH, STATE_BYTE):      addressP[0] = target_address - (address_of_var + 1);      extension = 1;      break;    case ENCODE_RELAX (STATE_CONDITIONAL_BRANCH, STATE_WORD):      opcodeP[0] ^= 1;		/* Reverse sense of test.  */      addressP[0] = 3;      addressP[1] = VAX_BRB + VAX_WIDEN_WORD;      md_number_to_chars (addressP + 2, target_address - (address_of_var + 4), 2);      extension = 4;      break;    case ENCODE_RELAX (STATE_CONDITIONAL_BRANCH, STATE_LONG):      opcodeP[0] ^= 1;		/* Reverse sense of test.  */      addressP[0] = 6;      addressP[1] = VAX_JMP;      addressP[2] = VAX_PC_RELATIVE_MODE;      md_number_to_chars (addressP + 3, target_address - (address_of_var + 7), 4);      extension = 7;      break;    case ENCODE_RELAX (STATE_ALWAYS_BRANCH, STATE_BYTE):      addressP[0] = target_address - (address_of_var + 1);      extension = 1;      break;    case ENCODE_RELAX (STATE_ALWAYS_BRANCH, STATE_WORD):      opcodeP[0] += VAX_WIDEN_WORD;	/* brb -> brw, bsbb -> bsbw */      md_number_to_chars (addressP, target_address - (address_of_var + 2), 2);      extension = 2;      break;    case ENCODE_RELAX (STATE_ALWAYS_BRANCH, STATE_LONG):      opcodeP[0] += VAX_WIDEN_LONG;	/* brb -> jmp, bsbb -> jsb */      addressP[0] = VAX_PC_RELATIVE_MODE;      md_number_to_chars (addressP + 1, target_address - (address_of_var + 5), 4);      extension = 5;      break;    case ENCODE_RELAX (STATE_COMPLEX_BRANCH, STATE_WORD):      md_number_to_chars (addressP, target_address - (address_of_var + 2), 2);      extension = 2;      break;    case ENCODE_RELAX (STATE_COMPLEX_BRANCH, STATE_LONG):      addressP[0] = 2;      addressP[1] = 0;      addressP[2] = VAX_BRB;      addressP[3] = 6;      addressP[4] = VAX_JMP;      addressP[5] = VAX_PC_RELATIVE_MODE;      md_number_to_chars (addressP + 6, target_address - (address_of_var + 10), 4);      extension = 10;      break;    case ENCODE_RELAX (STATE_COMPLEX_HOP, STATE_BYTE):      addressP[0] = target_address - (address_of_var + 1);      extension = 1;      break;    case ENCODE_RELAX (STATE_COMPLEX_HOP, STATE_WORD):      addressP[0] = 2;      addressP[1] = VAX_BRB;      addressP[2] = 3;      addressP[3] = VAX_BRW;      md_number_to_chars (addressP + 4, target_address - (address_of_var + 6), 2);      extension = 6;      break;    case ENCODE_RELAX (STATE_COMPLEX_HOP, STATE_LONG):      addressP[0] = 2;      addressP[1] = VAX_BRB;      addressP[2] = 6;      addressP[3] = VAX_JMP;      addressP[4] = VAX_PC_RELATIVE_MODE;      md_number_to_chars (addressP + 5, target_address - (address_of_var + 9), 4);      extension = 9;      break;    default:      BAD_CASE (fragP->fr_subtype);      break;    }  fragP->fr_fix += extension;}				/* md_convert_frag() *//* Translate internal format of relocation info into target format.   On vax: first 4 bytes are normal unsigned long, next three bytes   are symbolnum, least sig. byte first.  Last byte is broken up with   the upper nibble as nuthin, bit 3 as extern, bits 2 & 1 as length, and   bit 0 as pcrel.  */#ifdef commentvoidmd_ri_to_chars (the_bytes, ri)     char *the_bytes;     struct reloc_info_generic ri;{  /* this is easy */  md_number_to_chars (the_bytes, ri.r_address, sizeof (ri.r_address));  /* now the fun stuff */  the_bytes[6] = (ri.r_symbolnum >> 16) & 0x0ff;  the_bytes[5] = (ri.r_symbolnum >> 8) & 0x0ff;  the_bytes[4] = ri.r_symbolnum & 0x0ff;  the_bytes[7] = (((ri.r_extern << 3) & 0x08) | ((ri.r_length << 1) & 0x06) |		  ((ri.r_pcrel << 0) & 0x01)) & 0x0F;}#endif /* comment */voidtc_aout_fix_to_chars (where, fixP, segment_address_in_file)     char *where;     fixS *fixP;     relax_addressT segment_address_in_file;{  /*   * In: length of relocation (or of address) in chars: 1, 2 or 4.   * Out: GNU LD relocation length code: 0, 1, or 2.   */  static const unsigned char nbytes_r_length[] = {42, 0, 1, 42, 2};  long r_symbolnum;  know (fixP->fx_addsy != NULL);  md_number_to_chars (where,       fixP->fx_frag->fr_address + fixP->fx_where - segment_address_in_file,		      4);  r_symbolnum = (S_IS_DEFINED (fixP->fx_addsy)		 ? S_GET_TYPE (fixP->fx_addsy)		 : fixP->fx_addsy->sy_number);  where[6] = (r_symbolnum >> 16) & 0x0ff;  where[5] = (r_symbolnum >> 8) & 0x0ff;  where[4] = r_symbolnum & 0x0ff;  where[7] = ((((!S_IS_DEFINED (fixP->fx_addsy)) << 3) & 0x08)	      | ((nbytes_r_length[fixP->fx_size] << 1) & 0x06)	      | (((fixP->fx_pcrel << 0) & 0x01) & 0x0f));}/* *       BUGS, GRIPES,  APOLOGIA, etc. * * The opcode table 'votstrs' needs to be sorted on opcode frequency. * That is, AFTER we hash it with hash_...(), we want most-used opcodes * to come out of the hash table faster. * * I am sorry to inflict yet another VAX assembler on the world, but * RMS says we must do everything from scratch, to prevent pin-heads * restricting this software. *//* * This is a vaguely modular set of routines in C to parse VAX * assembly code using DEC mnemonics. It is NOT un*x specific. * * The idea here is that the assembler has taken care of all: *   labels *   macros *   listing *   pseudo-ops *   line continuation *   comments *   condensing any whitespace down to exactly one space * and all we have to do is parse 1 line into a vax instruction * partially formed. We will accept a line, and deliver: *   an error message (hopefully empty) *   a skeleton VAX instruction (tree structure) *   textual pointers to all the operand expressions *   a warning message that notes a silly operand (hopefully empty) *//* *		E D I T   H I S T O R Y * * 17may86 Dean Elsner. Bug if line ends immediately after opcode. * 30apr86 Dean Elsner. New vip_op() uses arg block so change call. *  6jan86 Dean Elsner. Crock vip_begin() to call vip_op_defaults(). *  2jan86 Dean Elsner. Invent synthetic opcodes. *	Widen vax_opcodeT to 32 bits. Use a bit for VIT_OPCODE_SYNTHETIC, *	which means this is not a real opcode, it is like a macro; it will *	be relax()ed into 1 or more instructions. *	Use another bit for VIT_OPCODE_SPECIAL if the op-code is not optimised *	like a regular branch instruction. Option added to vip_begin(): *	exclude	synthetic opcodes. Invent synthetic_votstrs[]. * 31dec85 Dean Elsner. Invent vit_opcode_nbytes. *	Also make vit_opcode into a char[]. We now have n-byte vax opcodes, *	so caller's don't have to know the difference between a 1-byte & a *	2-byte op-code. Still need vax_opcodeT concept, so we know how *	big an object must be to hold an op.code. * 30dec85 Dean Elsner. Widen typedef vax_opcodeT in "vax-inst.h" *	because vax opcodes may be 16 bits. Our crufty C compiler was *	happily initialising 8-bit vot_codes with 16-bit numbers! *	(Wouldn't the 'phone company like to compress data so easily!) * 29dec85 Dean Elsner. New static table vax_operand_width_size[]. *	Invented so we know hw many bytes a "I^#42" needs in its immediate *	operand. Revised struct vop in "vax-inst.h": explicitly include *	byte length of each operand, and it's letter-code datum type. * 17nov85 Dean Elsner. Name Change. *	Due to ar(1) truncating names, we learned the hard way that *	"vax-inst-parse.c" -> "vax-inst-parse." dropping the "o" off *	the archived object name. SO... we shortened the name of this *	source file, and changed the makefile. *//* handle of the OPCODE hash table */static struct hash_control *op_hash;/* * In:	1 character, from "bdfghloqpw" being the data-type of an operand *	of a vax instruction. * * Out:	the length of an operand of that type, in bytes. *	Special branch operands types "-?!" have length 0. */static const short int vax_operand_width_size[256] ={  0, 0, 0, 0, 0, 0, 0, 0,  0, 0, 0, 0, 0, 0, 0, 0,  0, 0, 0, 0, 0, 0, 0, 0,  0, 0, 0, 0, 0, 0, 0, 0,  0, 0, 0, 0, 0, 0, 0, 0,  0, 0, 0, 0, 0, 0, 0, 0,  0, 0, 0, 0, 0, 0, 0, 0,  0, 0, 0, 0, 0, 0, 0, 0,  0, 0, 1, 0, 8, 0, 4, 8, 16, 0, 0, 0, 4, 0, 0,16,	/* ..b.d.fgh...l..o  */  0, 8, 0, 0, 0, 0, 0, 2,  0, 0, 0, 0, 0, 0, 0, 0,	/* .q.....w........  */  0, 0, 1, 0, 8, 0, 4, 8, 16, 0, 0, 0, 4, 0, 0,16,	/* ..b.d.fgh...l..o  */  0, 8, 0, 0, 0, 0, 0, 2,  0, 0, 0, 0, 0, 0, 0, 0,	/* .q.....w........  */  0, 0, 0, 0, 0, 0, 0, 0,  0, 0, 0, 0, 0, 0, 0, 0,  0, 0, 0, 0, 0, 0, 0, 0,  0, 0, 0, 0, 0, 0, 0, 0,  0, 0, 0, 0, 0, 0, 0, 0,  0, 0, 0, 0, 0, 0, 0, 0,  0, 0, 0, 0, 0, 0, 0, 0,  0, 0, 0, 0, 0, 0, 0, 0,  0, 0, 0, 0, 0, 0, 0, 0,  0, 0, 0, 0, 0, 0, 0, 0,  0, 0, 0, 0, 0, 0, 0, 0,  0, 0, 0, 0, 0, 0, 0, 0,  0, 0, 0, 0, 0, 0, 0, 0,  0, 0, 0, 0, 0, 0, 0, 0,  0, 0, 0, 0, 0, 0, 0, 0,  0, 0, 0, 0, 0, 0, 0, 0,};/* * This perversion encodes all the vax opcodes as a bunch of strings. * RMS says we should build our hash-table at run-time. Hmm. * Please would someone arrange these in decreasing frequency of opcode? * Because of the way hash_...() works, the most frequently used opcode * should be textually first and so on. * * Input for this table was 'vax.opcodes', awk(1)ed by 'vax.opcodes.c.awk' . * So change 'vax.opcodes', then re-generate this table. */#include "opcode/vax.h"/* * This is a table of optional op-codes. All of them represent * 'synthetic' instructions that seem popular. * * Here we make some pseudo op-codes. Every code has a bit set to say * it is synthetic. This lets you catch them if you want to * ban these opcodes. They are mnemonics for "elastic" instructions * that are supposed to assemble into the fewest bytes needed to do a * branch, or to do a conditional branch, or whatever. * * The opcode is in the usual place [low-order n*8 bits]. This means * that if you mask off the bucky bits, the usual rules apply about * how long the opcode is. * * All VAX branch displacements come at the end of the instruction. * For simple branches (1-byte opcode + 1-byte displacement) the last * operand is coded 'b?' where the "data type" '?' is a clue that we * may reverse the sense of the branch (complement lowest order bit) * and branch around a jump. This is by far the most common case. * That is why the VIT_OPCODE_SYNTHETIC bit is set: it says this is * a 0-byte op-code followed by 2 or more bytes of operand address. * * If the op-code has VIT_OPCODE_SPECIAL set, then we have a more unusual * case. * * For JBSB & JBR the treatment is the similar, except (1) we have a 'bw' * option before (2) we can directly JSB/JMP because there is no condition. * These operands have 'b-' as their access/data type. * * That leaves a bunch of random opcodes: JACBx, JxOBxxx. In these * cases, we do the same idea. JACBxxx are all marked with a 'b!' * JAOBxxx & JSOBxxx are marked with a 'b:'. * */#if (VIT_OPCODE_SYNTHETIC != 0x80000000)You have just broken the encoding below, which assumes the sign bit  means 'I am an imaginary instruction'.#endif#if (VIT_OPCODE_SPECIAL != 0x40000000)  You have just broken the encoding below, which assumes the 0x40 M bit means  'I am not to be "optimised" the way normal branches are'.#endifstatic const struct vot  synthetic_votstrs[] ={  {"jbsb",	{"b-", 0xC0000010}},		/* BSD 4.2 *//* jsb used already */  {"jbr",	{"b-", 0xC0000011}},		/* BSD 4.2 */  {"jr",	{"b-", 0xC0000011}},		/* consistent */  {"jneq",	{"b?", 0x80000012}},  {"jnequ",	{"b?", 0x80000012}},  {"jeql",	{"b?", 0x80000013}},  {"jeqlu",	{"b?", 0x80000013}},  {"jgtr",	{"b?", 0x80000014}},  {"jleq",	{"b?", 0x80000015}},/* un-used opcodes here */  {"jgeq",	{"b?", 0x80000018}},  {"jlss",	{"b?", 0x80000019}},  {"jgtru",	{"b?", 0x8000001a}},  {"jlequ",	{"b?", 0x8000001b}},  {"jvc",	{"b?", 0x8000001c}},  {"jvs",	{"b?", 0x8000001d}},  {"jgequ",	{"b?", 0x8000001e}},  {"jcc",	{"b?", 0x8000001e}},  {"jlssu",	{"b?", 0x8000001f}},  {"jcs",	{"b?", 0x8000001f}},  {"jacbw",	{"rwrwmwb!", 0xC000003d}},  {"jacbf",	{"rfrfmfb!", 0xC000004f}},  {"jacbd",	{"rdrdmdb!", 0xC000006f}},  {"jacbb",	{"rbrbmbb!", 0xC000009d}},  {"jacbl",	{"rlrlmlb!", 0xC00000f1}},  {"jacbg",	{"rgrgmgb!", 0xC0004ffd}},  {"jacbh",	{"rhrhmhb!", 0xC0006ffd}},  {"jbs",	{"rlvbb?", 0x800000e0}},  {"jbc",	{"rlvbb?", 0x800000e1}},  {"jbss",	{"rlvbb?", 0x800000e2}},  {"jbcs",	{"rlvbb?", 0x800000e3}},  {"jbsc",	{"rlvbb?", 0x800000e4}},  {"jbcc",	{"rlvbb?", 0x800000e5}},  {"jlbs",	{"rlb?", 0x800000e8}},  {"jlbc",	{"rlb?", 0x800000e9}},  {"jaoblss",	{"rlmlb:", 0xC00000f2}},  {"jaobleq",	{"rlmlb:", 0xC00000f3}},  {"jsobgeq",	{"mlb:", 0xC00000f4}},  {"jsobgtr",	{"mlb:", 0xC00000f5}},/* CASEx has no branch addresses in our conception of it.  *//* You should use ".word ..." statements after the "case ...".  */  {"",	{"", 0}}			/* empty is end sentinel */};				/* synthetic_votstrs *//* *                  v i p _ b e g i n ( ) * * Call me once before you decode any lines. * I decode votstrs into a hash table at op_hash (which I create). * I return an error text or null. * If you want, I will include the 'synthetic' jXXX instructions in the * instruction table. * You must nominate metacharacters for eg DEC's "#", "@", "^". */static const char *vip_begin (synthetic_too, immediate, indirect, displen)     int synthetic_too;		/* 1 means include jXXX op-codes.  */     const char *immediate, *indirect, *displen;{  const struct vot *vP;		/* scan votstrs */  const char *retval = 0;	/* error text */  op_hash = hash_new ();  for (vP = votstrs; *vP->vot_name && !retval; vP++)    retval = hash_insert (op_hash, vP->vot_name, (PTR) &vP->vot_detail);  if (synthetic_too)    for (vP = synthetic_votstrs; *vP->vot_name && !retval; vP++)      retval = hash_insert (op_hash, vP->vot_name, (PTR) &vP->vot_detail);#ifndef CONST_TABLE  vip_op_defaults (immediate, indirect, displen);#endif  return retval;}/* *                  v i p ( ) * * This converts a string into a vax instruction. * The string must be a bare single instruction in dec-vax (with BSD4 frobs) * format. * It provides some error messages: at most one fatal error message (which * stops the scan) and at most one warning message for each operand. * The vax instruction is returned in exploded form, since we have no * knowledge of how you parse (or evaluate) your expressions. * We do however strip off and decode addressing modes and operation * mnemonic. * * The exploded instruction is returned to a struct vit of your choice. * #include "vax-inst.h" to know what a struct vit is. * * This function's value is a string. If it is not "" then an internal * logic error was found: read this code to assign meaning to the string. * No argument string should generate such an error string: * it means a bug in our code, not in the user's text. *

⌨️ 快捷键说明

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