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

📄 tc-w65.c

📁 基于4个mips核的noc设计
💻 C
📖 第 1 页 / 共 2 页
字号:
/* tc-w65.c -- Assemble code for the W65816   Copyright 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#include "../opcodes/w65-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  */#define OP_BCC	0x90#define OP_BCS	0xB0#define OP_BEQ	0xF0#define OP_BMI	0x30#define OP_BNE	0xD0#define OP_BPL	0x10#define OP_BRA	0x80#define OP_BRL	0x82#define OP_BVC	0x50#define OP_BVS	0x70void s_longa ();const pseudo_typeS md_pseudo_table[] = {  {"int", cons, 2},  {"word", cons, 2},  {"longa", s_longa, 0},  {"longi", s_longa, 1},  {0, 0, 0}};void cons ();void s_align_bytes ();#if 0int md_reloc_size;#endifstatic int relax;		/* set if -relax seen */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";/* Opcode mnemonics */static struct hash_control *opcode_hash_control;int M;				/* M flag */int X;				/* X flag */#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 COND_BRANCH 	1#define UNCOND_BRANCH   2#define END 	3#define BYTE_F 127		/* How far we can branch forwards */#define BYTE_B -126		/* How far we can branch backwards */#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 },  /* COND_BRANCH */  { 0,       0,       0,  0 },				/* UNDEF_BYTE_DISP */  { BYTE_F,  BYTE_B,  2,  C (COND_BRANCH, WORD_DISP) },	/* BYTE_DISP */  { WORD_F,  WORD_B,  5,  0 },				/* WORD_DISP */  { 0,       0,       5,  0 },				/* UNDEF_WORD_DISP */  /* UNCOND_BRANCH */  { 0,       0,       0,  0 },				  /* UNDEF_BYTE_DISP */  { BYTE_F,  BYTE_B,  2,  C (UNCOND_BRANCH, WORD_DISP) }, /* BYTE_DISP */  { WORD_F,  WORD_B,  3,  0 },				  /* WORD_DISP */  { 0,       0,       3,  0 }				  /* UNDEF_WORD_DISP */};/* 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.  */voids_longa (xmode){  int *p = xmode ? &X : &M;  while (*input_line_pointer == ' ')    input_line_pointer++;  if (strncmp (input_line_pointer, "on", 2) == 0)    {      input_line_pointer += 2;      *p = 0;    }  else if (strncmp (input_line_pointer, "off", 3) == 0)    {      *p = 1;      input_line_pointer += 3;    }  else    as_bad (_("need on or off."));  demand_empty_rest_of_line ();}voidmd_begin (){  struct opinfo *opcode;  char *prev_name = "";  opcode_hash_control = hash_new ();  /* Insert unique names into hash table.  */  for (opcode = optable; opcode->name; opcode++)    {      if (strcmp (prev_name, opcode->name))	{	  prev_name = opcode->name;	  hash_insert (opcode_hash_control, opcode->name, (char *) opcode);	}      else	{	  /* Make all the opcodes with the same name point to the same	     string.  */	  opcode->name = prev_name;	}    }  flag_signed_overflow_ok = 1;}static expressionS immediate;	/* absolute expression */static expressionS immediate1;	/* absolute expression */static symbolS *dot (){  const char *fake;  /* JF: '.' is pseudo symbol with value of current location     in current segment.  */  fake = FAKE_LABEL_NAME;  return symbol_new (fake,		     now_seg,		     (valueT) frag_now_fix (),		     frag_now);}int expr_size;int expr_shift;int tc_cons_reloc;voidw65_expression (dest, bytes)     expressionS *dest;     unsigned int bytes;{  expr_size = 0;  expr_shift = 0;  tc_cons_reloc = 0;  while (*input_line_pointer == ' ')    input_line_pointer++;  if (*input_line_pointer == '<')    {      expr_size = 1;      input_line_pointer++;    }  else if (*input_line_pointer == '>')    {      expr_shift = 1;      input_line_pointer++;    }  else if (*input_line_pointer == '^')    {      expr_shift = 2;      input_line_pointer++;    }  expr (0, dest);}int amode;static char *parse_exp (s, bytes)     char *s;     int bytes;{  char *save;  char *new;  save = input_line_pointer;  input_line_pointer = s;  w65_expression (&immediate, bytes);  if (immediate.X_op == O_absent)    as_bad (_("missing operand"));  new = input_line_pointer;  input_line_pointer = save;  return new;}static char *get_operands (info, ptr)     struct opinfo *info;     char *ptr;{  register int override_len = 0;  register int bytes = 0;  while (*ptr == ' ')    ptr++;  if (ptr[0] == '#')    {      ptr++;      switch (info->amode)	{	case ADDR_IMMTOI:	  bytes = X ? 1 : 2;	  amode = ADDR_IMMTOI;	  break;	case ADDR_IMMTOA:	  bytes = M ? 1 : 2;	  amode = ADDR_IMMTOA;	  break;	case ADDR_IMMCOP:	  bytes = 1;	  amode = ADDR_IMMCOP;	  break;	case ADDR_DIR:	  bytes = 2;	  amode = ADDR_ABS;	  break;	default:	  abort ();	  break;	}      ptr = parse_exp (ptr);    }  else if (ptr[0] == '!')    {      ptr = parse_exp (ptr + 1);      if (ptr[0] == ',')	{	  if (ptr[1] == 'y')	    {	      amode = ADDR_ABS_IDX_Y;	      bytes = 2;	      ptr += 2;	    }	  else if (ptr[1] == 'x')	    {	      amode = ADDR_ABS_IDX_X;	      bytes = 2;	      ptr += 2;	    }	  else	    {	      as_bad (_("syntax error after <exp"));	    }	}      else	{	  amode = ADDR_ABS;	  bytes = 2;	}    }  else if (ptr[0] == '>')    {      ptr = parse_exp (ptr + 1);      if (ptr[0] == ',' && ptr[1] == 'x')	{	  amode = ADDR_ABS_LONG_IDX_X;	  bytes = 3;	  ptr += 2;	}      else	{	  amode = ADDR_ABS_LONG;	  bytes = 3;	}    }  else if (ptr[0] == '<')    {      ptr = parse_exp (ptr + 1);      if (ptr[0] == ',')	{	  if (ptr[1] == 'y')	    {	      amode = ADDR_DIR_IDX_Y;	      ptr += 2;	      bytes = 2;	    }	  else if (ptr[1] == 'x')	    {	      amode = ADDR_DIR_IDX_X;	      ptr += 2;	      bytes = 2;	    }	  else	    {	      as_bad (_("syntax error after <exp"));	    }	}      else	{	  amode = ADDR_DIR;	  bytes = 1;	}    }  else if (ptr[0] == 'a')    {      amode = ADDR_ACC;    }  else if (ptr[0] == '(')    {      /* Look for (exp),y	 (<exp),y	 (exp,x)	 (<exp,x)	 (exp)	 (!exp)	 (exp)	 (<exp)	 (exp,x)	 (!exp,x)	 (exp,s)	 (exp,s),y */      ptr++;      if (ptr[0] == '<')	{	  override_len = 1;	  ptr++;	}      else if (ptr[0] == '!')	{	  override_len = 2;	  ptr++;	}      else if (ptr[0] == '>')	{	  override_len = 3;	  ptr++;	}      else	{	  override_len = 0;	}      ptr = parse_exp (ptr);      if (ptr[0] == ',')	{	  ptr++;	  if (ptr[0] == 'x' && ptr[1] == ')')	    {	      ptr += 2;	      if (override_len == 1)		{		  amode = ADDR_DIR_IDX_IND_X;		  bytes = 2;		}	      else		{		  amode = ADDR_ABS_IND_IDX;		  bytes = 2;		}	    }	  else if (ptr[0] == 's' && ptr[1] == ')'		   && ptr[2] == ',' && ptr[3] == 'y')	    {	      amode = ADDR_STACK_REL_INDX_IDX;	      bytes = 1;	      ptr += 4;	    }	}      else if (ptr[0] == ')')	{	  if (ptr[1] == ',' && ptr[2] == 'y')	    {	      amode = ADDR_DIR_IND_IDX_Y;	      ptr += 3;	      bytes = 2;	    }	  else	    {	      if (override_len == 1)		{		  amode = ADDR_DIR_IND;		  bytes = 1;		}	      else		{		  amode = ADDR_ABS_IND;		  bytes = 2;		}	      ptr++;	    }	}    }  else if (ptr[0] == '[')    {      ptr = parse_exp (ptr + 1);      if (ptr[0] == ']')	{	  ptr++;	  if (ptr[0] == ',' && ptr[1] == 'y')	    {	      bytes = 1;	      amode = ADDR_DIR_IND_IDX_Y_LONG;	      ptr += 2;	    }	  else	    {	      if (info->code == O_jmp)		{		  bytes = 2;		  amode = ADDR_ABS_IND_LONG;		}	      else		{		  bytes = 1;		  amode = ADDR_DIR_IND_LONG;		}	    }	}    }  else    {      ptr = parse_exp (ptr, 2);      if (ptr[0] == ',')	{	  if (ptr[1] == 'y')	    {	      if (override_len == 1)		{		  bytes = 1;		  amode = ADDR_DIR_IDX_Y;		}	      else		{		  amode = ADDR_ABS_IDX_Y;		  bytes = 2;		}	      ptr += 2;	    }	  else if (ptr[1] == 'x')	    {	      if (override_len == 1)		{		  amode = ADDR_DIR_IDX_X;		  bytes = 1;		}	      else		{		  amode = ADDR_ABS_IDX_X;		  bytes = 2;		}	      ptr += 2;	    }	  else if (ptr[1] == 's')	    {	      bytes = 1;	      amode = ADDR_STACK_REL;	      ptr += 2;	    }	  else	    {	      bytes = 1;	      immediate1 = immediate;	      ptr = parse_exp (ptr + 1);	      amode = ADDR_BLOCK_MOVE;	    }	}      else	{	  switch (info->amode)	    {	    case ADDR_PC_REL:	      amode = ADDR_PC_REL;	      bytes = 1;	      break;	    case ADDR_PC_REL_LONG:	      amode = ADDR_PC_REL_LONG;	      bytes = 2;	      break;	    default:	      if (override_len == 1)		{		  amode = ADDR_DIR;		  bytes = 1;		}	      else if (override_len == 3)		{		  bytes = 3;		  amode = ADDR_ABS_LONG;		}	      else		{		  amode = ADDR_ABS;		  bytes = 2;		}	    }	}    }  switch (bytes)    {    case 1:      switch (expr_shift)	{	case 0:	  if (amode == ADDR_DIR)	    tc_cons_reloc = R_W65_DP;	  else	    tc_cons_reloc = R_W65_ABS8;	  break;	case 1:	  tc_cons_reloc = R_W65_ABS8S8;	  break;	case 2:	  tc_cons_reloc = R_W65_ABS8S16;	  break;	}      break;    case 2:      switch (expr_shift)	{	case 0:	  tc_cons_reloc = R_W65_ABS16;	  break;	case 1:	  tc_cons_reloc = R_W65_ABS16S8;	  break;	case 2:	  tc_cons_reloc = R_W65_ABS16S16;	  break;	}    }  return ptr;}/* Passed a pointer to a list of opcodes which use different   addressing modes, return the opcode which matches the opcodes   provided.  */static struct opinfo *get_specific (opcode)     struct opinfo *opcode;{  int ocode = opcode->code;

⌨️ 快捷键说明

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