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

📄 tc-i960.c

📁 基于4个mips核的noc设计
💻 C
📖 第 1 页 / 共 5 页
字号:
/* tc-i960.c - All the i80960-specific stuff   Copyright 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998,   1999, 2000, 2001   Free Software Foundation, Inc.   This file is part of GAS.   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.  *//* See comment on md_parse_option for 80960-specific invocation options.  *//* There are 4 different lengths of (potentially) symbol-based displacements   in the 80960 instruction set, each of which could require address fix-ups   and (in the case of external symbols) emission of relocation directives:   32-bit (MEMB)        This is a standard length for the base assembler and requires no        special action.   13-bit (COBR)        This is a non-standard length, but the base assembler has a        hook for bit field address fixups: the fixS structure can        point to a descriptor of the field, in which case our        md_number_to_field() routine gets called to process it.        I made the hook a little cleaner by having fix_new() (in the base        assembler) return a pointer to the fixS in question.  And I made it a        little simpler by storing the field size (in this case 13) instead of        of a pointer to another structure:  80960 displacements are ALWAYS        stored in the low-order bits of a 4-byte word.        Since the target of a COBR cannot be external, no relocation        directives for this size displacement have to be generated.        But the base assembler had to be modified to issue error        messages if the symbol did turn out to be external.   24-bit (CTRL)        Fixups are handled as for the 13-bit case (except that 24 is stored        in the fixS).        The relocation directive generated is the same as that for the 32-bit        displacement, except that it's PC-relative (the 32-bit displacement        never is).   The i80960 version of the linker needs a mod to        distinguish and handle the 24-bit case.   12-bit (MEMA)        MEMA formats are always promoted to MEMB (32-bit) if the displacement        is based on a symbol, because it could be relocated at link time.        The only time we use the 12-bit format is if an absolute value of        less than 4096 is specified, in which case we need neither a fixup nor        a relocation directive.  */#include <stdio.h>#include <ctype.h>#include "as.h"#include "obstack.h"#include "opcode/i960.h"#if defined (OBJ_AOUT) || defined (OBJ_BOUT)#define TC_S_IS_SYSPROC(s)	((1<=S_GET_OTHER(s)) && (S_GET_OTHER(s)<=32))#define TC_S_IS_BALNAME(s)	(S_GET_OTHER(s) == N_BALNAME)#define TC_S_IS_CALLNAME(s)	(S_GET_OTHER(s) == N_CALLNAME)#define TC_S_IS_BADPROC(s)	((S_GET_OTHER(s) != 0) && !TC_S_IS_CALLNAME(s) && !TC_S_IS_BALNAME(s) && !TC_S_IS_SYSPROC(s))#define TC_S_SET_SYSPROC(s, p)	(S_SET_OTHER((s), (p)+1))#define TC_S_GET_SYSPROC(s)	(S_GET_OTHER(s)-1)#define TC_S_FORCE_TO_BALNAME(s)	(S_SET_OTHER((s), N_BALNAME))#define TC_S_FORCE_TO_CALLNAME(s)	(S_SET_OTHER((s), N_CALLNAME))#define TC_S_FORCE_TO_SYSPROC(s)	{;}#else /* ! OBJ_A/BOUT */#ifdef OBJ_COFF#define TC_S_IS_SYSPROC(s)	(S_GET_STORAGE_CLASS(s) == C_SCALL)#define TC_S_IS_BALNAME(s)	(SF_GET_BALNAME(s))#define TC_S_IS_CALLNAME(s)	(SF_GET_CALLNAME(s))#define TC_S_IS_BADPROC(s)	(TC_S_IS_SYSPROC(s) && TC_S_GET_SYSPROC(s) < 0 && 31 < TC_S_GET_SYSPROC(s))#define TC_S_SET_SYSPROC(s, p)	((s)->sy_symbol.ost_auxent[1].x_sc.x_stindx = (p))#define TC_S_GET_SYSPROC(s)	((s)->sy_symbol.ost_auxent[1].x_sc.x_stindx)#define TC_S_FORCE_TO_BALNAME(s)	(SF_SET_BALNAME(s))#define TC_S_FORCE_TO_CALLNAME(s)	(SF_SET_CALLNAME(s))#define TC_S_FORCE_TO_SYSPROC(s)	(S_SET_STORAGE_CLASS((s), C_SCALL))#else /* ! OBJ_COFF */#ifdef OBJ_ELF#define TC_S_IS_SYSPROC(s)	0#define TC_S_IS_BALNAME(s)	0#define TC_S_IS_CALLNAME(s)	0#define TC_S_IS_BADPROC(s)	0#define TC_S_SET_SYSPROC(s, p)#define TC_S_GET_SYSPROC(s) 0#define TC_S_FORCE_TO_BALNAME(s)#define TC_S_FORCE_TO_CALLNAME(s)#define TC_S_FORCE_TO_SYSPROC(s)#else #error COFF, a.out, b.out, and ELF are the only supported formats.#endif /* ! OBJ_ELF */#endif /* ! OBJ_COFF */#endif /* ! OBJ_A/BOUT */extern char *input_line_pointer;#if !defined (BFD_ASSEMBLER) && !defined (BFD)#ifdef OBJ_COFFconst int md_reloc_size = sizeof (struct reloc);#else /* OBJ_COFF */const int md_reloc_size = sizeof (struct relocation_info);#endif /* OBJ_COFF */#endif/* Local i80960 routines.  */static void brcnt_emit ();	/* Emit branch-prediction instrumentation code */static char *brlab_next ();	/* Return next branch local label */void brtab_emit ();		/* Emit br-predict instrumentation table */static void cobr_fmt ();	/* Generate COBR instruction */static void ctrl_fmt ();	/* Generate CTRL instruction */static char *emit ();		/* Emit (internally) binary */static int get_args ();		/* Break arguments out of comma-separated list */static void get_cdisp ();	/* Handle COBR or CTRL displacement */static char *get_ispec ();	/* Find index specification string */static int get_regnum ();	/* Translate text to register number */static int i_scan ();		/* Lexical scan of instruction source */static void mem_fmt ();		/* Generate MEMA or MEMB instruction */static void mema_to_memb ();	/* Convert MEMA instruction to MEMB format */static void parse_expr ();	/* Parse an expression */static int parse_ldconst ();	/* Parse and replace a 'ldconst' pseudo-op */static void parse_memop ();	/* Parse a memory operand */static void parse_po ();	/* Parse machine-dependent pseudo-op */static void parse_regop ();	/* Parse a register operand */static void reg_fmt ();		/* Generate a REG format instruction */void reloc_callj ();		/* Relocate a 'callj' instruction */static void relax_cobr ();	/* "De-optimize" cobr into compare/branch */static void s_leafproc ();	/* Process '.leafproc' pseudo-op */static void s_sysproc ();	/* Process '.sysproc' pseudo-op */static int shift_ok ();		/* Will a 'shlo' substiture for a 'ldconst'? */static void syntax ();		/* Give syntax error */static int targ_has_sfr ();	/* Target chip supports spec-func register? */static int targ_has_iclass ();	/* Target chip supports instruction set? *//* See md_parse_option() for meanings of these options */static char norelax;		/* True if -norelax switch seen */static char instrument_branches;	/* True if -b switch seen *//* Characters that always start a comment.   If the pre-processor is disabled, these aren't very useful. */const char comment_chars[] = "#";/* Characters that only start a comment at the beginning of   a line.  If the line seems to have the form '# 123 filename'   .line and .file directives will appear in the pre-processed output.   Note that input_file.c hand checks for '#' at the beginning of the   first line of the input file.  This is because the compiler outputs   #NO_APP at the beginning of its output. *//* Also note that comments started like this one will always work.  */const char line_comment_chars[] = "";const char line_separator_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 0f12.456 or 0d1.2345e12 */const char FLT_CHARS[] = "fFdDtT";/* Table used by base assembler to relax addresses based on varying length   instructions.  The fields are:     1) most positive reach of this state,     2) most negative reach of this state,     3) how many bytes this mode will add to the size of the current frag     4) which index into the table to try if we can't fit into this one.   For i80960, the only application is the (de-)optimization of cobr   instructions into separate compare and branch instructions when a 13-bit   displacement won't hack it. */const relax_typeS md_relax_table[] ={  {0, 0, 0, 0},			/* State 0 => no more relaxation possible */  {4088, -4096, 0, 2},		/* State 1: conditional branch (cobr) */  {0x800000 - 8, -0x800000, 4, 0},	/* State 2: compare (reg) & branch (ctrl) */};static void s_endian PARAMS ((int));/* These are the machine dependent pseudo-ops.   This table describes all the machine specific pseudo-ops the assembler   has to support.  The fields are:        pseudo-op name without dot        function to call to execute this pseudo-op        integer arg to pass to the function */#define S_LEAFPROC	1#define S_SYSPROC	2const pseudo_typeS md_pseudo_table[] ={  {"bss", s_lcomm, 1},  {"endian", s_endian, 0},  {"extended", float_cons, 't'},  {"leafproc", parse_po, S_LEAFPROC},  {"sysproc", parse_po, S_SYSPROC},  {"word", cons, 4},  {"quad", cons, 16},  {0, 0, 0}};/* Macros to extract info from an 'expressionS' structure 'e' */#define adds(e)	e.X_add_symbol#define offs(e)	e.X_add_number/* Branch-prediction bits for CTRL/COBR format opcodes */#define BP_MASK		0x00000002	/* Mask for branch-prediction bit */#define BP_TAKEN	0x00000000	/* Value to OR in to predict branch */#define BP_NOT_TAKEN	0x00000002	/* Value to OR in to predict no branch *//* Some instruction opcodes that we need explicitly */#define BE	0x12000000#define BG	0x11000000#define BGE	0x13000000#define BL	0x14000000#define BLE	0x16000000#define BNE	0x15000000#define BNO	0x10000000#define BO	0x17000000#define CHKBIT	0x5a002700#define CMPI	0x5a002080#define CMPO	0x5a002000#define B	0x08000000#define BAL	0x0b000000#define CALL	0x09000000#define CALLS	0x66003800#define RET	0x0a000000/* These masks are used to build up a set of MEMB mode bits.  */#define	A_BIT		0x0400#define	I_BIT		0x0800#define MEMB_BIT	0x1000#define	D_BIT		0x2000/* Mask for the only mode bit in a MEMA instruction (if set, abase reg is   used).  */#define MEMA_ABASE	0x2000/* Info from which a MEMA or MEMB format instruction can be generated */typedef struct  {    /* (First) 32 bits of instruction */    long opcode;    /* 0-(none), 12- or, 32-bit displacement needed */    int disp;    /* The expression in the source instruction from which the       displacement should be determined.  */    char *e;  }memS;/* The two pieces of info we need to generate a register operand */struct regop  {    int mode;			/* 0 =>local/global/spec reg; 1=> literal or fp reg */    int special;		/* 0 =>not a sfr;  1=> is a sfr (not valid w/mode=0) */    int n;			/* Register number or literal value */  };/* Number and assembler mnemonic for all registers that can appear in   operands.  */static const struct  {    char *reg_name;    int reg_num;  }regnames[] ={  { "pfp", 0 },  { "sp", 1 },  { "rip", 2 },  { "r3", 3 },  { "r4", 4 },  { "r5", 5 },  { "r6", 6 },  { "r7", 7 },  { "r8", 8 },  { "r9", 9 },  { "r10", 10 },  { "r11", 11 },  { "r12", 12 },  { "r13", 13 },  { "r14", 14 },  { "r15", 15 },  { "g0", 16 },  { "g1", 17 },  { "g2", 18 },  { "g3", 19 },  { "g4", 20 },  { "g5", 21 },  { "g6", 22 },  { "g7", 23 },  { "g8", 24 },  { "g9", 25 },  { "g10", 26 },  { "g11", 27 },  { "g12", 28 },  { "g13", 29 },  { "g14", 30 },  { "fp", 31 },  /* Numbers for special-function registers are for assembler internal     use only: they are scaled back to range [0-31] for binary output.  */#define SF0	32  { "sf0", 32 },  { "sf1", 33 },  { "sf2", 34 },  { "sf3", 35 },  { "sf4", 36 },  { "sf5", 37 },  { "sf6", 38 },  { "sf7", 39 },  { "sf8", 40 },  { "sf9", 41 },  { "sf10", 42 },  { "sf11", 43 },  { "sf12", 44 },  { "sf13", 45 },  { "sf14", 46 },  { "sf15", 47 },  { "sf16", 48 },  { "sf17", 49 },  { "sf18", 50 },  { "sf19", 51 },  { "sf20", 52 },  { "sf21", 53 },  { "sf22", 54 },  { "sf23", 55 },  { "sf24", 56 },  { "sf25", 57 },  { "sf26", 58 },  { "sf27", 59 },  { "sf28", 60 },  { "sf29", 61 },  { "sf30", 62 },  { "sf31", 63 },  /* Numbers for floating point registers are for assembler internal     use only: they are scaled back to [0-3] for binary output.  */#define FP0	64  { "fp0", 64 },  { "fp1", 65 },  { "fp2", 66 },  { "fp3", 67 },  { NULL, 0 },				/* END OF LIST */};#define	IS_RG_REG(n)	((0 <= (n)) && ((n) < SF0))#define	IS_SF_REG(n)	((SF0 <= (n)) && ((n) < FP0))#define	IS_FP_REG(n)	((n) >= FP0)/* Number and assembler mnemonic for all registers that can appear as   'abase' (indirect addressing) registers.  */static const struct  {    char *areg_name;    int areg_num;  }aregs[] ={  { "(pfp)", 0 },  { "(sp)", 1 },  { "(rip)", 2 },  { "(r3)", 3 },  { "(r4)", 4 },  { "(r5)", 5 },  { "(r6)", 6 },  { "(r7)", 7 },  { "(r8)", 8 },  { "(r9)", 9 },  { "(r10)", 10 },  { "(r11)", 11 },  { "(r12)", 12 },  { "(r13)", 13 },  { "(r14)", 14 },  { "(r15)", 15 },  { "(g0)", 16 },  { "(g1)", 17 },  { "(g2)", 18 },  { "(g3)", 19 },  { "(g4)", 20 },  { "(g5)", 21 },  { "(g6)", 22 },  { "(g7)", 23 },  { "(g8)", 24 },  { "(g9)", 25 },  { "(g10)", 26 },  { "(g11)", 27 },  { "(g12)", 28 },  { "(g13)", 29 },  { "(g14)", 30 },  { "(fp)", 31 },#define IPREL	32  /* For assembler internal use only: this number never appears in binary     output.  */  { "(ip)", IPREL },  { NULL, 0 },				/* END OF LIST */};/* Hash tables */static struct hash_control *op_hash;	/* Opcode mnemonics */static struct hash_control *reg_hash;	/* Register name hash table */static struct hash_control *areg_hash;	/* Abase register hash table *//* Architecture for which we are assembling */#define ARCH_ANY	0	/* Default: no architecture checking done */#define ARCH_KA		1#define ARCH_KB		2#define ARCH_MC		3#define ARCH_CA		4#define ARCH_JX		5#define ARCH_HX		6int architecture = ARCH_ANY;	/* Architecture requested on invocation line */int iclasses_seen;		/* OR of instruction classes (I_* constants)				 *    for which we've actually assembled				 *      instructions.				 *//* BRANCH-PREDICTION INSTRUMENTATION

⌨️ 快捷键说明

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