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

📄 tc-tahoe.c

📁 基于4个mips核的noc设计
💻 C
📖 第 1 页 / 共 4 页
字号:
/* This file is tc-tahoe.c   Copyright 1987, 1988, 1989, 1990, 1991, 1992, 1995, 2000   Free Software Foundation, Inc.   This file is part of GAS, the GNU Assembler.   GAS is free software; you can redistribute it and/or modify   it under the terms of the GNU General Public License as published by   the Free Software Foundation; either version 2, or (at your option)   any later version.   GAS is distributed in the hope that it will be useful,   but WITHOUT ANY WARRANTY; without even the implied warranty of   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the   GNU General Public License for more details.   You should have received a copy of the GNU General Public License   along with GAS; see the file COPYING.  If not, write to the Free   Software Foundation, 59 Temple Place - Suite 330, Boston, MA   02111-1307, USA.  */#include "as.h"#include "obstack.h"/* This bit glommed from tahoe-inst.h.  */typedef unsigned char byte;typedef byte tahoe_opcodeT;/* This is part of tahoe-ins-parse.c & friends.   We want to parse a tahoe instruction text into a tree defined here.  */#define TIT_MAX_OPERANDS (4)	/* maximum number of operands in one				   single tahoe instruction */struct top			/* tahoe instruction operand */  {    int top_ndx;		/* -1, or index register. eg 7=[R7] */    int top_reg;		/* -1, or register number. eg 7 = R7 or (R7) */    byte top_mode;		/* Addressing mode byte. This byte, defines				   which of the 11 modes opcode is.  */    char top_access;		/* Access type wanted for this opperand				   'b'branch ' 'no-instruction 'amrvw' */    char top_width;		/* Operand width expected, one of "bwlq?-:!" */    char * top_error;		/* Say if operand is inappropriate         */    segT seg_of_operand;	/* segment as returned by expression()*/    expressionS exp_of_operand;	/* The expression as parsed by expression()*/    byte top_dispsize;		/* Number of bytes in the displacement if we				   can figure it out */  };/* The addressing modes for an operand. These numbers are the acutal values   for certain modes, so be carefull if you screw with them.  */#define TAHOE_DIRECT_REG (0x50)#define TAHOE_REG_DEFERRED (0x60)#define TAHOE_REG_DISP (0xE0)#define TAHOE_REG_DISP_DEFERRED (0xF0)#define TAHOE_IMMEDIATE (0x8F)#define TAHOE_IMMEDIATE_BYTE (0x88)#define TAHOE_IMMEDIATE_WORD (0x89)#define TAHOE_IMMEDIATE_LONGWORD (0x8F)#define TAHOE_ABSOLUTE_ADDR (0x9F)#define TAHOE_DISPLACED_RELATIVE (0xEF)#define TAHOE_DISP_REL_DEFERRED (0xFF)#define TAHOE_AUTO_DEC (0x7E)#define TAHOE_AUTO_INC (0x8E)#define TAHOE_AUTO_INC_DEFERRED (0x9E)/* INDEXED_REG is decided by the existance or lack of a [reg].  *//* These are encoded into top_width when top_access=='b'   and it's a psuedo op.  */#define TAHOE_WIDTH_ALWAYS_JUMP      '-'#define TAHOE_WIDTH_CONDITIONAL_JUMP '?'#define TAHOE_WIDTH_BIG_REV_JUMP     '!'#define TAHOE_WIDTH_BIG_NON_REV_JUMP ':'/* The hex code for certain tahoe commands and modes.   This is just for readability.  */#define TAHOE_JMP (0x71)#define TAHOE_PC_REL_LONG (0xEF)#define TAHOE_BRB (0x11)#define TAHOE_BRW (0x13)/* These, when 'ored' with, or added to, a register number,   set up the number for the displacement mode.  */#define TAHOE_PC_OR_BYTE (0xA0)#define TAHOE_PC_OR_WORD (0xC0)#define TAHOE_PC_OR_LONG (0xE0)struct tit			/* Get it out of the sewer, it stands for				   tahoe instruction tree (Geeze!).  */{  tahoe_opcodeT tit_opcode;	/* The opcode.  */  byte tit_operands;		/* How many operands are here.  */  struct top tit_operand[TIT_MAX_OPERANDS];	/* Operands */  char *tit_error;		/* "" or fatal error text */};/* end: tahoe-inst.h *//* tahoe.c - tahoe-specific -   Not part of gas yet.   */#include "opcode/tahoe.h"/* This is the number to put at the beginning of the a.out file */long omagic = OMAGIC;/* These chars start a comment anywhere in a source file (except inside   another comment or a quoted string.  */const char comment_chars[] = "#;";/* These chars only start a comment at the beginning of a line.  */const char line_comment_chars[] = "#";/* Chars that can be used to separate mant from exp in floating point nums */const char EXP_CHARS[] = "eE";/* Chars that mean this number is a floating point constant   as in 0f123.456   or    0d1.234E-12 (see exp chars above)   Note: The Tahoe port doesn't support floating point constants. This is         consistant with 'as' If it's needed, I can always add it later.  */const char FLT_CHARS[] = "df";/* Also be aware that MAXIMUM_NUMBER_OF_CHARS_FOR_FLOAT may have to be   changed in read.c .  Ideally it shouldn't have to know about it at all,   but nothing is ideal around here.   (The tahoe has plenty of room, so the change currently isn't needed.)   */static struct tit t;		/* A tahoe instruction after decoding.  */void float_cons ();/* A table of pseudo ops (sans .), the function called, and an integer op   that the function is called with.  */const pseudo_typeS md_pseudo_table[] ={  {"dfloat", float_cons, 'd'},  {"ffloat", float_cons, 'f'},  {0}};/* * For Tahoe, relative addresses of "just the right length" are pretty easy. * The branch displacement is always the last operand, even in * synthetic instructions. * For Tahoe, we encode the relax_substateTs (in e.g. fr_substate) as: * *		    4       3       2       1       0	     bit number *	---/ /--+-------+-------+-------+-------+-------+ *		|     what state ?	|  how long ?	| *	---/ /--+-------+-------+-------+-------+-------+ * * The "how long" bits are 00=byte, 01=word, 10=long. * This is a Un*x convention. * Not all lengths are legit for a given value of (what state). * The four states are listed below. * The "how long" refers merely to the displacement length. * The address usually has some constant bytes in it as well. *States for Tahoe address relaxing.1.	TAHOE_WIDTH_ALWAYS_JUMP (-)	Format: "b-"	Tahoe opcodes are:	(Hex)		jr		11		jbr		11	Simple branch.	Always, 1 byte opcode, then displacement/absolute.	If word or longword, change opcode to brw or jmp.2.	TAHOE_WIDTH_CONDITIONAL_JUMP (?)	J<cond> where <cond> is a simple flag test.	Format: "b?"	Tahoe opcodes are:	(Hex)		jneq/jnequ	21		jeql/jeqlu	31		jgtr		41		jleq		51		jgeq		81		jlss		91		jgtru		a1		jlequ		b1		jvc		c1		jvs		d1		jlssu/jcs	e1		jgequ/jcc	f1	Always, you complement 4th bit to reverse the condition.	Always, 1-byte opcode, then 1-byte displacement.3.	TAHOE_WIDTH_BIG_REV_JUMP (!)	Jbc/Jbs where cond tests a memory bit.	Format: "rlvlb!"	Tahoe opcodes are:	(Hex)		jbs		0e		jbc		1e	Always, you complement 4th bit to reverse the condition.	Always, 1-byte opcde, longword, longword-address, 1-word-displacement4.	TAHOE_WIDTH_BIG_NON_REV_JUMP (:)	JaoblXX/Jbssi	Format: "rlmlb:"	Tahoe opcodes are:	(Hex)		aojlss		2f		jaoblss		2f		aojleq		3f		jaobleq		3f		jbssi		5f	Always, we cannot reverse the sense of the branch; we have a word	displacement.We need to modify the opcode is for class 1, 2 and 3 instructions.After relax() we may complement the 4th bit of 2 or 3 to reverse sense ofbranch.We sometimes store context in the operand literal. This way we can figure outafter relax() what the original addressing mode was. (Was is pc_rel, orpc_rel_disp? That sort of thing.) *//* These displacements are relative to the START address of the   displacement which is at the start of the displacement, not the end of   the instruction. The hardware pc_rel is at the end of the instructions.   That's why all the displacements have the length of the displacement added   to them. (WF + length(word))   The first letter is Byte, Word.   2nd letter is Forward, Backward.  */#define BF (1+ 127)#define BB (1+-128)#define WF (2+ 32767)#define WB (2+-32768)/* Dont need LF, LB because they always reach. [They are coded as 0.] */#define C(a,b) ENCODE_RELAX(a,b)/* This macro has no side-effects.  */#define ENCODE_RELAX(what,length) (((what) << 2) + (length))#define RELAX_STATE(s) ((s) >> 2)#define RELAX_LENGTH(s) ((s) & 3)#define STATE_ALWAYS_BRANCH             (1)#define STATE_CONDITIONAL_BRANCH        (2)#define STATE_BIG_REV_BRANCH            (3)#define STATE_BIG_NON_REV_BRANCH        (4)#define STATE_PC_RELATIVE		(5)#define STATE_BYTE                      (0)#define STATE_WORD                      (1)#define STATE_LONG                      (2)#define STATE_UNDF                      (3)	/* Symbol undefined in pass1 *//* This is the table used by gas to figure out relaxing modes. The fields are   forward_branch reach, backward_branch reach, number of bytes it would take,   where the next biggest branch is.  */const relax_typeS md_relax_table[] ={  {    1, 1, 0, 0  },				/* error sentinel   0,0	*/  {    1, 1, 0, 0  },				/* unused	    0,1	*/  {    1, 1, 0, 0  },				/* unused	    0,2	*/  {    1, 1, 0, 0  },				/* unused	    0,3	*//* Unconditional branch cases "jrb"     The relax part is the actual displacement */  {    BF, BB, 1, C (1, 1)  },				/* brb B`foo	    1,0 */  {    WF, WB, 2, C (1, 2)  },				/* brw W`foo	    1,1 */  {    0, 0, 5, 0  },				/* Jmp L`foo	    1,2 */  {    1, 1, 0, 0  },				/* unused	    1,3 *//* Reversible Conditional Branch. If the branch won't reach, reverse     it, and jump over a brw or a jmp that will reach. The relax part is the     actual address.  */  {    BF, BB, 1, C (2, 1)  },				/* b<cond> B`foo    2,0 */  {    WF + 2, WB + 2, 4, C (2, 2)  },				/* brev over, brw W`foo, over: 2,1 */  {    0, 0, 7, 0  },				/* brev over, jmp L`foo, over: 2,2 */  {    1, 1, 0, 0  },				/* unused	    2,3 *//* Another type of reversable branch. But this only has a word     displacement.  */  {    1, 1, 0, 0  },				/* unused	    3,0 */  {    WF, WB, 2, C (3, 2)  },				/* jbX W`foo	    3,1 */  {    0, 0, 8, 0  },				/* jrevX over, jmp L`foo, over:  3,2 */  {    1, 1, 0, 0  },				/* unused	    3,3 *//* These are the non reversable branches, all of which have a word     displacement. If I can't reach, branch over a byte branch, to a     jump that will reach. The jumped branch jumps over the reaching     branch, to continue with the flow of the program. It's like playing     leap frog.  */  {    1, 1, 0, 0  },				/* unused	    4,0 */  {    WF, WB, 2, C (4, 2)  },				/* aobl_ W`foo	    4,1 */  {    0, 0, 10, 0  },				/*aobl_ W`hop,br over,hop: jmp L^foo,over 4,2*/  {    1, 1, 0, 0  },				/* unused	    4,3 *//* Normal displacement mode, no jumping or anything like that.     The relax points to one byte before the address, thats why all     the numbers are up by one.  */  {    BF + 1, BB + 1, 2, C (5, 1)  },				/* B^"foo"	    5,0 */  {    WF + 1, WB + 1, 3, C (5, 2)  },				/* W^"foo"	    5,1 */  {    0, 0, 5, 0  },				/* L^"foo"	    5,2 */  {    1, 1, 0, 0  },				/* unused	    5,3 */};#undef C#undef BF#undef BB#undef WF#undef WB/* End relax stuff *//* Handle of the OPCODE hash table.  NULL means any use before   md_begin() will crash.  */static struct hash_control *op_hash;/* Init function. Build the hash table.  */voidmd_begin (){  struct tot *tP;  char *errorval = 0;  int synthetic_too = 1;	/* If 0, just use real opcodes.  */  op_hash = hash_new ();  for (tP = totstrs; *tP->name && !errorval; tP++)    errorval = hash_insert (op_hash, tP->name, &tP->detail);  if (synthetic_too)    for (tP = synthetic_totstrs; *tP->name && !errorval; tP++)      errorval = hash_insert (op_hash, tP->name, &tP->detail);  if (errorval)    as_fatal (errorval);}CONST char *md_shortopts = "ad:STt:V";struct option md_longopts[] = {  {NULL, no_argument, NULL, 0}};size_t md_longopts_size = sizeof (md_longopts);intmd_parse_option (c, arg)     int c;     char *arg;{  switch (c)    {    case 'a':      as_warn (_("The -a option doesn't exist. (Despite what the man page says!"));      break;    case 'd':      as_warn (_("Displacement length %s ignored!"), arg);      break;    case 'S':      as_warn (_("SYMBOL TABLE not implemented"));      break;    case 'T':      as_warn (_("TOKEN TRACE not implemented"));      break;    case 't':      as_warn (_("I don't need or use temp. file \"%s\"."), arg);      break;    case 'V':      as_warn (_("I don't use an interpass file! -V ignored"));      break;    default:      return 0;    }  return 1;}voidmd_show_usage (stream)     FILE *stream;{  fprintf (stream, _("\Tahoe options:\n\-a			ignored\n\-d LENGTH		ignored\n\-J			ignored\n\-S			ignored\n\-t FILE			ignored\n\-T			ignored\n\-V			ignored\n"));}/* The functions in this section take numbers in the machine format, and   munges them into Tahoe byte order.   They exist primarily for cross assembly purpose.  */void				/* Knows about order of bytes in address.  */md_number_to_chars (con, value, nbytes)     char con[];		/* Return 'nbytes' of chars here.  */     valueT value;		/* The value of the bits.  */     int nbytes;		/* Number of bytes in the output.  */{  number_to_chars_bigendian (con, value, nbytes);}#ifdef commentvoid				/* Knows about order of bytes in address.  */md_number_to_imm (con, value, nbytes)     char con[];		/* Return 'nbytes' of chars here.  */     long int value;		/* The value of the bits.  */     int nbytes;		/* Number of bytes in the output.  */{  md_number_to_chars (con, value, nbytes);}#endif /* comment */voidtc_apply_fix (fixP, val)     fixS *fixP;     long val;{  /* should never be called */  know (0);}void				/* Knows about order of bytes in address.  */md_number_to_disp (con, value, nbytes)     char con[];		/* Return 'nbytes' of chars here.  */     long int value;		/* The value of the bits.  */     int nbytes;		/* Number of bytes in the output.  */{  md_number_to_chars (con, value, nbytes);}void				/* Knows about order of bytes in address.  */md_number_to_field (con, value, nbytes)     char con[];		/* Return 'nbytes' of chars here.  */     long int value;		/* The value of the bits.  */     int nbytes;		/* Number of bytes in the output.  */{  md_number_to_chars (con, value, nbytes);}/* 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,

⌨️ 快捷键说明

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