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

📄 tc-mn10300.c

📁 基于4个mips核的noc设计
💻 C
📖 第 1 页 / 共 4 页
字号:
/* tc-mn10300.c -- Assembler code for the Matsushita 10300   Copyright 1996, 1997, 1998, 1999, 2000, 2001   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 <stdio.h>#include <ctype.h>#include "as.h"#include "subsegs.h"#include "opcode/mn10300.h"#include "dwarf2dbg.h"/* Structure to hold information about predefined registers.  */struct reg_name{  const char *name;  int value;};/* Generic assembler global variables which must be defined by all   targets.  *//* Characters which always start a comment.  */const char comment_chars[] = "#";/* Characters which start a comment at the beginning of a line.  */const char line_comment_chars[] = ";#";/* Characters which may be used to separate multiple commands on a   single line.  */const char line_separator_chars[] = ";";/* Characters which are used to indicate an exponent in a floating   point number.  */const char EXP_CHARS[] = "eE";/* Characters which mean that a number is a floating point constant,   as in 0d1.0.  */const char FLT_CHARS[] = "dD";const relax_typeS md_relax_table[] = {  /* bCC relaxing  */  {0x7f, -0x80, 2, 1},  {0x7fff, -0x8000, 5, 2},  {0x7fffffff, -0x80000000, 7, 0},  /* bCC relaxing (uncommon cases)  */  {0x7f, -0x80, 3, 4},  {0x7fff, -0x8000, 6, 5},  {0x7fffffff, -0x80000000, 8, 0},  /* call relaxing  */  {0x7fff, -0x8000, 5, 7},  {0x7fffffff, -0x80000000, 7, 0},  /* calls relaxing  */  {0x7fff, -0x8000, 4, 9},  {0x7fffffff, -0x80000000, 6, 0},  /* jmp relaxing  */  {0x7f, -0x80, 2, 11},  {0x7fff, -0x8000, 3, 12},  {0x7fffffff, -0x80000000, 5, 0},};/* Local functions.  */static void mn10300_insert_operand PARAMS ((unsigned long *, unsigned long *,					    const struct mn10300_operand *,					    offsetT, char *, unsigned,					    unsigned));static unsigned long check_operand PARAMS ((unsigned long,					    const struct mn10300_operand *,					    offsetT));static int reg_name_search PARAMS ((const struct reg_name *, int, const char *));static boolean data_register_name PARAMS ((expressionS *expressionP));static boolean address_register_name PARAMS ((expressionS *expressionP));static boolean other_register_name PARAMS ((expressionS *expressionP));static void set_arch_mach PARAMS ((int));/*  Set linkrelax here to avoid fixups in most sections.  */int linkrelax = 1;static int current_machine;/* Fixups.  */#define MAX_INSN_FIXUPS (5)struct mn10300_fixup{  expressionS exp;  int opindex;  bfd_reloc_code_real_type reloc;};struct mn10300_fixup fixups[MAX_INSN_FIXUPS];static int fc;/* We must store the value of each register operand so that we can   verify that certain registers do not match.  */int mn10300_reg_operands[MN10300_MAX_OPERANDS];const char *md_shortopts = "";struct option md_longopts[] = {  {NULL, no_argument, NULL, 0}};size_t md_longopts_size = sizeof (md_longopts);/* The target specific pseudo-ops which we support.  */const pseudo_typeS md_pseudo_table[] ={  { "file",     dwarf2_directive_file,  0 },  { "loc",      dwarf2_directive_loc,   0 },  { "am30",	set_arch_mach,		AM30 },  { "am33",	set_arch_mach,		AM33 },  { "mn10300",	set_arch_mach,		MN103 },  {NULL, 0, 0}};#define HAVE_AM33 (current_machine == AM33)#define HAVE_AM30 (current_machine == AM30)/* Opcode hash table.  */static struct hash_control *mn10300_hash;/* This table is sorted. Suitable for searching by a binary search.  */static const struct reg_name data_registers[] ={  { "d0", 0 },  { "d1", 1 },  { "d2", 2 },  { "d3", 3 },};#define DATA_REG_NAME_CNT				\  (sizeof (data_registers) / sizeof (struct reg_name))static const struct reg_name address_registers[] ={  { "a0", 0 },  { "a1", 1 },  { "a2", 2 },  { "a3", 3 },};#define ADDRESS_REG_NAME_CNT					\  (sizeof (address_registers) / sizeof (struct reg_name))static const struct reg_name r_registers[] ={  { "a0", 8 },  { "a1", 9 },  { "a2", 10 },  { "a3", 11 },  { "d0", 12 },  { "d1", 13 },  { "d2", 14 },  { "d3", 15 },  { "e0", 0 },  { "e1", 1 },  { "e10", 10 },  { "e11", 11 },  { "e12", 12 },  { "e13", 13 },  { "e14", 14 },  { "e15", 15 },  { "e2", 2 },  { "e3", 3 },  { "e4", 4 },  { "e5", 5 },  { "e6", 6 },  { "e7", 7 },  { "e8", 8 },  { "e9", 9 },  { "r0", 0 },  { "r1", 1 },  { "r10", 10 },  { "r11", 11 },  { "r12", 12 },  { "r13", 13 },  { "r14", 14 },  { "r15", 15 },  { "r2", 2 },  { "r3", 3 },  { "r4", 4 },  { "r5", 5 },  { "r6", 6 },  { "r7", 7 },  { "r8", 8 },  { "r9", 9 },};#define R_REG_NAME_CNT					\  (sizeof (r_registers) / sizeof (struct reg_name))static const struct reg_name xr_registers[] ={  { "mcrh", 2 },  { "mcrl", 3 },  { "mcvf", 4 },  { "mdrq", 1 },  { "pc", 0 },  { "sp", 0 },  { "xr0", 0 },  { "xr1", 1 },  { "xr10", 10 },  { "xr11", 11 },  { "xr12", 12 },  { "xr13", 13 },  { "xr14", 14 },  { "xr15", 15 },  { "xr2", 2 },  { "xr3", 3 },  { "xr4", 4 },  { "xr5", 5 },  { "xr6", 6 },  { "xr7", 7 },  { "xr8", 8 },  { "xr9", 9 },};#define XR_REG_NAME_CNT					\  (sizeof (xr_registers) / sizeof (struct reg_name))static const struct reg_name other_registers[] ={  { "mdr", 0 },  { "psw", 0 },  { "sp", 0 },};#define OTHER_REG_NAME_CNT				\  (sizeof (other_registers) / sizeof (struct reg_name))/* reg_name_search does a binary search of the given register table   to see if "name" is a valid regiter name.  Returns the register   number from the array on success, or -1 on failure.  */static intreg_name_search (regs, regcount, name)     const struct reg_name *regs;     int regcount;     const char *name;{  int middle, low, high;  int cmp;  low = 0;  high = regcount - 1;  do    {      middle = (low + high) / 2;      cmp = strcasecmp (name, regs[middle].name);      if (cmp < 0)	high = middle - 1;      else if (cmp > 0)	low = middle + 1;      else	return regs[middle].value;    }  while (low <= high);  return -1;}/* Summary of register_name(). * * in: Input_line_pointer points to 1st char of operand. * * out: A expressionS. *	The operand may have been a register: in this case, X_op == O_register, *	X_add_number is set to the register number, and truth is returned. *	Input_line_pointer->(next non-blank) char after operand, or is in *	its original state. */static booleanr_register_name (expressionP)     expressionS *expressionP;{  int reg_number;  char *name;  char *start;  char c;  /* Find the spelling of the operand.  */  start = name = input_line_pointer;  c = get_symbol_end ();  reg_number = reg_name_search (r_registers, R_REG_NAME_CNT, name);  /* Look to see if it's in the register table.  */  if (reg_number >= 0)    {      expressionP->X_op = O_register;      expressionP->X_add_number = reg_number;      /* Make the rest nice.  */      expressionP->X_add_symbol = NULL;      expressionP->X_op_symbol = NULL;      /* Put back the delimiting char.  */      *input_line_pointer = c;      return true;    }  else    {      /* Reset the line as if we had not done anything.  */      /* Put back the delimiting char.  */      *input_line_pointer = c;      /* Reset input_line pointer.  */      input_line_pointer = start;      return false;    }}/* Summary of register_name(). * * in: Input_line_pointer points to 1st char of operand. * * out: A expressionS. *	The operand may have been a register: in this case, X_op == O_register, *	X_add_number is set to the register number, and truth is returned. *	Input_line_pointer->(next non-blank) char after operand, or is in *	its original state. */static booleanxr_register_name (expressionP)     expressionS *expressionP;{  int reg_number;  char *name;  char *start;  char c;  /* Find the spelling of the operand.  */  start = name = input_line_pointer;  c = get_symbol_end ();  reg_number = reg_name_search (xr_registers, XR_REG_NAME_CNT, name);  /* Look to see if it's in the register table.  */  if (reg_number >= 0)    {      expressionP->X_op = O_register;      expressionP->X_add_number = reg_number;      /* Make the rest nice.  */      expressionP->X_add_symbol = NULL;      expressionP->X_op_symbol = NULL;      /* Put back the delimiting char.  */      *input_line_pointer = c;      return true;    }  else    {      /* Reset the line as if we had not done anything.  */      /* Put back the delimiting char.  */      *input_line_pointer = c;      /* Reset input_line pointer.  */      input_line_pointer = start;      return false;    }}/* Summary of register_name(). * * in: Input_line_pointer points to 1st char of operand. * * out: A expressionS. *	The operand may have been a register: in this case, X_op == O_register, *	X_add_number is set to the register number, and truth is returned. *	Input_line_pointer->(next non-blank) char after operand, or is in *	its original state. */static booleandata_register_name (expressionP)     expressionS *expressionP;{  int reg_number;  char *name;  char *start;  char c;  /* Find the spelling of the operand.  */  start = name = input_line_pointer;  c = get_symbol_end ();  reg_number = reg_name_search (data_registers, DATA_REG_NAME_CNT, name);  /* Look to see if it's in the register table.  */  if (reg_number >= 0)    {      expressionP->X_op = O_register;      expressionP->X_add_number = reg_number;      /* Make the rest nice.  */      expressionP->X_add_symbol = NULL;      expressionP->X_op_symbol = NULL;      /* Put back the delimiting char.  */      *input_line_pointer = c;      return true;    }  else    {      /* Reset the line as if we had not done anything.  */      /* Put back the delimiting char.  */      *input_line_pointer = c;      /* Reset input_line pointer.  */      input_line_pointer = start;      return false;    }}/* Summary of register_name(). * * in: Input_line_pointer points to 1st char of operand. * * out: A expressionS. *	The operand may have been a register: in this case, X_op == O_register, *	X_add_number is set to the register number, and truth is returned. *	Input_line_pointer->(next non-blank) char after operand, or is in *	its original state. */static booleanaddress_register_name (expressionP)     expressionS *expressionP;{  int reg_number;  char *name;  char *start;  char c;  /* Find the spelling of the operand.  */  start = name = input_line_pointer;  c = get_symbol_end ();  reg_number = reg_name_search (address_registers, ADDRESS_REG_NAME_CNT, name);  /* Look to see if it's in the register table.  */  if (reg_number >= 0)    {      expressionP->X_op = O_register;      expressionP->X_add_number = reg_number;      /* Make the rest nice.  */      expressionP->X_add_symbol = NULL;      expressionP->X_op_symbol = NULL;      /* Put back the delimiting char.  */      *input_line_pointer = c;      return true;    }  else    {      /* Reset the line as if we had not done anything.  */      /* Put back the delimiting char.  */      *input_line_pointer = c;      /* Reset input_line pointer.  */      input_line_pointer = start;      return false;    }}/* Summary of register_name(). * * in: Input_line_pointer points to 1st char of operand. * * out: A expressionS. *	The operand may have been a register: in this case, X_op == O_register, *	X_add_number is set to the register number, and truth is returned. *	Input_line_pointer->(next non-blank) char after operand, or is in *	its original state. */static booleanother_register_name (expressionP)     expressionS *expressionP;{  int reg_number;  char *name;  char *start;  char c;  /* Find the spelling of the operand.  */  start = name = input_line_pointer;  c = get_symbol_end ();  reg_number = reg_name_search (other_registers, OTHER_REG_NAME_CNT, name);  /* Look to see if it's in the register table.  */  if (reg_number >= 0)    {      expressionP->X_op = O_register;      expressionP->X_add_number = reg_number;      /* Make the rest nice.  */      expressionP->X_add_symbol = NULL;      expressionP->X_op_symbol = NULL;      /* Put back the delimiting char.  */      *input_line_pointer = c;      return true;    }  else    {      /* Reset the line as if we had not done anything.  */      /* Put back the delimiting char.  */      *input_line_pointer = c;      /* Reset input_line pointer.  */      input_line_pointer = start;      return false;    }}voidmd_show_usage (stream)     FILE *stream;

⌨️ 快捷键说明

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