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

📄 tc-avr.c

📁 基于4个mips核的noc设计
💻 C
📖 第 1 页 / 共 3 页
字号:
    {      /* Fetch the instruction, insert the fully resolved operand	 value, and stuff the instruction back again.  */      where = fixp->fx_frag->fr_literal + fixp->fx_where;      insn = bfd_getl16 (where);      switch (fixp->fx_r_type)	{	case BFD_RELOC_AVR_7_PCREL:	  if (value & 1)	    as_bad_where (fixp->fx_file, fixp->fx_line,			  _("odd address operand: %ld"), value);	  /* Instruction addresses are always right-shifted by 1.  */	  value >>= 1;	  --value;			/* Correct PC.  */	  if (value < -64 || value > 63)	    as_bad_where (fixp->fx_file, fixp->fx_line,			  _("operand out of range: %ld"), value);	  value = (value << 3) & 0x3f8;	  bfd_putl16 ((bfd_vma) (value | insn), where);	  break;	case BFD_RELOC_AVR_13_PCREL:	  if (value & 1)	    as_bad_where (fixp->fx_file, fixp->fx_line,			  _("odd address operand: %ld"), value);	  /* Instruction addresses are always right-shifted by 1.  */	  value >>= 1;	  --value;			/* Correct PC.  */	  if (value < -2048 || value > 2047)	    {	      /* No wrap for devices with >8K of program memory.  */	      if ((avr_mcu->isa & AVR_ISA_MEGA) || avr_opt.no_wrap)		as_bad_where (fixp->fx_file, fixp->fx_line,			      _("operand out of range: %ld"), value);	    }	  value &= 0xfff;	  bfd_putl16 ((bfd_vma) (value | insn), where);	  break;	case BFD_RELOC_32:	  bfd_putl16 ((bfd_vma) value, where);	  break;	case BFD_RELOC_16:	  bfd_putl16 ((bfd_vma) value, where);	  break;	case BFD_RELOC_AVR_16_PM:	  bfd_putl16 ((bfd_vma) (value >> 1), where);	  break;	case BFD_RELOC_AVR_LO8_LDI:	  bfd_putl16 ((bfd_vma) insn | LDI_IMMEDIATE (value), where);	  break;	case -BFD_RELOC_AVR_LO8_LDI:	  bfd_putl16 ((bfd_vma) insn | LDI_IMMEDIATE (value >> 16), where);	  break;	case BFD_RELOC_AVR_HI8_LDI:	  bfd_putl16 ((bfd_vma) insn | LDI_IMMEDIATE (value >> 8), where);	  break;	case -BFD_RELOC_AVR_HI8_LDI:	  bfd_putl16 ((bfd_vma) insn | LDI_IMMEDIATE (value >> 24), where);	  break;	case BFD_RELOC_AVR_HH8_LDI:	  bfd_putl16 ((bfd_vma) insn | LDI_IMMEDIATE (value >> 16), where);	  break;	case BFD_RELOC_AVR_LO8_LDI_NEG:	  bfd_putl16 ((bfd_vma) insn | LDI_IMMEDIATE (-value), where);	  break;	case -BFD_RELOC_AVR_LO8_LDI_NEG:	  bfd_putl16 ((bfd_vma) insn | LDI_IMMEDIATE (-value >> 16), where);	  break;	case BFD_RELOC_AVR_HI8_LDI_NEG:	  bfd_putl16 ((bfd_vma) insn | LDI_IMMEDIATE (-value >> 8), where);	  break;	case -BFD_RELOC_AVR_HI8_LDI_NEG:	  bfd_putl16 ((bfd_vma) insn | LDI_IMMEDIATE (-value >> 24), where);	  break;	case BFD_RELOC_AVR_HH8_LDI_NEG:	  bfd_putl16 ((bfd_vma) insn | LDI_IMMEDIATE (-value >> 16), where);	  break;	case BFD_RELOC_AVR_LO8_LDI_PM:	  bfd_putl16 ((bfd_vma) insn | LDI_IMMEDIATE (value >> 1), where);	  break;	case BFD_RELOC_AVR_HI8_LDI_PM:	  bfd_putl16 ((bfd_vma) insn | LDI_IMMEDIATE (value >> 9), where);	  break;	case BFD_RELOC_AVR_HH8_LDI_PM:	  bfd_putl16 ((bfd_vma) insn | LDI_IMMEDIATE (value >> 17), where);	  break;	case BFD_RELOC_AVR_LO8_LDI_PM_NEG:	  bfd_putl16 ((bfd_vma) insn | LDI_IMMEDIATE (-value >> 1), where);	  break;	case BFD_RELOC_AVR_HI8_LDI_PM_NEG:	  bfd_putl16 ((bfd_vma) insn | LDI_IMMEDIATE (-value >> 9), where);	  break;	case BFD_RELOC_AVR_HH8_LDI_PM_NEG:	  bfd_putl16 ((bfd_vma) insn | LDI_IMMEDIATE (-value >> 17), where);	  break;	case BFD_RELOC_AVR_CALL:	  {	    unsigned long x;	    x = bfd_getl16 (where);	    if (value & 1)	      as_bad_where (fixp->fx_file, fixp->fx_line,			    _("odd address operand: %ld"), value);	    value >>= 1;	    x |= ((value & 0x10000) | ((value << 3) & 0x1f00000)) >> 16;	    bfd_putl16 ((bfd_vma) x, where);	    bfd_putl16 ((bfd_vma) (value & 0xffff), where + 2);	  }	  break;	default:	  as_fatal (_("line %d: unknown relocation type: 0x%x"),		    fixp->fx_line, fixp->fx_r_type);	  break;	}    }  else    {      switch (fixp->fx_r_type)	{	case -BFD_RELOC_AVR_HI8_LDI_NEG:	case -BFD_RELOC_AVR_HI8_LDI:	case -BFD_RELOC_AVR_LO8_LDI_NEG:	case -BFD_RELOC_AVR_LO8_LDI:	  as_bad_where (fixp->fx_file, fixp->fx_line,			_("only constant expression allowed"));	  fixp->fx_done = 1;	  break;	default:	  break;	}      fixp->fx_addnumber = value;    }  return 0;}/* A `BFD_ASSEMBLER' GAS will call this to generate a reloc.  GAS   will pass the resulting reloc to `bfd_install_relocation'.  This   currently works poorly, as `bfd_install_relocation' often does the   wrong thing, and instances of `tc_gen_reloc' have been written to   work around the problems, which in turns makes it difficult to fix   `bfd_install_relocation'.  *//* If while processing a fixup, a reloc really needs to be created   then it is done here.  */arelent *tc_gen_reloc (seg, fixp)     asection *seg ATTRIBUTE_UNUSED;     fixS *fixp;{  arelent *reloc;  reloc = (arelent *) xmalloc (sizeof (arelent));  reloc->sym_ptr_ptr = (asymbol **) xmalloc (sizeof (asymbol *));  *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);  reloc->address = fixp->fx_frag->fr_address + fixp->fx_where;  reloc->howto = bfd_reloc_type_lookup (stdoutput, fixp->fx_r_type);  if (reloc->howto == (reloc_howto_type *) NULL)    {      as_bad_where (fixp->fx_file, fixp->fx_line,		    _("reloc %d not supported by object file format"),		    (int) fixp->fx_r_type);      return NULL;    }  if (fixp->fx_r_type == BFD_RELOC_VTABLE_INHERIT      || fixp->fx_r_type == BFD_RELOC_VTABLE_ENTRY)    reloc->address = fixp->fx_offset;  reloc->addend = fixp->fx_offset;  return reloc;}voidmd_assemble (str)     char *str;{  struct avr_opcodes_s *opcode;  char op[11];  str = skip_space (extract_word (str, op, sizeof (op)));  if (!op[0])    as_bad (_("can't find opcode "));  opcode = (struct avr_opcodes_s *) hash_find (avr_hash, op);  if (opcode == NULL)    {      as_bad (_("unknown opcode `%s'"), op);      return;    }  /* Special case for opcodes with optional operands (lpm, elpm) -     version with operands exists in avr_opcodes[] in the next entry.  */  if (*str && *opcode->constraints == '?')    ++opcode;  if (!avr_opt.all_opcodes && (opcode->isa & avr_mcu->isa) != opcode->isa)    as_bad (_("illegal opcode %s for mcu %s"), opcode->name, avr_mcu->name);  /* We used to set input_line_pointer to the result of get_operands,     but that is wrong.  Our caller assumes we don't change it.  */  {    char *t = input_line_pointer;    avr_operands (opcode, &str);    if (*skip_space (str))      as_bad (_("garbage at end of line"));    input_line_pointer = t;  }}/* Parse ordinary expression.  */static char *parse_exp (s, op)     char *s;     expressionS *op;{  input_line_pointer = s;  expression (op);  if (op->X_op == O_absent)    as_bad (_("missing operand"));  return input_line_pointer;}/* Parse special expressions (needed for LDI command):   xx8 (address)   xx8 (-address)   pm_xx8 (address)   pm_xx8 (-address)   where xx is: hh, hi, lo.  */static bfd_reloc_code_real_typeavr_ldi_expression (exp)     expressionS *exp;{  char *str = input_line_pointer;  char *tmp;  char op[8];  int mod;  tmp = str;  str = extract_word (str, op, sizeof (op));  if (op[0])    {      mod = (int) hash_find (avr_mod_hash, op);      if (mod)	{	  int closes = 0;	  mod -= 10;	  str = skip_space (str);	  if (*str == '(')	    {	      int neg_p = 0;	      ++str;	      if (strncmp ("pm(", str, 3) == 0		  || strncmp ("-(pm(", str, 5) == 0)		{		  if (HAVE_PM_P (mod))		    {		      ++mod;		      ++closes;		    }		  else		    as_bad (_("illegal expression"));		  if (*str == '-')		    {		      neg_p = 1;		      ++closes;		      str += 5;		    }		  else		    str += 3;		}	      if (*str == '-' && *(str + 1) == '(')		{		  neg_p ^= 1;		  ++closes;		  str += 2;		}	      input_line_pointer = str;	      expression (exp);	      do		{		  if (*input_line_pointer != ')')		    {		      as_bad (_("`)' required"));		      break;		    }		  input_line_pointer++;		}	      while (closes--);	      return neg_p ? EXP_MOD_NEG_RELOC (mod) : EXP_MOD_RELOC (mod);	    }	}    }  input_line_pointer = tmp;  expression (exp);  /* Warn about expressions that fail to use lo8 ().  */  if (exp->X_op == O_constant)    {      int x = exp->X_add_number;      if (x < -255 || x > 255)	as_warn (_("constant out of 8-bit range: %d"), x);    }  else    as_warn (_("expression possibly out of 8-bit range"));  return BFD_RELOC_AVR_LO8_LDI;}/* Flag to pass `pm' mode between `avr_parse_cons_expression' and   `avr_cons_fix_new'.  */static int exp_mod_pm = 0;/* Parse special CONS expression: pm (expression)   which is used for addressing to a program memory.   Relocation: BFD_RELOC_AVR_16_PM.  */voidavr_parse_cons_expression (exp, nbytes)     expressionS *exp;     int nbytes;{  char *tmp;  exp_mod_pm = 0;  tmp = input_line_pointer = skip_space (input_line_pointer);  if (nbytes == 2)    {      char *pm_name = "pm";      int len = strlen (pm_name);      if (strncasecmp (input_line_pointer, pm_name, len) == 0)	{	  input_line_pointer = skip_space (input_line_pointer + len);	  if (*input_line_pointer == '(')	    {	      input_line_pointer = skip_space (input_line_pointer + 1);	      exp_mod_pm = 1;	      expression (exp);	      if (*input_line_pointer == ')')		++input_line_pointer;	      else		{		  as_bad (_("`)' required"));		  exp_mod_pm = 0;		}	      return;	    }	  input_line_pointer = tmp;	}    }  expression (exp);}voidavr_cons_fix_new (frag, where, nbytes, exp)     fragS *frag;     int where;     int nbytes;     expressionS *exp;{  if (exp_mod_pm == 0)    {      if (nbytes == 2)	fix_new_exp (frag, where, nbytes, exp, false, BFD_RELOC_16);      else if (nbytes == 4)	fix_new_exp (frag, where, nbytes, exp, false, BFD_RELOC_32);      else	as_bad (_("illegal %srelocation size: %d"), "", nbytes);    }  else    {      if (nbytes == 2)	fix_new_exp (frag, where, nbytes, exp, false, BFD_RELOC_AVR_16_PM);      else	as_bad (_("illegal %srelocation size: %d"), "`pm' ", nbytes);      exp_mod_pm = 0;    }}

⌨️ 快捷键说明

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