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

📄 tc-h8300.c

📁 基于4个mips核的noc设计
💻 C
📖 第 1 页 / 共 3 页
字号:
/* tc-h8300.c -- Assemble code for the Hitachi H8/300   Copyright 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 2000   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.  *//* Written By Steve Chamberlain <sac@cygnus.com>.  */#include <stdio.h>#include "as.h"#include "subsegs.h"#include "bfd.h"#define DEFINE_TABLE#define h8_opcodes ops#include "opcode/h8300.h"#include <ctype.h>const char comment_chars[] = ";";const char line_comment_chars[] = "#";const char line_separator_chars[] = "";/* This table describes all the machine specific pseudo-ops the assembler   has to support.  The fields are:   pseudo-op name without dot   function to call to execute this pseudo-op   Integer arg to pass to the function   */void cons ();int Hmode;int Smode;#define PSIZE (Hmode ? L_32 : L_16)#define DMODE (L_16)#define DSYMMODE (Hmode ? L_24 : L_16)int bsize = L_8;		/* default branch displacement */voidh8300hmode (){  Hmode = 1;  Smode = 0;}voidh8300smode (){  Smode = 1;  Hmode = 1;}voidsbranch (size)     int size;{  bsize = size;}static voidpint (){  cons (Hmode ? 4 : 2);}const pseudo_typeS md_pseudo_table[] ={  {"h8300h", h8300hmode, 0},  {"h8300s", h8300smode, 0},  {"sbranch", sbranch, L_8},  {"lbranch", sbranch, L_16},  {"int", pint, 0},  {"data.b", cons, 1},  {"data.w", cons, 2},  {"data.l", cons, 4},  {"form", listing_psize, 0},  {"heading", listing_title, 0},  {"import", s_ignore, 0},  {"page", listing_eject, 0},  {"program", s_ignore, 0},  {0, 0, 0}};const int md_reloc_size;const char EXP_CHARS[] = "eE";/* Chars that mean this number is a floating point constant *//* As in 0f12.456 *//* or    0d1.2345e12 */const char FLT_CHARS[] = "rRsSfFdDxXpP";static struct hash_control *opcode_hash_control;	/* Opcode mnemonics *//* This function is called once, at assembler startup time.  This   should set up all the tables, etc. that the MD part of the assembler   needs.  */voidmd_begin (){  struct h8_opcode *opcode;  char prev_buffer[100];  int idx = 0;  opcode_hash_control = hash_new ();  prev_buffer[0] = 0;  for (opcode = h8_opcodes; opcode->name; opcode++)    {      /* Strip off any . part when inserting the opcode and only enter         unique codes into the hash table.  */      char *src = opcode->name;      unsigned int len = strlen (src);      char *dst = malloc (len + 1);      char *buffer = dst;      opcode->size = 0;      while (*src)	{	  if (*src == '.')	    {	      src++;	      opcode->size = *src;	      break;	    }	  *dst++ = *src++;	}      *dst++ = 0;      if (strcmp (buffer, prev_buffer))	{	  hash_insert (opcode_hash_control, buffer, (char *) opcode);	  strcpy (prev_buffer, buffer);	  idx++;	}      opcode->idx = idx;      /* Find the number of operands.  */      opcode->noperands = 0;      while (opcode->args.nib[opcode->noperands] != E)	opcode->noperands++;      /* Find the length of the opcode in bytes.  */      opcode->length = 0;      while (opcode->data.nib[opcode->length * 2] != E)	opcode->length++;    }  linkrelax = 1;}struct h8_exp{  char *e_beg;  char *e_end;  expressionS e_exp;};int dispreg;int opsize;			/* Set when a register size is seen */struct h8_op{  op_type mode;  unsigned reg;  expressionS exp;};/*  parse operands  WREG r0,r1,r2,r3,r4,r5,r6,r7,fp,sp  r0l,r0h,..r7l,r7h  @WREG  @WREG+  @-WREG  #const  ccr*//* Try to parse a reg name.  Return the number of chars consumed.  */static intparse_reg (src, mode, reg, direction)     char *src;     op_type *mode;     unsigned int *reg;     int direction;{  char *end;  int len;  /* Cribbed from get_symbol_end.  */  if (!is_name_beginner (*src) || *src == '\001')    return 0;  end = src + 1;  while (is_part_of_name (*end) || *end == '\001')    end++;  len = end - src;  if (len == 2 && src[0] == 's' && src[1] == 'p')    {      *mode = PSIZE | REG | direction;      *reg = 7;      return len;    }  if (len == 3 && src[0] == 'c' && src[1] == 'c' && src[2] == 'r')    {      *mode = CCR;      *reg = 0;      return len;    }  if (len == 3 && src[0] == 'e' && src[1] == 'x' && src[2] == 'r')    {      *mode = EXR;      *reg = 0;      return len;    }  if (len == 2 && src[0] == 'f' && src[1] == 'p')    {      *mode = PSIZE | REG | direction;      *reg = 6;      return len;    }  if (len == 3 && src[0] == 'e' && src[1] == 'r'      && src[2] >= '0' && src[2] <= '7')    {      *mode = L_32 | REG | direction;      *reg = src[2] - '0';      if (!Hmode)	as_warn (_("Reg not valid for H8/300"));      return len;    }  if (len == 2 && src[0] == 'e' && src[1] >= '0' && src[1] <= '7')    {      *mode = L_16 | REG | direction;      *reg = src[1] - '0' + 8;      if (!Hmode)	as_warn (_("Reg not valid for H8/300"));      return len;    }  if (src[0] == 'r')    {      if (src[1] >= '0' && src[1] <= '7')	{	  if (len == 3 && src[2] == 'l')	    {	      *mode = L_8 | REG | direction;	      *reg = (src[1] - '0') + 8;	      return len;	    }	  if (len == 3 && src[2] == 'h')	    {	      *mode = L_8 | REG | direction;	      *reg = (src[1] - '0');	      return len;	    }	  if (len == 2)	    {	      *mode = L_16 | REG | direction;	      *reg = (src[1] - '0');	      return len;	    }	}    }  return 0;}static char *parse_exp (s, op)     char *s;     expressionS *op;{  char *save = input_line_pointer;  char *new;  input_line_pointer = s;  expression (op);  if (op->X_op == O_absent)    as_bad (_("missing operand"));  new = input_line_pointer;  input_line_pointer = save;  return new;}static char *skip_colonthing (ptr, exp, mode)     char *ptr;     expressionS *exp ATTRIBUTE_UNUSED;     int *mode;{  if (*ptr == ':')    {      ptr++;      *mode &= ~SIZE;      if (*ptr == '8')	{	  ptr++;	  /* ff fill any 8 bit quantity */	  /* exp->X_add_number -= 0x100; */	  *mode |= L_8;	}      else	{	  if (*ptr == '2')	    {	      *mode |= L_24;	    }	  else if (*ptr == '3')	    {	      *mode |= L_32;	    }	  else if (*ptr == '1')	    {	      *mode |= L_16;	    }	  while (isdigit (*ptr))	    ptr++;	}    }  return ptr;}/* The many forms of operand:   Rn			Register direct   @Rn			Register indirect   @(exp[:16], Rn)	Register indirect with displacement   @Rn+   @-Rn   @aa:8		absolute 8 bit   @aa:16		absolute 16 bit   @aa			absolute 16 bit   #xx[:size]		immediate data   @(exp:[8], pc)	pc rel   @@aa[:8]		memory indirect   */char *colonmod24 (op, src)     struct h8_op *op;     char *src;{  int mode = 0;  src = skip_colonthing (src, &op->exp, &mode);  if (!mode)    {      /* Choose a default mode.  */      if (op->exp.X_add_number < -32768	  || op->exp.X_add_number > 32767)	{	  if (Hmode)	    mode = L_24;	  else	    mode = L_16;	}      else if (op->exp.X_add_symbol	       || op->exp.X_op_symbol)	mode = DSYMMODE;      else	mode = DMODE;    }  op->mode |= mode;  return src;}static voidget_operand (ptr, op, dst, direction)     char **ptr;     struct h8_op *op;     unsigned int dst ATTRIBUTE_UNUSED;     int direction;{  char *src = *ptr;  op_type mode;  unsigned int num;  unsigned int len;  op->mode = E;  /* Gross.  Gross.  ldm and stm have a format not easily handled     by get_operand.  We deal with it explicitly here.  */  if (src[0] == 'e' && src[1] == 'r' && isdigit (src[2])      && src[3] == '-' && src[4] == 'e' && src[5] == 'r' && isdigit (src[6]))    {      int low, high;      low = src[2] - '0';      high = src[6] - '0';      if (high < low)	as_bad (_("Invalid register list for ldm/stm\n"));      if (low % 2)	as_bad (_("Invalid register list for ldm/stm\n"));      if (high - low > 3)	as_bad (_("Invalid register list for ldm/stm\n"));      if (high - low != 1	  && low % 4)	as_bad (_("Invalid register list for ldm/stm\n"));      /* Even sicker.  We encode two registers into op->reg.  One	 for the low register to save, the other for the high	 register to save;  we also set the high bit in op->reg	 so we know this is "very special".  */      op->reg = 0x80000000 | (high << 8) | low;      op->mode = REG;      *ptr = src + 7;      return;    }  len = parse_reg (src, &op->mode, &op->reg, direction);  if (len)    {      *ptr = src + len;      return;    }  if (*src == '@')    {      src++;      if (*src == '@')	{	  src++;	  src = parse_exp (src, &op->exp);	  src = skip_colonthing (src, &op->exp, &op->mode);	  *ptr = src;	  op->mode = MEMIND;	  return;	}      if (*src == '-')	{	  src++;	  len = parse_reg (src, &mode, &num, direction);	  if (len == 0)	    {	      /* Oops, not a reg after all, must be ordinary exp.  */	      src--;	      /* Must be a symbol.  */	      op->mode = ABS | PSIZE | direction;	      *ptr = skip_colonthing (parse_exp (src, &op->exp),				      &op->exp, &op->mode);	      return;	    }	  if ((mode & SIZE) != PSIZE)	    as_bad (_("Wrong size pointer register for architecture."));	  op->mode = RDDEC;	  op->reg = num;	  *ptr = src + len;	  return;	}      if (*src == '(')	{	  /* Disp.  */	  src++;	  /* Start off assuming a 16 bit offset.  */	  src = parse_exp (src, &op->exp);	  src = colonmod24 (op, src);	  if (*src == ')')	    {	      src++;	      op->mode |= ABS | direction;	      *ptr = src;	      return;	    }	  if (*src != ',')	    {	      as_bad (_("expected @(exp, reg16)"));	      return;	    }	  src++;	  len = parse_reg (src, &mode, &op->reg, direction);	  if (len == 0 || !(mode & REG))	    {	      as_bad (_("expected @(exp, reg16)"));	      return;	    }	  op->mode |= DISP | direction;	  dispreg = op->reg;	  src += len;	  src = skip_colonthing (src, &op->exp, &op->mode);

⌨️ 快捷键说明

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