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

📄 tc-v850.c

📁 基于4个mips核的noc设计
💻 C
📖 第 1 页 / 共 4 页
字号:
/* tc-v850.c -- Assembler code for the NEC V850   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/v850.h"#include "dwarf2dbg.h"#define AREA_ZDA 0#define AREA_SDA 1#define AREA_TDA 2/* Sign-extend a 16-bit number.  */#define SEXT16(x)	((((x) & 0xffff) ^ (~0x7fff)) + 0x8000)/* Temporarily holds the reloc in a cons expression.  */static bfd_reloc_code_real_type hold_cons_reloc = BFD_RELOC_UNUSED;/* Set to TRUE if we want to be pedantic about signed overflows.  */static boolean warn_signed_overflows   = FALSE;static boolean warn_unsigned_overflows = FALSE;/* Indicates the target BFD machine number.  */static int machine = -1;/* Indicates the target processor(s) for the assemble.  */static int processor_mask = -1;/* 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[] = {  /* Conditional branches.  */  {0xff,     -0x100,    2, 1},  {0x1fffff, -0x200000, 6, 0},  /* Unconditional branches.  */  {0xff,     -0x100,    2, 3},  {0x1fffff, -0x200000, 4, 0},};static segT sdata_section = NULL;static segT tdata_section = NULL;static segT zdata_section = NULL;static segT sbss_section = NULL;static segT tbss_section = NULL;static segT zbss_section = NULL;static segT rosdata_section = NULL;static segT rozdata_section = NULL;static segT scommon_section = NULL;static segT tcommon_section = NULL;static segT zcommon_section = NULL;static segT call_table_data_section = NULL;static segT call_table_text_section = NULL;/* Fixups.  */#define MAX_INSN_FIXUPS (5)struct v850_fixup {  expressionS exp;  int opindex;  bfd_reloc_code_real_type reloc;};struct v850_fixup fixups[MAX_INSN_FIXUPS];static int fc;voidv850_sdata (int ignore ATTRIBUTE_UNUSED){  obj_elf_section_change_hook ();  subseg_set (sdata_section, (subsegT) get_absolute_expression ());  demand_empty_rest_of_line ();}voidv850_tdata (int ignore ATTRIBUTE_UNUSED){  obj_elf_section_change_hook ();  subseg_set (tdata_section, (subsegT) get_absolute_expression ());  demand_empty_rest_of_line ();}voidv850_zdata (int ignore ATTRIBUTE_UNUSED){  obj_elf_section_change_hook ();  subseg_set (zdata_section, (subsegT) get_absolute_expression ());  demand_empty_rest_of_line ();}voidv850_sbss (int ignore ATTRIBUTE_UNUSED){  obj_elf_section_change_hook ();  subseg_set (sbss_section, (subsegT) get_absolute_expression ());  demand_empty_rest_of_line ();}voidv850_tbss (int ignore ATTRIBUTE_UNUSED){  obj_elf_section_change_hook ();  subseg_set (tbss_section, (subsegT) get_absolute_expression ());  demand_empty_rest_of_line ();}voidv850_zbss (int ignore ATTRIBUTE_UNUSED){  obj_elf_section_change_hook ();  subseg_set (zbss_section, (subsegT) get_absolute_expression ());  demand_empty_rest_of_line ();}voidv850_rosdata (int ignore ATTRIBUTE_UNUSED){  obj_elf_section_change_hook ();  subseg_set (rosdata_section, (subsegT) get_absolute_expression ());  demand_empty_rest_of_line ();}voidv850_rozdata (int ignore ATTRIBUTE_UNUSED){  obj_elf_section_change_hook ();  subseg_set (rozdata_section, (subsegT) get_absolute_expression ());  demand_empty_rest_of_line ();}voidv850_call_table_data (int ignore ATTRIBUTE_UNUSED){  obj_elf_section_change_hook ();  subseg_set (call_table_data_section, (subsegT) get_absolute_expression ());  demand_empty_rest_of_line ();}voidv850_call_table_text (int ignore ATTRIBUTE_UNUSED){  obj_elf_section_change_hook ();  subseg_set (call_table_text_section, (subsegT) get_absolute_expression ());  demand_empty_rest_of_line ();}voidv850_bss (int ignore ATTRIBUTE_UNUSED){  register int temp = get_absolute_expression ();  obj_elf_section_change_hook ();  subseg_set (bss_section, (subsegT) temp);  demand_empty_rest_of_line ();}voidv850_offset (int ignore ATTRIBUTE_UNUSED){  int temp = get_absolute_expression ();  temp -= frag_now_fix ();  if (temp > 0)    (void) frag_more (temp);  demand_empty_rest_of_line ();}/* Copied from obj_elf_common() in gas/config/obj-elf.c.  */static voidv850_comm (area)     int area;{  char *name;  char c;  char *p;  int temp;  unsigned int size;  symbolS *symbolP;  int have_align;  name = input_line_pointer;  c = get_symbol_end ();  /* Just after name is now '\0'.  */  p = input_line_pointer;  *p = c;  SKIP_WHITESPACE ();  if (*input_line_pointer != ',')    {      as_bad (_("Expected comma after symbol-name"));      ignore_rest_of_line ();      return;    }  /* Skip ','.  */  input_line_pointer++;  if ((temp = get_absolute_expression ()) < 0)    {      /* xgettext:c-format  */      as_bad (_(".COMMon length (%d.) < 0! Ignored."), temp);      ignore_rest_of_line ();      return;    }  size = temp;  *p = 0;  symbolP = symbol_find_or_make (name);  *p = c;  if (S_IS_DEFINED (symbolP) && ! S_IS_COMMON (symbolP))    {      as_bad (_("Ignoring attempt to re-define symbol"));      ignore_rest_of_line ();      return;    }  if (S_GET_VALUE (symbolP) != 0)    {      if (S_GET_VALUE (symbolP) != size)	{	  /* xgettext:c-format  */	  as_warn (_("Length of .comm \"%s\" is already %ld. Not changed to %d."),		   S_GET_NAME (symbolP), (long) S_GET_VALUE (symbolP), size);	}    }  know (symbol_get_frag (symbolP) == &zero_address_frag);  if (*input_line_pointer != ',')    have_align = 0;  else    {      have_align = 1;      input_line_pointer++;      SKIP_WHITESPACE ();    }  if (! have_align || *input_line_pointer != '"')    {      if (! have_align)	temp = 0;      else	{	  temp = get_absolute_expression ();	  if (temp < 0)	    {	      temp = 0;	      as_warn (_("Common alignment negative; 0 assumed"));	    }	}      if (symbol_get_obj (symbolP)->local)	{	  segT old_sec;	  int old_subsec;	  char *pfrag;	  int align;	  flagword applicable;	  old_sec = now_seg;	  old_subsec = now_subseg;	  applicable = bfd_applicable_section_flags (stdoutput);	  applicable &= SEC_ALLOC;	  switch (area)	    {	    case AREA_SDA:	      if (sbss_section == NULL)		{		  sbss_section = subseg_new (".sbss", 0);		  bfd_set_section_flags (stdoutput, sbss_section, applicable);		  seg_info (sbss_section)->bss = 1;		}	      break;	    case AREA_ZDA:	      if (zbss_section == NULL)		{		  zbss_section = subseg_new (".zbss", 0);		  bfd_set_section_flags (stdoutput, sbss_section, applicable);		  seg_info (zbss_section)->bss = 1;		}	      break;	    case AREA_TDA:	      if (tbss_section == NULL)		{		  tbss_section = subseg_new (".tbss", 0);		  bfd_set_section_flags (stdoutput, tbss_section, applicable);		  seg_info (tbss_section)->bss = 1;		}	      break;	    }	  if (temp)	    {	      /* Convert to a power of 2 alignment.  */	      for (align = 0; (temp & 1) == 0; temp >>= 1, ++align)		;	      if (temp != 1)		{		  as_bad (_("Common alignment not a power of 2"));		  ignore_rest_of_line ();		  return;		}	    }	  else	    align = 0;	  switch (area)	    {	    case AREA_SDA:	      record_alignment (sbss_section, align);	      obj_elf_section_change_hook ();	      subseg_set (sbss_section, 0);	      break;	    case AREA_ZDA:	      record_alignment (zbss_section, align);	      obj_elf_section_change_hook ();	      subseg_set (zbss_section, 0);	      break;	    case AREA_TDA:	      record_alignment (tbss_section, align);	      obj_elf_section_change_hook ();	      subseg_set (tbss_section, 0);	      break;	    default:	      abort ();	    }	  if (align)	    frag_align (align, 0, 0);	  switch (area)	    {	    case AREA_SDA:	      if (S_GET_SEGMENT (symbolP) == sbss_section)		symbol_get_frag (symbolP)->fr_symbol = 0;	      break;	    case AREA_ZDA:	      if (S_GET_SEGMENT (symbolP) == zbss_section)		symbol_get_frag (symbolP)->fr_symbol = 0;	      break;	    case AREA_TDA:	      if (S_GET_SEGMENT (symbolP) == tbss_section)		symbol_get_frag (symbolP)->fr_symbol = 0;	      break;	    default:	      abort ();	    }	  symbol_set_frag (symbolP, frag_now);	  pfrag = frag_var (rs_org, 1, 1, (relax_substateT) 0, symbolP,			    (offsetT) size, (char *) 0);	  *pfrag = 0;	  S_SET_SIZE (symbolP, size);	  switch (area)	    {	    case AREA_SDA:	      S_SET_SEGMENT (symbolP, sbss_section);	      break;	    case AREA_ZDA:	      S_SET_SEGMENT (symbolP, zbss_section);	      break;	    case AREA_TDA:	      S_SET_SEGMENT (symbolP, tbss_section);	      break;	    default:	      abort ();	    }	  S_CLEAR_EXTERNAL (symbolP);	  obj_elf_section_change_hook ();	  subseg_set (old_sec, old_subsec);	}      else	{	allocate_common:	  S_SET_VALUE (symbolP, (valueT) size);	  S_SET_ALIGN (symbolP, temp);	  S_SET_EXTERNAL (symbolP);	  switch (area)	    {	    case AREA_SDA:	      if (scommon_section == NULL)		{		  flagword applicable =		    bfd_applicable_section_flags (stdoutput);		  scommon_section = subseg_new (".scommon", 0);		  bfd_set_section_flags (stdoutput, scommon_section,					 (applicable		     & (SEC_ALLOC | SEC_LOAD | SEC_RELOC | SEC_DATA			| SEC_HAS_CONTENTS)) | SEC_IS_COMMON);		}	      S_SET_SEGMENT (symbolP, scommon_section);	      break;	    case AREA_ZDA:	      if (zcommon_section == NULL)		{		  flagword applicable =		    bfd_applicable_section_flags (stdoutput);		  zcommon_section = subseg_new (".zcommon", 0);		  bfd_set_section_flags (stdoutput, zcommon_section,					 (applicable		     & (SEC_ALLOC | SEC_LOAD | SEC_RELOC | SEC_DATA			| SEC_HAS_CONTENTS)) | SEC_IS_COMMON);		}	      S_SET_SEGMENT (symbolP, zcommon_section);	      break;	    case AREA_TDA:	      if (tcommon_section == NULL)		{		  flagword applicable =		    bfd_applicable_section_flags (stdoutput);		  tcommon_section = subseg_new (".tcommon", 0);		  bfd_set_section_flags (stdoutput, tcommon_section,					 ((applicable					   & (SEC_ALLOC | SEC_LOAD					      | SEC_RELOC | SEC_DATA					      | SEC_HAS_CONTENTS))					  | SEC_IS_COMMON));		}	      S_SET_SEGMENT (symbolP, tcommon_section);	      break;	    default:	      abort ();	    }	}    }  else    {      input_line_pointer++;      /* @@ Some use the dot, some don't.  Can we get some consistency??  */      if (*input_line_pointer == '.')	input_line_pointer++;      /* @@ Some say data, some say bss.  */      if (strncmp (input_line_pointer, "bss\"", 4)	  && strncmp (input_line_pointer, "data\"", 5))	{	  while (*--input_line_pointer != '"')	    ;	  input_line_pointer--;	  goto bad_common_segment;	}      while (*input_line_pointer++ != '"')	;      goto allocate_common;    }  symbol_get_bfdsym (symbolP)->flags |= BSF_OBJECT;  demand_empty_rest_of_line ();  return;  {  bad_common_segment:    p = input_line_pointer;    while (*p && *p != '\n')      p++;    c = *p;    *p = '\0';    as_bad (_("bad .common segment %s"), input_line_pointer + 1);    *p = c;    input_line_pointer = p;    ignore_rest_of_line ();    return;  }}voidset_machine (int number){  machine = number;  bfd_set_arch_mach (stdoutput, TARGET_ARCH, machine);  switch (machine)    {    case 0:               processor_mask = PROCESSOR_V850;   break;    case bfd_mach_v850e:  processor_mask = PROCESSOR_V850E;  break;    case bfd_mach_v850ea: processor_mask = PROCESSOR_V850EA; break;    }}/* The target specific pseudo-ops which we support.  */const pseudo_typeS md_pseudo_table[] = {  {"sdata",   v850_sdata,   0},  {"tdata",   v850_tdata,   0},  {"zdata",   v850_zdata,   0},  {"sbss",    v850_sbss,    0},  {"tbss",    v850_tbss,    0},  {"zbss",    v850_zbss,    0},  {"rosdata", v850_rosdata, 0},  {"rozdata", v850_rozdata, 0},  {"bss",     v850_bss,     0},  {"offset",  v850_offset,  0},  {"word",    cons,         4},  {"zcomm",   v850_comm,    AREA_ZDA},  {"scomm",   v850_comm,    AREA_SDA},  {"tcomm",   v850_comm,    AREA_TDA},  {"v850",    set_machine,  0},  {"call_table_data", v850_call_table_data, 0},  {"call_table_text", v850_call_table_text, 0},  {"v850e",           set_machine,          bfd_mach_v850e},  {"v850ea",          set_machine,          bfd_mach_v850ea},  {"file",    dwarf2_directive_file, 0},  {"loc",     dwarf2_directive_loc, 0},  { NULL,     NULL,         0}};/* Opcode hash table.  */static struct hash_control *v850_hash;/* This table is sorted.  Suitable for searching by a binary search.  */static const struct reg_name pre_defined_registers[] = {  { "ep",  30 },		/* ep - element ptr */  { "gp",   4 },		/* gp - global ptr  */  { "hp",   2 },		/* hp - handler stack ptr  */  { "lp",  31 },		/* lp - link ptr  */  { "r0",   0 },  { "r1",   1 },  { "r10", 10 },  { "r11", 11 },  { "r12", 12 },  { "r13", 13 },  { "r14", 14 },  { "r15", 15 },  { "r16", 16 },  { "r17", 17 },  { "r18", 18 },

⌨️ 快捷键说明

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