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

📄 tc-tahoe.c

📁 基于4个mips核的noc设计
💻 C
📖 第 1 页 / 共 4 页
字号:
	bit 4 as extern and the last nibble as 'undefined'.  */#if commentvoidmd_ri_to_chars (ri_p, ri)     struct relocation_info *ri_p, ri;{  byte the_bytes[sizeof (struct relocation_info)];  /* The reason I can't just encode these directly into ri_p is that     ri_p may point to ri.  */  /* 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_symbolnum >> 16) & 0x0ff;  the_bytes[5] = (ri.r_symbolnum >> 8) & 0x0ff;  the_bytes[6] = ri.r_symbolnum & 0x0ff;  the_bytes[7] = (((ri.r_extern << 4) & 0x10) | ((ri.r_length << 5) & 0x60) |		  ((ri.r_pcrel << 7) & 0x80)) & 0xf0;  bcopy (the_bytes, (char *) ri_p, sizeof (struct relocation_info));}#endif /* comment *//* Put the bits in an order that a tahoe will understand, despite the ordering   of the native machine.   On Tahoe: first 4 bytes are normal unsigned big endian long,   next three bytes are symbolnum, in kind of 3 byte big endian (least sig. byte last).   The last byte is broken up with bit 7 as pcrel,   	bits 6 & 5 as length,	bit 4 as extern and the last nibble as 'undefined'.  */voidtc_aout_fix_to_chars (where, fixP, segment_address_in_file)     char *where;     fixS *fixP;     relax_addressT segment_address_in_file;{  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[4] = (r_symbolnum >> 16) & 0x0ff;  where[5] = (r_symbolnum >> 8) & 0x0ff;  where[6] = r_symbolnum & 0x0ff;  where[7] = (((is_pcrel (fixP) << 7) & 0x80)	      | ((((fixP->fx_type == FX_8 || fixP->fx_type == FX_PCREL8		    ? 0		    : (fixP->fx_type == FX_16 || fixP->fx_type == FX_PCREL16		       ? 1		    : (fixP->fx_type == FX_32 || fixP->fx_type == FX_PCREL32		       ? 2		       : 42)))) << 5) & 0x60)	      | ((!S_IS_DEFINED (fixP->fx_addsy) << 4) & 0x10));}/* Relocate byte stuff *//* This is for broken word.  */const int md_short_jump_size = 3;voidmd_create_short_jump (ptr, from_addr, to_addr, frag, to_symbol)     char *ptr;     addressT from_addr, to_addr;     fragS *frag;     symbolS *to_symbol;{  valueT offset;  offset = to_addr - (from_addr + 1);  *ptr++ = TAHOE_BRW;  md_number_to_chars (ptr, offset, 2);}const int md_long_jump_size = 6;const int md_reloc_size = 8;	/* Size of relocation record */voidmd_create_long_jump (ptr, from_addr, to_addr, frag, to_symbol)     char *ptr;     addressT from_addr, to_addr;     fragS *frag;     symbolS *to_symbol;{  valueT offset;  offset = to_addr - (from_addr + 4);  *ptr++ = TAHOE_JMP;  *ptr++ = TAHOE_PC_REL_LONG;  md_number_to_chars (ptr, offset, 4);}/* md_estimate_size_before_relax(), called just before relax().   Any symbol that is now undefined will not become defined.   Return the correct fr_subtype in the frag and the growth beyond   fr_fix.  */intmd_estimate_size_before_relax (fragP, segment_type)     register fragS *fragP;     segT segment_type;		/* N_DATA or N_TEXT.  */{  if (RELAX_LENGTH (fragP->fr_subtype) == STATE_UNDF)    {      if (S_GET_SEGMENT (fragP->fr_symbol) != segment)	{	  /* Non-relaxable cases.  */	  char *p;	  int old_fr_fix;	  old_fr_fix = fragP->fr_fix;	  p = fragP->fr_literal + old_fr_fix;	  switch (RELAX_STATE (fragP->fr_subtype))	    {	    case STATE_PC_RELATIVE:	      *p |= TAHOE_PC_OR_LONG;	      /* We now know how big it will be, one long word.  */	      fragP->fr_fix += 1 + 4;	      fix_new (fragP, old_fr_fix + 1, fragP->fr_symbol,		       fragP->fr_offset, FX_PCREL32, NULL);	      break;	    case STATE_CONDITIONAL_BRANCH:	      *fragP->fr_opcode ^= 0x10;	/* Reverse sense of branch.  */	      *p++ = 6;	      *p++ = TAHOE_JMP;	      *p++ = TAHOE_PC_REL_LONG;	      fragP->fr_fix += 1 + 1 + 1 + 4;	      fix_new (fragP, old_fr_fix + 3, fragP->fr_symbol,		       fragP->fr_offset, FX_PCREL32, NULL);	      break;	    case STATE_BIG_REV_BRANCH:	      *fragP->fr_opcode ^= 0x10;	/* Reverse sense of branch.  */	      *p++ = 0;	      *p++ = 6;	      *p++ = TAHOE_JMP;	      *p++ = TAHOE_PC_REL_LONG;	      fragP->fr_fix += 2 + 2 + 4;	      fix_new (fragP, old_fr_fix + 4, fragP->fr_symbol,		       fragP->fr_offset, FX_PCREL32, NULL);	      break;	    case STATE_BIG_NON_REV_BRANCH:	      *p++ = 2;	      *p++ = 0;	      *p++ = TAHOE_BRB;	      *p++ = 6;	      *p++ = TAHOE_JMP;	      *p++ = TAHOE_PC_REL_LONG;	      fragP->fr_fix += 2 + 2 + 2 + 4;	      fix_new (fragP, old_fr_fix + 6, fragP->fr_symbol,		       fragP->fr_offset, FX_PCREL32, NULL);	      break;	    case STATE_ALWAYS_BRANCH:	      *fragP->fr_opcode = TAHOE_JMP;	      *p++ = TAHOE_PC_REL_LONG;	      fragP->fr_fix += 1 + 4;	      fix_new (fragP, old_fr_fix + 1, fragP->fr_symbol,		       fragP->fr_offset, FX_PCREL32, NULL);	      break;	    default:	      abort ();	    }	  frag_wane (fragP);	  /* Return the growth in the fixed part of the frag.  */	  return fragP->fr_fix - old_fr_fix;	}      /* Relaxable cases.  Set up the initial guess for the variable	 part of the frag.  */      switch (RELAX_STATE (fragP->fr_subtype))	{	case STATE_PC_RELATIVE:	  fragP->fr_subtype = ENCODE_RELAX (STATE_PC_RELATIVE, STATE_BYTE);	  break;	case STATE_CONDITIONAL_BRANCH:	  fragP->fr_subtype = ENCODE_RELAX (STATE_CONDITIONAL_BRANCH, STATE_BYTE);	  break;	case STATE_BIG_REV_BRANCH:	  fragP->fr_subtype = ENCODE_RELAX (STATE_BIG_REV_BRANCH, STATE_WORD);	  break;	case STATE_BIG_NON_REV_BRANCH:	  fragP->fr_subtype = ENCODE_RELAX (STATE_BIG_NON_REV_BRANCH, STATE_WORD);	  break;	case STATE_ALWAYS_BRANCH:	  fragP->fr_subtype = ENCODE_RELAX (STATE_ALWAYS_BRANCH, STATE_BYTE);	  break;	}    }  if (fragP->fr_subtype >= sizeof (md_relax_table) / sizeof (md_relax_table[0]))    abort ();  /* Return the size of the variable part of the frag.  */  return md_relax_table[fragP->fr_subtype].rlx_length;}/* *			md_convert_frag(); * * Called after relax() is finished. * In:	Address of frag. *	fr_type == rs_machine_dependent. *	fr_subtype is what the address relaxed to. * * Out:	Any fixSs and constants are set up. *	Caller will turn frag into a ".space 0". */voidmd_convert_frag (headers, seg, fragP)     object_headers *headers;     segT seg;     register fragS *fragP;{  register char *addressP;	/* -> _var to change.  */  register char *opcodeP;	/* -> opcode char(s) to change.  */  register short int extension = 0;	/* Size of relaxed address.				   Added to fr_fix: incl. ALL var chars.  */  register symbolS *symbolP;  register long int where;  register long int address_of_var;  /* Where, in file space, is _var of *fragP? */  register long int target_address;  /* Where, in file space, does addr point? */  know (fragP->fr_type == rs_machine_dependent);  where = fragP->fr_fix;  addressP = fragP->fr_literal + where;  opcodeP = fragP->fr_opcode;  symbolP = fragP->fr_symbol;  know (symbolP);  target_address = S_GET_VALUE (symbolP) + fragP->fr_offset;  address_of_var = fragP->fr_address + where;  switch (fragP->fr_subtype)    {    case ENCODE_RELAX (STATE_PC_RELATIVE, STATE_BYTE):      /* *addressP holds the registers number, plus 0x10, if it's deferred       mode. To set up the right mode, just OR the size of this displacement */      /* Byte displacement.  */      *addressP++ |= TAHOE_PC_OR_BYTE;      *addressP = target_address - (address_of_var + 2);      extension = 2;      break;    case ENCODE_RELAX (STATE_PC_RELATIVE, STATE_WORD):      /* Word displacement.  */      *addressP++ |= TAHOE_PC_OR_WORD;      md_number_to_chars (addressP, target_address - (address_of_var + 3), 2);      extension = 3;      break;    case ENCODE_RELAX (STATE_PC_RELATIVE, STATE_LONG):      /* Long word displacement.  */      *addressP++ |= TAHOE_PC_OR_LONG;      md_number_to_chars (addressP, target_address - (address_of_var + 5), 4);      extension = 5;      break;    case ENCODE_RELAX (STATE_CONDITIONAL_BRANCH, STATE_BYTE):      *addressP = target_address - (address_of_var + 1);      extension = 1;      break;    case ENCODE_RELAX (STATE_CONDITIONAL_BRANCH, STATE_WORD):      *opcodeP ^= 0x10;		/* Reverse sense of test.  */      *addressP++ = 3;		/* Jump over word branch */      *addressP++ = TAHOE_BRW;      md_number_to_chars (addressP, target_address - (address_of_var + 4), 2);      extension = 4;      break;    case ENCODE_RELAX (STATE_CONDITIONAL_BRANCH, STATE_LONG):      *opcodeP ^= 0x10;		/* Reverse sense of test.  */      *addressP++ = 6;      *addressP++ = TAHOE_JMP;      *addressP++ = TAHOE_PC_REL_LONG;      md_number_to_chars (addressP, target_address, 4);      extension = 7;      break;    case ENCODE_RELAX (STATE_ALWAYS_BRANCH, STATE_BYTE):      *addressP = target_address - (address_of_var + 1);      extension = 1;      break;    case ENCODE_RELAX (STATE_ALWAYS_BRANCH, STATE_WORD):      *opcodeP = TAHOE_BRW;      md_number_to_chars (addressP, target_address - (address_of_var + 2), 2);      extension = 2;      break;    case ENCODE_RELAX (STATE_ALWAYS_BRANCH, STATE_LONG):      *opcodeP = TAHOE_JMP;      *addressP++ = TAHOE_PC_REL_LONG;      md_number_to_chars (addressP, target_address - (address_of_var + 5), 4);      extension = 5;      break;    case ENCODE_RELAX (STATE_BIG_REV_BRANCH, STATE_WORD):      md_number_to_chars (addressP, target_address - (address_of_var + 2), 2);      extension = 2;      break;    case ENCODE_RELAX (STATE_BIG_REV_BRANCH, STATE_LONG):      *opcodeP ^= 0x10;      *addressP++ = 0;      *addressP++ = 6;      *addressP++ = TAHOE_JMP;      *addressP++ = TAHOE_PC_REL_LONG;      md_number_to_chars (addressP, target_address, 4);      extension = 8;      break;    case ENCODE_RELAX (STATE_BIG_NON_REV_BRANCH, STATE_WORD):      md_number_to_chars (addressP, target_address - (address_of_var + 2), 2);      extension = 2;      break;    case ENCODE_RELAX (STATE_BIG_NON_REV_BRANCH, STATE_LONG):      *addressP++ = 0;      *addressP++ = 2;      *addressP++ = TAHOE_BRB;      *addressP++ = 6;      *addressP++ = TAHOE_JMP;      *addressP++ = TAHOE_PC_REL_LONG;      md_number_to_chars (addressP, target_address, 4);      extension = 10;      break;    default:      BAD_CASE (fragP->fr_subtype);      break;    }  fragP->fr_fix += extension;}				/* md_convert_frag *//* This is the stuff for md_assemble.  */#define FP_REG 13#define SP_REG 14#define PC_REG 15#define BIGGESTREG PC_REG/* * Parse the string pointed to by START * If it represents a valid register, point START to the character after * the last valid register char, and return the register number (0-15). * If invalid, leave START alone, return -1. * The format has to be exact. I don't do things like eat leading zeros * or the like. * Note: This doesn't check for the next character in the string making * this invalid. Ex: R123 would return 12, it's the callers job to check * what start is point to apon return. * * Valid registers are R1-R15, %1-%15, FP (13), SP (14), PC (15) * Case doesn't matter. */inttahoe_reg_parse (start)     char **start;		/* A pointer to the string to parse.  */{  register char *regpoint = *start;  register int regnum = -1;  switch (*regpoint++)    {    case '%':			/* Registers can start with a %,				   R or r, and then a number.  */    case 'R':    case 'r':      if (isdigit (*regpoint))	{	  /* Got the first digit.  */	  regnum = *regpoint++ - '0';	  if ((regnum == 1) && isdigit (*regpoint))	    {	      /* Its a two digit number.  */	      regnum = 10 + (*regpoint++ - '0');	      if (regnum > BIGGESTREG)		{		/* Number too big? */		  regnum = -1;		}	    }	}      break;    case 'F':			/* Is it the FP */    case 'f':      switch (*regpoint++)	{	case 'p':	case 'P':	  regnum = FP_REG;	}      break;    case 's':			/* How about the SP */    case 'S':      switch (*regpoint++)	{	case 'p':	case 'P':	  regnum = SP_REG;	}      break;    case 'p':			/* OR the PC even */    case 'P':      switch (*regpoint++)	{	case 'c':	case 'C':	  regnum = PC_REG;	}      break;    }  if (regnum != -1)    {				/* No error, so move string pointer */      *start = regpoint;    }  return regnum;		/* Return results */}				/* tahoe_reg_parse *//* * This chops up an operand and figures out its modes and stuff. * It's a little touchy about extra characters. * Optex to start with one extra character so it can be overwritten for * the backward part of the parsing. * You can't put a bunch of extra characters in side to * make the command look cute. ie: * foo ( r1 ) [  r0 ] * If you like doing a lot of typing, try COBOL! * Actually, this parser is a little weak all around. It's designed to be * used with compliers, so I emphisise correct decoding of valid code quickly * rather that catching every possable error. * Note: This uses the expression function, so save input_line_pointer before * calling. * * Sperry defines the semantics of address modes (and values) * by a two-letter code, explained here. * *   letter 1:   access type * *     a         address calculation - no data access, registers forbidden *     b         branch displacement *     m         read - let go of bus - write back "modify" *     r         read *     w         write *     v         bit field address: like 'a' but registers are OK * *   letter 2:   data type (i.e. width, alignment) * *     b         byte *     w         word *     l         longword *     q         quadword (Even regs < 14 allowed) (if 12, you get a warning) *     -	 unconditional synthetic jbr operand *     ?	 simple synthetic reversable branch operand *     !	 complex synthetic reversable branch operand *     :	 complex synthetic non-reversable branch operand * * The '-?!:' letter 2's are not for external consumption. They are used * by GAS for psuedo ops relaxing code. * * After parsing topP has: * *   top_ndx:        -1, or the index register. eg 7=[R7] *   top_reg:        -1, or register number. eg 7 = R7 or (R7) *   top_mode:       The addressing mode byte. This byte, defines which of *                   the 11 modes opcode is. *   top_access:     Access type wanted for this opperand 'b'branch ' ' *                   no-instruction 'amrvw' *   top_width:      Operand width expected, one of "bwlq?-:!" *   exp_of_operand: The expression as parsed by expression() *   top_dispsize:   Number of bytes in the displacement if we can figure it *                   out and it's relavent. * * Need syntax checks built. */voidtip_op (optex, topP)     char *optex;		/* The users text input, with one leading character */     struct top *topP;		/* The tahoe instruction with some fields already set:			 in: access, width			 out: ndx, reg, mode, error, dispsize */{  int mode = 0;			/* This operand's mode.  */  char segfault = *optex;	/* To keep the back parsing from freaking.  */  char *point = optex + 1;	/* Parsing from front to back.  */  char *end;			/* Parsing from back to front.  */

⌨️ 快捷键说明

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