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

📄 tc-h8500.c

📁 基于4个mips核的noc设计
💻 C
📖 第 1 页 / 共 3 页
字号:
/* tc-h8500.c -- Assemble code for the Hitachi H8/500   Copyright 1993, 1994, 1995, 1998, 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.  *//* Written By Steve Chamberlain <sac@cygnus.com>.  */#include <stdio.h>#include "as.h"#include "bfd.h"#include "subsegs.h"#define DEFINE_TABLE#define ASSEMBLER_TABLE#include "opcodes/h8500-opc.h"#include <ctype.h>const char comment_chars[] = "!";const char line_separator_chars[] = ";";const char line_comment_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 ();const pseudo_typeS md_pseudo_table[] ={  {"int", cons, 2},  {"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";#define C(a,b) ENCODE_RELAX(a,b)#define ENCODE_RELAX(what,length) (((what) << 2) + (length))#define GET_WHAT(x) ((x>>2))#define BYTE_DISP 1#define WORD_DISP 2#define UNDEF_BYTE_DISP 0#define UNDEF_WORD_DISP 3#define BRANCH  1#define SCB_F   2#define SCB_TST 3#define END 4#define BYTE_F 127#define BYTE_B -126#define WORD_F 32767#define WORD_B 32768relax_typeS md_relax_table[C (END, 0)] = {  { 0, 0, 0, 0 },  { 0, 0, 0, 0 },  { 0, 0, 0, 0 },  { 0, 0, 0, 0 },  /* BRANCH */  { 0,      0,       0, 0 },  { BYTE_F, BYTE_B,  2, C (BRANCH, WORD_DISP) },  { WORD_F, WORD_B,  3, 0 },  { 0,      0,       3, 0 },  /* SCB_F */  { 0,      0,       0, 0 },  { BYTE_F, BYTE_B,  3, C (SCB_F, WORD_DISP) },  { WORD_F, WORD_B,  8, 0 },  { 0,      0,       8, 0 },  /* SCB_TST */  { 0,      0,       0, 0 },  { BYTE_F, BYTE_B,  3, C (SCB_TST, WORD_DISP) },  { WORD_F, WORD_B, 10, 0 },  { 0,      0,      10, 0 }};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 (){  h8500_opcode_info *opcode;  char prev_buffer[100];  int idx = 0;  opcode_hash_control = hash_new ();  prev_buffer[0] = 0;  /* Insert unique names into hash table */  for (opcode = h8500_table; opcode->name; opcode++)    {      if (idx != opcode->idx)	{	  hash_insert (opcode_hash_control, opcode->name, (char *) opcode);	  idx++;	}    }}static int rn;			/* register number used by RN */static int rs;			/* register number used by RS */static int rd;			/* register number used by RD */static int crb;			/* byte size cr */static int crw;			/* word sized cr */static int cr;			/* unknown size cr */static expressionS displacement;/* displacement expression */static int displacement_size;	/* and size if given */static int immediate_inpage;static expressionS immediate;	/* immediate expression */static int immediate_size;	/* and size if given */static expressionS absolute;	/* absolute expression */static int absolute_size;	/* and size if given */typedef struct{  int type;  int reg;  expressionS exp;  int page;}h8500_operand_info;/* Try to parse a reg name.  Return the number of chars consumed.  */static intparse_reg (src, mode, reg)     char *src;     int *mode;     int *reg;{  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] == 'r')    {      if (src[1] >= '0' && src[1] <= '7')	{	  *mode = RN;	  *reg = (src[1] - '0');	  return len;	}    }  if (len == 2 && src[0] == 's' && src[1] == 'p')    {      *mode = RN;      *reg = 7;      return len;    }  if (len == 3 && src[0] == 'c' && src[1] == 'c' && src[2] == 'r')    {      *mode = CRB;      *reg = 1;      return len;    }  if (len == 2 && src[0] == 's' && src[1] == 'r')    {      *mode = CRW;      *reg = 0;      return len;    }  if (len == 2 && src[0] == 'b' && src[1] == 'r')    {      *mode = CRB;      *reg = 3;      return len;    }  if (len == 2 && src[0] == 'e' && src[1] == 'p')    {      *mode = CRB;      *reg = 4;      return len;    }  if (len == 2 && src[0] == 'd' && src[1] == 'p')    {      *mode = CRB;      *reg = 5;      return len;    }  if (len == 2 && src[0] == 't' && src[1] == 'p')    {      *mode = CRB;      *reg = 7;      return len;    }  if (len == 2 && src[0] == 'f' && src[1] == 'p')    {      *mode = RN;      *reg = 6;      return len;    }  return 0;}static char *parse_exp (s, op, page)     char *s;     expressionS *op;     int *page;{  char *save;  char *new;  save = input_line_pointer;  *page = 0;  if (s[0] == '%')    {      if (s[1] == 'p' && s[2] == 'a' && s[3] == 'g' && s[4] == 'e')	{	  s += 5;	  *page = 'p';	}      if (s[1] == 'h' && s[2] == 'i' && s[3] == '1' && s[4] == '6')	{	  s += 5;	  *page = 'h';	}      else if (s[1] == 'o' && s[2] == 'f' && s[3] == 'f')	{	  s += 4;	  *page = 'o';	}    }  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;}typedef enum  {    exp_signed, exp_unsigned, exp_sandu  } sign_type;static char *skip_colonthing (sign, ptr, exp, def, size8, size16, size24)     sign_type sign;     char *ptr;     h8500_operand_info *exp;     int def;     int size8;     int size16;     int size24;{  ptr = parse_exp (ptr, &exp->exp, &exp->page);  if (*ptr == ':')    {      ptr++;      if (*ptr == '8')	{	  ptr++;	  exp->type = size8;	}      else if (ptr[0] == '1' & ptr[1] == '6')	{	  ptr += 2;	  exp->type = size16;	}      else if (ptr[0] == '2' & ptr[1] == '4')	{	  if (!size24)	    {	      as_bad (_(":24 not valid for this opcode"));	    }	  ptr += 2;	  exp->type = size24;	}      else	{	  as_bad (_("expect :8,:16 or :24"));	  exp->type = size16;	}    }  else    {      if (exp->page == 'p')	{	  exp->type = IMM8;	}      else if (exp->page == 'h')	{	  exp->type = IMM16;	}      else	{	  /* Let's work out the size from the context */	  int n = exp->exp.X_add_number;	  if (size8	      && exp->exp.X_op == O_constant	      && ((sign == exp_signed && (n >= -128 && n <= 127))		  || (sign == exp_unsigned && (n >= 0 && (n <= 255)))		  || (sign == exp_sandu && (n >= -128 && (n <= 255)))))	    {	      exp->type = size8;	    }	  else	    {	      exp->type = def;	    }	}    }  return ptr;}static intparse_reglist (src, op)     char *src;     h8500_operand_info *op;{  int mode;  int rn;  int mask = 0;  int rm;  int idx = 1;			/* skip ( */  while (src[idx] && src[idx] != ')')    {      int done = parse_reg (src + idx, &mode, &rn);      if (done)	{	  idx += done;	  mask |= 1 << rn;	}      else	{	  as_bad (_("syntax error in reg list"));	  return 0;	}      if (src[idx] == '-')	{	  idx++;	  done = parse_reg (src + idx, &mode, &rm);	  if (done)	    {	      idx += done;	      while (rn <= rm)		{		  mask |= 1 << rn;		  rn++;		}	    }	  else	    {	      as_bad (_("missing final register in range"));	    }	}      if (src[idx] == ',')	idx++;    }  idx++;  op->exp.X_add_symbol = 0;  op->exp.X_op_symbol = 0;  op->exp.X_add_number = mask;  op->exp.X_op = O_constant;  op->exp.X_unsigned = 1;  op->type = IMM8;  return idx;}/* The many forms of operand:   Rn			Register direct   @Rn			Register indirect   @(disp[:size], Rn)	Register indirect with displacement   @Rn+   @-Rn   @aa[:size]		absolute   #xx[:size]		immediate data   */static voidget_operand (ptr, op, ispage)     char **ptr;     h8500_operand_info *op;     char ispage;{  char *src = *ptr;  int mode;  unsigned int num;  unsigned int len;  op->page = 0;  if (src[0] == '(' && src[1] == 'r')    {      /* This is a register list */      *ptr = src + parse_reglist (src, op);      return;    }  len = parse_reg (src, &op->type, &op->reg);  if (len)    {      *ptr = src + len;      return;    }  if (*src == '@')    {      src++;      if (*src == '-')	{	  src++;	  len = parse_reg (src, &mode, &num);	  if (len == 0)	    {	      /* Oops, not a reg after all, must be ordinary exp */	      src--;	      /* must be a symbol */	      *ptr = skip_colonthing (exp_unsigned, src,				      op, ABS16, ABS8, ABS16, ABS24);	      return;	    }	  op->type = RNDEC;	  op->reg = num;	  *ptr = src + len;	  return;	}      if (*src == '(')	{	  /* Disp */	  src++;	  src = skip_colonthing (exp_signed, src,				 op, RNIND_D16, RNIND_D8, RNIND_D16, 0);	  if (*src != ',')	    {	      as_bad (_("expected @(exp, Rn)"));	      return;	    }	  src++;	  len = parse_reg (src, &mode, &op->reg);	  if (len == 0 || mode != RN)	    {	      as_bad (_("expected @(exp, Rn)"));	      return;	    }	  src += len;	  if (*src != ')')	    {	      as_bad (_("expected @(exp, Rn)"));	      return;	    }	  *ptr = src + 1;	  return;	}      len = parse_reg (src, &mode, &num);      if (len)	{	  src += len;	  if (*src == '+')	    {	      src++;	      if (mode != RN)		{		  as_bad (_("@Rn+ needs word register"));		  return;		}	      op->type = RNINC;	      op->reg = num;	      *ptr = src;	      return;	    }	  if (mode != RN)	    {	      as_bad (_("@Rn needs word register"));	      return;	    }	  op->type = RNIND;	  op->reg = num;	  *ptr = src;

⌨️ 快捷键说明

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