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 + -
显示快捷键?