fr30-asm.c

来自「基于4个mips核的noc设计」· C语言 代码 · 共 590 行 · 第 1/2 页

C
590
字号
/* Assembler interface for targets using CGEN. -*- C -*-   CGEN: Cpu tools GENeratorTHIS FILE IS MACHINE GENERATED WITH CGEN.- the resultant file is machine generated, cgen-asm.in isn'tCopyright 1996, 1997, 1998, 1999, 2000, 2001 Free Software Foundation, Inc.This file is part of the GNU Binutils and GDB, the GNU debugger.This program is free software; you can redistribute it and/or modifyit under the terms of the GNU General Public License as published bythe Free Software Foundation; either version 2, or (at your option)any later version.This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; without even the implied warranty ofMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See theGNU General Public License for more details.You should have received a copy of the GNU General Public Licensealong with this program; if not, write to the Free Software Foundation, Inc.,59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  *//* ??? Eventually more and more of this stuff can go to cpu-independent files.   Keep that in mind.  */#include "sysdep.h"#include <ctype.h>#include <stdio.h>#include "ansidecl.h"#include "bfd.h"#include "symcat.h"#include "fr30-desc.h"#include "fr30-opc.h"#include "opintl.h"#undef min#define min(a,b) ((a) < (b) ? (a) : (b))#undef max#define max(a,b) ((a) > (b) ? (a) : (b))static const char * parse_insn_normal     PARAMS ((CGEN_CPU_DESC, const CGEN_INSN *, const char **, CGEN_FIELDS *));/* -- assembler routines inserted here *//* -- asm.c *//* Handle register lists for LDMx and STMx  */static intparse_register_number (strp)     const char **strp;{  int regno;  if (**strp < '0' || **strp > '9')    return -1; /* error */  regno = **strp - '0';  ++*strp;  if (**strp >= '0' && **strp <= '9')    {      regno = regno * 10 + (**strp - '0');      ++*strp;    }  return regno;}static const char *parse_register_list (cd, strp, opindex, valuep, high_low, load_store)     CGEN_CPU_DESC cd;     const char **strp;     int opindex;     unsigned long *valuep;     int high_low;   /* 0 == high, 1 == low */     int load_store; /* 0 == load, 1 == store */{  int regno;  *valuep = 0;  while (**strp && **strp != ')')    {      if (**strp != 'R' && **strp != 'r')	break;      ++*strp;      regno = parse_register_number (strp);      if (regno == -1)	return "Register number is not valid";      if (regno > 7 && !high_low)	return "Register must be between r0 and r7";      if (regno < 8 && high_low)	return "Register must be between r8 and r15";      if (high_low)	regno -= 8;      if (load_store) /* mask is reversed for store */	*valuep |= 0x80 >> regno;      else	*valuep |= 1 << regno;      if (**strp == ',')	{	  if (*(*strp + 1) == ')')	    break;	  ++*strp;	}    }  if (!*strp || **strp != ')')    return "Register list is not valid";  return NULL;}static const char *parse_low_register_list_ld (cd, strp, opindex, valuep)     CGEN_CPU_DESC cd;     const char **strp;     int opindex;     unsigned long *valuep;{  return parse_register_list (cd, strp, opindex, valuep, 0/*low*/, 0/*load*/);}static const char *parse_hi_register_list_ld (cd, strp, opindex, valuep)     CGEN_CPU_DESC cd;     const char **strp;     int opindex;     unsigned long *valuep;{  return parse_register_list (cd, strp, opindex, valuep, 1/*high*/, 0/*load*/);}static const char *parse_low_register_list_st (cd, strp, opindex, valuep)     CGEN_CPU_DESC cd;     const char **strp;     int opindex;     unsigned long *valuep;{  return parse_register_list (cd, strp, opindex, valuep, 0/*low*/, 1/*store*/);}static const char *parse_hi_register_list_st (cd, strp, opindex, valuep)     CGEN_CPU_DESC cd;     const char **strp;     int opindex;     unsigned long *valuep;{  return parse_register_list (cd, strp, opindex, valuep, 1/*high*/, 1/*store*/);}/* -- *//* Main entry point for operand parsing.   This function is basically just a big switch statement.  Earlier versions   used tables to look up the function to use, but   - if the table contains both assembler and disassembler functions then     the disassembler contains much of the assembler and vice-versa,   - there's a lot of inlining possibilities as things grow,   - using a switch statement avoids the function call overhead.   This function could be moved into `parse_insn_normal', but keeping it   separate makes clear the interface between `parse_insn_normal' and each of   the handlers.*/const char *fr30_cgen_parse_operand (cd, opindex, strp, fields)     CGEN_CPU_DESC cd;     int opindex;     const char ** strp;     CGEN_FIELDS * fields;{  const char * errmsg = NULL;  /* Used by scalar operands that still need to be parsed.  */  long junk;  switch (opindex)    {    case FR30_OPERAND_CRI :      errmsg = cgen_parse_keyword (cd, strp, & fr30_cgen_opval_cr_names, & fields->f_CRi);      break;    case FR30_OPERAND_CRJ :      errmsg = cgen_parse_keyword (cd, strp, & fr30_cgen_opval_cr_names, & fields->f_CRj);      break;    case FR30_OPERAND_R13 :      errmsg = cgen_parse_keyword (cd, strp, & fr30_cgen_opval_h_r13, & junk);      break;    case FR30_OPERAND_R14 :      errmsg = cgen_parse_keyword (cd, strp, & fr30_cgen_opval_h_r14, & junk);      break;    case FR30_OPERAND_R15 :      errmsg = cgen_parse_keyword (cd, strp, & fr30_cgen_opval_h_r15, & junk);      break;    case FR30_OPERAND_RI :      errmsg = cgen_parse_keyword (cd, strp, & fr30_cgen_opval_gr_names, & fields->f_Ri);      break;    case FR30_OPERAND_RIC :      errmsg = cgen_parse_keyword (cd, strp, & fr30_cgen_opval_gr_names, & fields->f_Ric);      break;    case FR30_OPERAND_RJ :      errmsg = cgen_parse_keyword (cd, strp, & fr30_cgen_opval_gr_names, & fields->f_Rj);      break;    case FR30_OPERAND_RJC :      errmsg = cgen_parse_keyword (cd, strp, & fr30_cgen_opval_gr_names, & fields->f_Rjc);      break;    case FR30_OPERAND_RS1 :      errmsg = cgen_parse_keyword (cd, strp, & fr30_cgen_opval_dr_names, & fields->f_Rs1);      break;    case FR30_OPERAND_RS2 :      errmsg = cgen_parse_keyword (cd, strp, & fr30_cgen_opval_dr_names, & fields->f_Rs2);      break;    case FR30_OPERAND_CC :      errmsg = cgen_parse_unsigned_integer (cd, strp, FR30_OPERAND_CC, &fields->f_cc);      break;    case FR30_OPERAND_CCC :      errmsg = cgen_parse_unsigned_integer (cd, strp, FR30_OPERAND_CCC, &fields->f_ccc);      break;    case FR30_OPERAND_DIR10 :      errmsg = cgen_parse_unsigned_integer (cd, strp, FR30_OPERAND_DIR10, &fields->f_dir10);      break;    case FR30_OPERAND_DIR8 :      errmsg = cgen_parse_unsigned_integer (cd, strp, FR30_OPERAND_DIR8, &fields->f_dir8);      break;    case FR30_OPERAND_DIR9 :      errmsg = cgen_parse_unsigned_integer (cd, strp, FR30_OPERAND_DIR9, &fields->f_dir9);      break;    case FR30_OPERAND_DISP10 :      errmsg = cgen_parse_signed_integer (cd, strp, FR30_OPERAND_DISP10, &fields->f_disp10);      break;    case FR30_OPERAND_DISP8 :      errmsg = cgen_parse_signed_integer (cd, strp, FR30_OPERAND_DISP8, &fields->f_disp8);      break;    case FR30_OPERAND_DISP9 :      errmsg = cgen_parse_signed_integer (cd, strp, FR30_OPERAND_DISP9, &fields->f_disp9);      break;    case FR30_OPERAND_I20 :      errmsg = cgen_parse_unsigned_integer (cd, strp, FR30_OPERAND_I20, &fields->f_i20);      break;    case FR30_OPERAND_I32 :      errmsg = cgen_parse_unsigned_integer (cd, strp, FR30_OPERAND_I32, &fields->f_i32);      break;    case FR30_OPERAND_I8 :      errmsg = cgen_parse_unsigned_integer (cd, strp, FR30_OPERAND_I8, &fields->f_i8);      break;    case FR30_OPERAND_LABEL12 :      {        bfd_vma value;        errmsg = cgen_parse_address (cd, strp, FR30_OPERAND_LABEL12, 0, NULL,  & value);        fields->f_rel12 = value;      }      break;    case FR30_OPERAND_LABEL9 :      {        bfd_vma value;        errmsg = cgen_parse_address (cd, strp, FR30_OPERAND_LABEL9, 0, NULL,  & value);        fields->f_rel9 = value;      }      break;    case FR30_OPERAND_M4 :      errmsg = cgen_parse_signed_integer (cd, strp, FR30_OPERAND_M4, &fields->f_m4);      break;    case FR30_OPERAND_PS :      errmsg = cgen_parse_keyword (cd, strp, & fr30_cgen_opval_h_ps, & junk);      break;    case FR30_OPERAND_REGLIST_HI_LD :      errmsg = parse_hi_register_list_ld (cd, strp, FR30_OPERAND_REGLIST_HI_LD, &fields->f_reglist_hi_ld);      break;    case FR30_OPERAND_REGLIST_HI_ST :      errmsg = parse_hi_register_list_st (cd, strp, FR30_OPERAND_REGLIST_HI_ST, &fields->f_reglist_hi_st);      break;    case FR30_OPERAND_REGLIST_LOW_LD :      errmsg = parse_low_register_list_ld (cd, strp, FR30_OPERAND_REGLIST_LOW_LD, &fields->f_reglist_low_ld);      break;    case FR30_OPERAND_REGLIST_LOW_ST :      errmsg = parse_low_register_list_st (cd, strp, FR30_OPERAND_REGLIST_LOW_ST, &fields->f_reglist_low_st);      break;    case FR30_OPERAND_S10 :      errmsg = cgen_parse_signed_integer (cd, strp, FR30_OPERAND_S10, &fields->f_s10);      break;    case FR30_OPERAND_U10 :      errmsg = cgen_parse_unsigned_integer (cd, strp, FR30_OPERAND_U10, &fields->f_u10);      break;    case FR30_OPERAND_U4 :      errmsg = cgen_parse_unsigned_integer (cd, strp, FR30_OPERAND_U4, &fields->f_u4);      break;    case FR30_OPERAND_U4C :      errmsg = cgen_parse_unsigned_integer (cd, strp, FR30_OPERAND_U4C, &fields->f_u4c);      break;

⌨️ 快捷键说明

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