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

📄 tc-mn10200.c

📁 基于4个mips核的noc设计
💻 C
📖 第 1 页 / 共 3 页
字号:
/* tc-mn10200.c -- Assembler code for the Matsushita 10200   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/mn10200.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  */  {0x81, -0x7e, 2, 1},  {0x8004, -0x7ffb, 5, 2},  {0x800006, -0x7ffff9, 7, 0},  /* bCCx relaxing  */  {0x81, -0x7e, 3, 4},  {0x8004, -0x7ffb, 6, 5},  {0x800006, -0x7ffff9, 8, 0},  /* jsr relaxing  */  {0x8004, -0x7ffb, 3, 7},  {0x800006, -0x7ffff9, 5, 0},  /* jmp relaxing  */  {0x81, -0x7e, 2, 9},  {0x8004, -0x7ffb, 3, 10},  {0x800006, -0x7ffff9, 5, 0},};/* Local functions.  */static void mn10200_insert_operand PARAMS ((unsigned long *, unsigned long *,					    const struct mn10200_operand *,					    offsetT, char *, unsigned,					    unsigned));static unsigned long check_operand PARAMS ((unsigned long,					    const struct mn10200_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));/* Fixups.  */#define MAX_INSN_FIXUPS (5)struct mn10200_fixup{  expressionS exp;  int opindex;  bfd_reloc_code_real_type reloc;};struct mn10200_fixup fixups[MAX_INSN_FIXUPS];static int fc;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[] ={  { NULL,       NULL,           0 }};/* Opcode hash table.  */static struct hash_control *mn10200_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 other_registers[] ={  { "mdr", 0 },  { "psw", 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 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;{  fprintf (stream, _("MN10200 options:\n\none yet\n"));}intmd_parse_option (c, arg)     int c;     char *arg;{  return 0;}symbolS *md_undefined_symbol (name)     char *name;{  return 0;}char *md_atof (type, litp, sizep)     int type;     char *litp;     int *sizep;{  int prec;  LITTLENUM_TYPE words[4];  char *t;  int i;  switch (type)    {    case 'f':      prec = 2;      break;    case 'd':      prec = 4;      break;    default:      *sizep = 0;      return _("bad call to md_atof");    }  t = atof_ieee (input_line_pointer, type, words);  if (t)    input_line_pointer = t;  *sizep = prec * 2;  for (i = prec - 1; i >= 0; i--)    {      md_number_to_chars (litp, (valueT) words[i], 2);      litp += 2;    }  return NULL;}voidmd_convert_frag (abfd, sec, fragP)     bfd *abfd;     asection *sec;     fragS *fragP;{  static unsigned long label_count = 0;  char buf[40];  subseg_change (sec, 0);  if (fragP->fr_subtype == 0)    {      fix_new (fragP, fragP->fr_fix + 1, 1, fragP->fr_symbol,	       fragP->fr_offset, 1, BFD_RELOC_8_PCREL);      fragP->fr_var = 0;      fragP->fr_fix += 2;    }  else if (fragP->fr_subtype == 1)    {      /* Reverse the condition of the first branch.  */      int offset = fragP->fr_fix;      int opcode = fragP->fr_literal[offset] & 0xff;      switch (opcode)	{	case 0xe8:	  opcode = 0xe9;	  break;	case 0xe9:	  opcode = 0xe8;	  break;	case 0xe0:	  opcode = 0xe2;	  break;	case 0xe2:	  opcode = 0xe0;	  break;	case 0xe3:	  opcode = 0xe1;	  break;	case 0xe1:	  opcode = 0xe3;	  break;	case 0xe4:	  opcode = 0xe6;	  break;	case 0xe6:	  opcode = 0xe4;	  break;	case 0xe7:	  opcode = 0xe5;	  break;	case 0xe5:	  opcode = 0xe7;	  break;	default:	  abort ();	}      fragP->fr_literal[offset] = opcode;      /* Create a fixup for the reversed conditional branch.  */      sprintf (buf, ".%s_%d", FAKE_LABEL_NAME, label_count++);      fix_new (fragP, fragP->fr_fix + 1, 1,	       symbol_new (buf, sec, 0, fragP->fr_next),	       fragP->fr_offset, 1, BFD_RELOC_8_PCREL);      /* Now create the unconditional branch + fixup to the	 final target.  */      fragP->fr_literal[offset + 2] = 0xfc;      fix_new (fragP, fragP->fr_fix + 3, 2, fragP->fr_symbol,	       fragP->fr_offset, 1, BFD_RELOC_16_PCREL);      fragP->fr_var = 0;      fragP->fr_fix += 5;    }  else if (fragP->fr_subtype == 2)    {      /* Reverse the condition of the first branch.  */      int offset = fragP->fr_fix;      int opcode = fragP->fr_literal[offset] & 0xff;      switch (opcode)	{

⌨️ 快捷键说明

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