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

📄 tc-avr.c

📁 基于4个mips核的noc设计
💻 C
📖 第 1 页 / 共 3 页
字号:
/* tc-avr.c -- Assembler code for the ATMEL AVR   Copyright 1999, 2000 Free Software Foundation, Inc.   Contributed by Denis Chertykov <denisc@overta.ru>   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"struct avr_opcodes_s{  char *name;  char *constraints;  int insn_size;		/* In words.  */  int isa;  unsigned int bin_opcode;};#define AVR_INSN(NAME, CONSTR, OPCODE, SIZE, ISA, BIN) \{#NAME, CONSTR, SIZE, ISA, BIN},struct avr_opcodes_s avr_opcodes[] ={  #include "opcode/avr.h"  {NULL, NULL, 0, 0, 0}};const char comment_chars[] = ";";const char line_comment_chars[] = "#";const char line_separator_chars[] = "$";const char *md_shortopts = "m:";struct mcu_type_s{  char *name;  int isa;  int mach;};static struct mcu_type_s mcu_types[] ={  {"avr1",      AVR_ISA_TINY1,    bfd_mach_avr1},  {"avr2",      AVR_ISA_2xxx,     bfd_mach_avr2},  {"avr3",      AVR_ISA_M103,     bfd_mach_avr3},  {"avr4",      AVR_ISA_M83,      bfd_mach_avr4},  {"avr5",      AVR_ISA_ALL,      bfd_mach_avr5},  {"at90s1200", AVR_ISA_1200,     bfd_mach_avr1},  {"attiny10",  AVR_ISA_TINY1,    bfd_mach_avr1},  {"attiny11",  AVR_ISA_TINY1,    bfd_mach_avr1},  {"attiny12",  AVR_ISA_TINY1,    bfd_mach_avr1},  {"attiny15",  AVR_ISA_TINY1,    bfd_mach_avr1},  {"attiny28",  AVR_ISA_TINY1,    bfd_mach_avr1},  {"at90s2313", AVR_ISA_2xxx,     bfd_mach_avr2},  {"at90s2323", AVR_ISA_2xxx,     bfd_mach_avr2},  {"at90s2333", AVR_ISA_2xxx,     bfd_mach_avr2},  {"attiny22" , AVR_ISA_2xxx,     bfd_mach_avr2},  {"at90s2343", AVR_ISA_2xxx,     bfd_mach_avr2},  {"at90s4433", AVR_ISA_2xxx,     bfd_mach_avr2},  {"at90s4414", AVR_ISA_2xxx,     bfd_mach_avr2},  {"at90s4434", AVR_ISA_2xxx,     bfd_mach_avr2},  {"at90s8515", AVR_ISA_2xxx,     bfd_mach_avr2},  {"at90s8535", AVR_ISA_2xxx,     bfd_mach_avr2},  {"at90c8534", AVR_ISA_2xxx,     bfd_mach_avr2},  {"atmega603", AVR_ISA_M603,     bfd_mach_avr3},  {"atmega103", AVR_ISA_M103,     bfd_mach_avr3},  {"atmega83",  AVR_ISA_M83,      bfd_mach_avr4},  {"atmega85",  AVR_ISA_M83,      bfd_mach_avr4},  {"atmega161", AVR_ISA_M161,     bfd_mach_avr5},  {"atmega163", AVR_ISA_M161,     bfd_mach_avr5},  {"atmega32",  AVR_ISA_M161,     bfd_mach_avr5},  {"at94k",     AVR_ISA_94K,      bfd_mach_avr5},  {NULL, 0, 0}};/* Current MCU type.  */static struct mcu_type_s default_mcu = {"avr2", AVR_ISA_2xxx,bfd_mach_avr2};static struct mcu_type_s *avr_mcu = &default_mcu;/* AVR target-specific switches.  */struct avr_opt_s{  int all_opcodes;  /* -mall-opcodes: accept all known AVR opcodes  */  int no_skip_bug;  /* -mno-skip-bug: no warnings for skipping 2-word insns  */  int no_wrap;      /* -mno-wrap: reject rjmp/rcall with 8K wrap-around  */};static struct avr_opt_s avr_opt = { 0, 0, 0 };const char EXP_CHARS[] = "eE";const char FLT_CHARS[] = "dD";static void avr_set_arch (int dummy);/* The target specific pseudo-ops which we support.  */const pseudo_typeS md_pseudo_table[] ={  {"arch", avr_set_arch,	0},  { NULL,	NULL,		0}};#define LDI_IMMEDIATE(x) (((x) & 0xf) | (((x) << 4) & 0xf00))static void show_mcu_list PARAMS ((FILE *));static char *skip_space PARAMS ((char *));static char *extract_word PARAMS ((char *, char *, int));static unsigned int avr_operand PARAMS ((struct avr_opcodes_s *,					 int, char *, char **));static unsigned int avr_operands PARAMS ((struct avr_opcodes_s *, char **));static unsigned int avr_get_constant PARAMS ((char *, int));static char *parse_exp PARAMS ((char *, expressionS *));static bfd_reloc_code_real_type avr_ldi_expression PARAMS ((expressionS *));#define EXP_MOD_NAME(i) exp_mod[i].name#define EXP_MOD_RELOC(i) exp_mod[i].reloc#define EXP_MOD_NEG_RELOC(i) exp_mod[i].neg_reloc#define HAVE_PM_P(i) exp_mod[i].have_pmstruct exp_mod_s{  char *name;  bfd_reloc_code_real_type reloc;  bfd_reloc_code_real_type neg_reloc;  int have_pm;};static struct exp_mod_s exp_mod[] ={  {"hh8",    BFD_RELOC_AVR_HH8_LDI,    BFD_RELOC_AVR_HH8_LDI_NEG,    1},  {"pm_hh8", BFD_RELOC_AVR_HH8_LDI_PM, BFD_RELOC_AVR_HH8_LDI_PM_NEG, 0},  {"hi8",    BFD_RELOC_AVR_HI8_LDI,    BFD_RELOC_AVR_HI8_LDI_NEG,    1},  {"pm_hi8", BFD_RELOC_AVR_HI8_LDI_PM, BFD_RELOC_AVR_HI8_LDI_PM_NEG, 0},  {"lo8",    BFD_RELOC_AVR_LO8_LDI,    BFD_RELOC_AVR_LO8_LDI_NEG,    1},  {"pm_lo8", BFD_RELOC_AVR_LO8_LDI_PM, BFD_RELOC_AVR_LO8_LDI_PM_NEG, 0},  {"hlo8",   -BFD_RELOC_AVR_LO8_LDI,   -BFD_RELOC_AVR_LO8_LDI_NEG,   0},  {"hhi8",   -BFD_RELOC_AVR_HI8_LDI,   -BFD_RELOC_AVR_HI8_LDI_NEG,   0},};/* Opcode hash table.  */static struct hash_control *avr_hash;/* Reloc modifiers hash control (hh8,hi8,lo8,pm_xx).  */static struct hash_control *avr_mod_hash;#define OPTION_MMCU 'm'#define OPTION_ALL_OPCODES (OPTION_MD_BASE + 1)#define OPTION_NO_SKIP_BUG (OPTION_MD_BASE + 2)#define OPTION_NO_WRAP     (OPTION_MD_BASE + 3)struct option md_longopts[] ={  { "mmcu",   required_argument, NULL, OPTION_MMCU        },  { "mall-opcodes", no_argument, NULL, OPTION_ALL_OPCODES },  { "mno-skip-bug", no_argument, NULL, OPTION_NO_SKIP_BUG },  { "mno-wrap",     no_argument, NULL, OPTION_NO_WRAP     },  { NULL, no_argument, NULL, 0 }};size_t md_longopts_size = sizeof (md_longopts);/* Display nicely formatted list of known MCU names.  */static voidshow_mcu_list (stream)     FILE *stream;{  int i, x;  fprintf (stream, _("Known MCU names:"));  x = 1000;  for (i = 0; mcu_types[i].name; i++)    {      int len = strlen (mcu_types[i].name);      x += len + 1;      if (x < 75)	fprintf (stream, " %s", mcu_types[i].name);      else	{	  fprintf (stream, "\n  %s", mcu_types[i].name);	  x = len + 2;	}    }  fprintf (stream, "\n");}static inline char *skip_space (s)     char *s;{  while (*s == ' ' || *s == '\t')    ++s;  return s;}/* Extract one word from FROM and copy it to TO.  */static char *extract_word (char *from, char *to, int limit){  char *op_start;  char *op_end;  int size = 0;  /* Drop leading whitespace.  */  from = skip_space (from);  *to = 0;  /* Find the op code end.  */  for (op_start = op_end = from; *op_end != 0 && is_part_of_name (*op_end);)    {      to[size++] = *op_end++;      if (size + 1 >= limit)	break;    }  to[size] = 0;  return op_end;}intmd_estimate_size_before_relax (fragp, seg)     fragS *fragp ATTRIBUTE_UNUSED;     asection *seg ATTRIBUTE_UNUSED;{  abort ();  return 0;}voidmd_show_usage (stream)     FILE *stream;{  fprintf (stream,      _("AVR options:\n"	"  -mmcu=[avr-name] select microcontroller variant\n"	"                   [avr-name] can be:\n"	"                   avr1 - AT90S1200, ATtiny1x, ATtiny28\n"	"                   avr2 - AT90S2xxx, AT90S4xxx, AT90S8xxx, ATtiny22\n"	"                   avr3 - ATmega103, ATmega603\n"	"                   avr4 - ATmega83, ATmega85\n"	"                   avr5 - ATmega161, ATmega163, ATmega32, AT94K\n"	"                   or immediate microcontroller name.\n"));  fprintf (stream,      _("  -mall-opcodes    accept all AVR opcodes, even if not supported by MCU\n"	"  -mno-skip-bug    disable warnings for skipping two-word instructions\n"	"                   (default for avr4, avr5)\n"	"  -mno-wrap        reject rjmp/rcall instructions with 8K wrap-around\n"	"                   (default for avr3, avr5)\n"));  show_mcu_list (stream);}static voidavr_set_arch (dummy)     int dummy ATTRIBUTE_UNUSED;{  char *str;  str = (char *) alloca (20);  input_line_pointer = extract_word (input_line_pointer, str, 20);  md_parse_option (OPTION_MMCU, str);  bfd_set_arch_mach (stdoutput, TARGET_ARCH, avr_mcu->mach);}intmd_parse_option (c, arg)     int c;     char *arg;{  switch (c)    {    case OPTION_MMCU:      {	int i;	char *s = alloca (strlen (arg) + 1);	{	  char *t = s;	  char *arg1 = arg;	  do	    *t = tolower (*arg1++);	  while (*t++);	}	for (i = 0; mcu_types[i].name; ++i)	  if (strcmp (mcu_types[i].name, s) == 0)	    break;	if (!mcu_types[i].name)	  {	    show_mcu_list (stderr);	    as_fatal (_("unknown MCU: %s\n"), arg);	  }	/* It is OK to redefine mcu type within the same avr[1-5] bfd machine	   type - this for allows passing -mmcu=... via gcc ASM_SPEC as well	   as .arch ... in the asm output at the same time.  */	if (avr_mcu == &default_mcu || avr_mcu->mach == mcu_types[i].mach)	  avr_mcu = &mcu_types[i];	else	  as_fatal (_("redefinition of mcu type `%s' to `%s'"),		    avr_mcu->name, mcu_types[i].name);	return 1;      }    case OPTION_ALL_OPCODES:      avr_opt.all_opcodes = 1;      return 1;    case OPTION_NO_SKIP_BUG:      avr_opt.no_skip_bug = 1;      return 1;    case OPTION_NO_WRAP:      avr_opt.no_wrap = 1;      return 1;    }  return 0;}symbolS *md_undefined_symbol (name)     char *name ATTRIBUTE_UNUSED;{  return 0;}/* Turn a string in input_line_pointer into a floating point constant   of type TYPE, and store the appropriate bytes in *LITP.  The number   of LITTLENUMS emitted is stored in *SIZEP.  An error message is   returned, or NULL on OK.  */char *md_atof (type, litP, sizeP)     int type;     char *litP;     int *sizeP;{  int prec;  LITTLENUM_TYPE words[4];  LITTLENUM_TYPE *wordP;  char *t;  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 * sizeof (LITTLENUM_TYPE);  /* This loop outputs the LITTLENUMs in REVERSE order.  */  for (wordP = words + prec - 1; prec--;)    {      md_number_to_chars (litP, (valueT) (*wordP--), sizeof (LITTLENUM_TYPE));      litP += sizeof (LITTLENUM_TYPE);    }  return NULL;}voidmd_convert_frag (abfd, sec, fragP)     bfd *abfd ATTRIBUTE_UNUSED;     asection *sec ATTRIBUTE_UNUSED;     fragS *fragP ATTRIBUTE_UNUSED;{  abort ();}voidmd_begin (){  unsigned int i;  struct avr_opcodes_s *opcode;  avr_hash = hash_new ();  /* Insert unique names into hash table.  This hash table then provides a     quick index to the first opcode with a particular name in the opcode     table.  */  for (opcode = avr_opcodes; opcode->name; opcode++)    hash_insert (avr_hash, opcode->name, (char *) opcode);  avr_mod_hash = hash_new ();  for (i = 0; i < sizeof (exp_mod) / sizeof (exp_mod[0]); ++i)    hash_insert (avr_mod_hash, EXP_MOD_NAME (i), (void *) (i + 10));  bfd_set_arch_mach (stdoutput, TARGET_ARCH, avr_mcu->mach);}/* Resolve STR as a constant expression and return the result.   If result greater than MAX then error.  */static unsigned intavr_get_constant (str, max)     char *str;     int max;{  expressionS ex;  str = skip_space (str);  input_line_pointer = str;  expression (&ex);  if (ex.X_op != O_constant)    as_bad (_("constant value required"));

⌨️ 快捷键说明

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