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

📄 tc-z8k.c

📁 基于4个mips核的noc设计
💻 C
📖 第 1 页 / 共 2 页
字号:
/* tc-z8k.c -- Assemble code for the Zilog Z800n   Copyright 1992, 1993, 1994, 1995, 1996, 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>.  */#define DEFINE_TABLE#include <stdio.h>#include "opcodes/z8k-opc.h"#include "as.h"#include "bfd.h"#include <ctype.h>const char comment_chars[] = "!";const char line_comment_chars[] = "#";const char line_separator_chars[] = ";";extern int machine;extern int coff_flags;int segmented_mode;const int md_reloc_size;void cons ();voids_segm (){  segmented_mode = 1;  machine = bfd_mach_z8001;  coff_flags = F_Z8001;}voids_unseg (){  segmented_mode = 0;  machine = bfd_mach_z8002;  coff_flags = F_Z8002;}static voideven (){  frag_align (1, 0, 0);  record_alignment (now_seg, 1);}void obj_coff_section ();inttohex (c)     int c;{  if (isdigit (c))    return c - '0';  if (islower (c))    return c - 'a' + 10;  return c - 'A' + 10;}voidsval (){  SKIP_WHITESPACE ();  if (*input_line_pointer == '\'')    {      int c;      input_line_pointer++;      c = *input_line_pointer++;      while (c != '\'')	{	  if (c == '%')	    {	      c = (tohex (input_line_pointer[0]) << 4)		| tohex (input_line_pointer[1]);	      input_line_pointer += 2;	    }	  FRAG_APPEND_1_CHAR (c);	  c = *input_line_pointer++;	}      demand_empty_rest_of_line ();    }}/* 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   */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},  {"z8001"  , s_segm          , 0},  {"z8002"  , s_unseg         , 0},  {"segm"   , s_segm          , 0},  {"unsegm" , s_unseg         , 0},  {"unseg"  , s_unseg         , 0},  {"name"   , s_app_file      , 0},  {"global" , s_globl         , 0},  {"wval"   , cons            , 2},  {"lval"   , cons            , 4},  {"bval"   , cons            , 1},  {"sval"   , sval            , 0},  {"rsect"  , obj_coff_section, 0},  {"sect"   , obj_coff_section, 0},  {"block"  , s_space         , 0},  {"even"   , even            , 0},  {0        , 0               , 0}};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;voidmd_begin (){  opcode_entry_type *opcode;  char *prev_name = "";  int idx = 0;  opcode_hash_control = hash_new ();  for (opcode = z8k_table; opcode->name; opcode++)    {      /* Only enter unique codes into the table.  */      if (strcmp (opcode->name, prev_name))	{	  hash_insert (opcode_hash_control, opcode->name, (char *) opcode);	  idx++;	}      opcode->idx = idx;      prev_name = opcode->name;    }  /* Default to z8002.  */  s_unseg ();  /* Insert the pseudo ops, too.  */  for (idx = 0; md_pseudo_table[idx].poc_name; idx++)    {      opcode_entry_type *fake_opcode;      fake_opcode = (opcode_entry_type *) malloc (sizeof (opcode_entry_type));      fake_opcode->name = md_pseudo_table[idx].poc_name;      fake_opcode->func = (void *) (md_pseudo_table + idx);      fake_opcode->opcode = 250;      hash_insert (opcode_hash_control, fake_opcode->name, fake_opcode);    }  linkrelax = 1;}struct z8k_exp {  char *e_beg;  char *e_end;  expressionS e_exp;};typedef struct z8k_op {  /* 'b','w','r','q'.  */  char regsize;  /* 0 .. 15.  */  unsigned int reg;  int mode;  /* Any other register associated with the mode.  */  unsigned int x_reg;  /* Any expression.  */  expressionS exp;} op_type;static expressionS *da_operand;static expressionS *imm_operand;int reg[16];int the_cc;int the_ctrl;int the_flags;int the_interrupt;char *whatreg (reg, src)     int *reg;     char *src;{  if (isdigit (src[1]))    {      *reg = (src[0] - '0') * 10 + src[1] - '0';      return src + 2;    }  else    {      *reg = (src[0] - '0');      return src + 1;    }}/* Parse operands   rh0-rh7, rl0-rl7   r0-r15   rr0-rr14   rq0--rq12   WREG r0,r1,r2,r3,r4,r5,r6,r7,fp,sp   r0l,r0h,..r7l,r7h   @WREG   @WREG+   @-WREG   #const*//* Try to parse a reg name.  Return a pointer to the first character   in SRC after the reg name.  */char *parse_reg (src, mode, reg)     char *src;     int *mode;     unsigned int *reg;{  char *res = 0;  char regno;  if (src[0] == 's' && src[1] == 'p')    {      if (segmented_mode)	{	  *mode = CLASS_REG_LONG;	  *reg = 14;	}      else	{	  *mode = CLASS_REG_WORD;	  *reg = 15;	}      return src + 2;    }  if (src[0] == 'r')    {      if (src[1] == 'r')	{	  *mode = CLASS_REG_LONG;	  res = whatreg (reg, src + 2);	  regno = *reg;	  if (regno > 14)	    as_warn (_("register rr%d, out of range."), regno);	}      else if (src[1] == 'h')	{	  *mode = CLASS_REG_BYTE;	  res = whatreg (reg, src + 2);	  regno = *reg;	  if (regno > 7)	    as_warn (_("register rh%d, out of range."), regno);	}      else if (src[1] == 'l')	{	  *mode = CLASS_REG_BYTE;	  res = whatreg (reg, src + 2);	  regno = *reg;	  if (regno > 7)	    as_warn (_("register rl%d, out of range."), regno);	  *reg += 8;	}      else if (src[1] == 'q')	{	  *mode = CLASS_REG_QUAD;	  res = whatreg (reg, src + 2);	  regno = *reg;	  if (regno > 12)	    as_warn (_("register rq%d, out of range."), regno);	}      else	{	  *mode = CLASS_REG_WORD;	  res = whatreg (reg, src + 1);	  regno = *reg;	  if (regno > 15)	    as_warn (_("register r%d, out of range."), regno);	}    }  return res;}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;}/* The many forms of operand:   <rb>   <r>   <rr>   <rq>   @r   #exp   exp   exp(r)   r(#exp)   r(r)   */static char *checkfor (ptr, what)     char *ptr;     char what;{  if (*ptr == what)    ptr++;  else    as_bad (_("expected %c"), what);  return ptr;}/* Make sure the mode supplied is the size of a word.  */static voidregword (mode, string)     int mode;     char *string;{  int ok;  ok = CLASS_REG_WORD;  if (ok != mode)    {      as_bad (_("register is wrong size for a word %s"), string);    }}/* Make sure the mode supplied is the size of an address.  */static voidregaddr (mode, string)     int mode;     char *string;{  int ok;  ok = segmented_mode ? CLASS_REG_LONG : CLASS_REG_WORD;  if (ok != mode)    {      as_bad (_("register is wrong size for address %s"), string);    }}struct ctrl_names {  int value;  char *name;};struct ctrl_names ctrl_table[] = {  { 0x2, "fcw" },  { 0x3, "refresh" },  { 0x4, "psapseg" },  { 0x5, "psapoff" },  { 0x5, "psap" },  { 0x6, "nspseg" },  { 0x7, "nspoff" },  { 0x7, "nsp" },  { 0  , 0 }};static voidget_ctrl_operand (ptr, mode, dst)     char **ptr;     struct z8k_op *mode;     unsigned int dst ATTRIBUTE_UNUSED;{  char *src = *ptr;  int i;  while (*src == ' ')    src++;  mode->mode = CLASS_CTRL;  for (i = 0; ctrl_table[i].name; i++)    {      int j;      for (j = 0; ctrl_table[i].name[j]; j++)	{	  if (ctrl_table[i].name[j] != src[j])	    goto fail;	}      the_ctrl = ctrl_table[i].value;      *ptr = src + j;      return;    fail:      ;    }  the_ctrl = 0;  return;}struct flag_names {  int value;  char *name;};struct flag_names flag_table[] = {  { 0x1, "p" },  { 0x1, "v" },  { 0x2, "s" },  { 0x4, "z" },  { 0x8, "c" },  { 0x0, "+" },  { 0, 0 }};static voidget_flags_operand (ptr, mode, dst)     char **ptr;     struct z8k_op *mode;     unsigned int dst ATTRIBUTE_UNUSED;{  char *src = *ptr;  int i;  int j;  while (*src == ' ')    src++;  mode->mode = CLASS_FLAGS;  the_flags = 0;  for (j = 0; j <= 9; j++)    {      if (!src[j])	goto done;      for (i = 0; flag_table[i].name; i++)	{	  if (flag_table[i].name[0] == src[j])	    {	      the_flags = the_flags | flag_table[i].value;	      goto match;	    }	}      goto done;    match:      ;    } done:  *ptr = src + j;  return;}struct interrupt_names {  int value;  char *name;};struct interrupt_names intr_table[] = {  { 0x1, "nvi" },  { 0x2, "vi" },  { 0x3, "both" },  { 0x3, "all" },  { 0, 0 }};static voidget_interrupt_operand (ptr, mode, dst)     char **ptr;     struct z8k_op *mode;     unsigned int dst ATTRIBUTE_UNUSED;{  char *src = *ptr;  int i;  while (*src == ' ')    src++;  mode->mode = CLASS_IMM;  for (i = 0; intr_table[i].name; i++)    {      int j;      for (j = 0; intr_table[i].name[j]; j++)	{	  if (intr_table[i].name[j] != src[j])	    goto fail;	}      the_interrupt = intr_table[i].value;      *ptr = src + j;      return;    fail:      ;    }  the_interrupt = 0x0;  return;}struct cc_names {  int value;  char *name;};struct cc_names table[] = {  { 0x0, "f" },  { 0x1, "lt" },  { 0x2, "le" },  { 0x3, "ule" },  { 0x4, "ov" },  { 0x4, "pe" },  { 0x5, "mi" },  { 0x6, "eq" },  { 0x6, "z" },  { 0x7, "c" },  { 0x7, "ult" },  { 0x8, "t" },  { 0x9, "ge" },  { 0xa, "gt" },  { 0xb, "ugt" },  { 0xc, "nov" },  { 0xc, "po" },  { 0xd, "pl" },  { 0xe, "ne" },  { 0xe, "nz" },  { 0xf, "nc" },  { 0xf, "uge" },  { 0  ,  0 }};static voidget_cc_operand (ptr, mode, dst)     char **ptr;     struct z8k_op *mode;     unsigned int dst ATTRIBUTE_UNUSED;{  char *src = *ptr;  int i;  while (*src == ' ')    src++;  mode->mode = CLASS_CC;  for (i = 0; table[i].name; i++)    {      int j;      for (j = 0; table[i].name[j]; j++)	{	  if (table[i].name[j] != src[j])	    goto fail;	}      the_cc = table[i].value;      *ptr = src + j;      return;    fail:      ;    }  the_cc = 0x8;}static voidget_operand (ptr, mode, dst)     char **ptr;     struct z8k_op *mode;     unsigned int dst ATTRIBUTE_UNUSED;{  char *src = *ptr;  char *end;  mode->mode = 0;  while (*src == ' ')    src++;  if (*src == '#')    {      mode->mode = CLASS_IMM;      imm_operand = &(mode->exp);      src = parse_exp (src + 1, &(mode->exp));    }  else if (*src == '@')    {      int d;      mode->mode = CLASS_IR;      src = parse_reg (src + 1, &d, &mode->reg);    }  else    {      int regn;      end = parse_reg (src, &mode->mode, &regn);      if (end)	{	  int nw, nr;	  src = end;	  if (*src == '(')	    {	      src++;	      end = parse_reg (src, &nw, &nr);	      if (end)		{		  /* Got Ra(Rb).  */		  src = end;		  if (*src != ')')		    as_bad (_("Missing ) in ra(rb)"));		  else		    src++;		  regaddr (mode->mode, "ra(rb) ra");#if 0		  regword (mode->mode, "ra(rb) rb");#endif		  mode->mode = CLASS_BX;		  mode->reg = regn;		  mode->x_reg = nr;		  reg[ARG_RX] = nr;		}	      else		{		  /* Got Ra(disp).  */		  if (*src == '#')		    src++;		  src = parse_exp (src, &(mode->exp));		  src = checkfor (src, ')');		  mode->mode = CLASS_BA;		  mode->reg = regn;		  mode->x_reg = 0;		  imm_operand = &(mode->exp);		}	    }	  else	    {	      mode->reg = regn;	      mode->x_reg = 0;	    }	}      else	{	  /* No initial reg.  */	  src = parse_exp (src, &(mode->exp));	  if (*src == '(')	    {	      src++;	      end = parse_reg (src, &(mode->mode), &regn);	      regword (mode->mode, "addr(Ra) ra");	      mode->mode = CLASS_X;	      mode->reg = regn;	      mode->x_reg = 0;	      da_operand = &(mode->exp);	      src = checkfor (end, ')');	    }	  else	    {	      /* Just an address.  */	      mode->mode = CLASS_DA;	      mode->reg = 0;	      mode->x_reg = 0;	      da_operand = &(mode->exp);	    }	}    }  *ptr = src;}static char *get_operands (opcode, op_end, operand)     opcode_entry_type *opcode;     char *op_end;     op_type *operand;{  char *ptr = op_end;  char *savptr;  switch (opcode->noperands)    {    case 0:      operand[0].mode = 0;      operand[1].mode = 0;      break;    case 1:      ptr++;      if (opcode->arg_info[0] == CLASS_CC)	{	  get_cc_operand (&ptr, operand + 0, 0);	}      else if (opcode->arg_info[0] == CLASS_FLAGS)	{	  get_flags_operand (&ptr, operand + 0, 0);	}      else if (opcode->arg_info[0] == (CLASS_IMM + (ARG_IMM2)))	{	  get_interrupt_operand (&ptr, operand + 0, 0);	}      else	{	  get_operand (&ptr, operand + 0, 0);	}      operand[1].mode = 0;      break;    case 2:      ptr++;      savptr = ptr;      if (opcode->arg_info[0] == CLASS_CC)	{	  get_cc_operand (&ptr, operand + 0, 0);	}      else if (opcode->arg_info[0] == CLASS_CTRL)	{	  get_ctrl_operand (&ptr, operand + 0, 0);	  if (the_ctrl == 0)	    {	      ptr = savptr;	      get_operand (&ptr, operand + 0, 0);	      if (ptr == 0)		return NULL;	      if (*ptr == ',')		ptr++;	      get_ctrl_operand (&ptr, operand + 1, 1);	      return ptr;	    }	}      else	{	  get_operand (&ptr, operand + 0, 0);

⌨️ 快捷键说明

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