📄 m32r-dis.c
字号:
/* Disassembler interface for targets using CGEN. -*- C -*- CGEN: Cpu tools GENeratorTHIS FILE IS MACHINE GENERATED WITH CGEN.- the resultant file is machine generated, cgen-dis.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 <stdio.h>#include "ansidecl.h"#include "dis-asm.h"#include "bfd.h"#include "symcat.h"#include "m32r-desc.h"#include "m32r-opc.h"#include "opintl.h"/* Default text to print if an instruction isn't recognized. */#define UNKNOWN_INSN_MSG _("*unknown*")static void print_normal PARAMS ((CGEN_CPU_DESC, PTR, long, unsigned int, bfd_vma, int));static void print_address PARAMS ((CGEN_CPU_DESC, PTR, bfd_vma, unsigned int, bfd_vma, int));static void print_keyword PARAMS ((CGEN_CPU_DESC, PTR, CGEN_KEYWORD *, long, unsigned int));static void print_insn_normal PARAMS ((CGEN_CPU_DESC, PTR, const CGEN_INSN *, CGEN_FIELDS *, bfd_vma, int));static int print_insn PARAMS ((CGEN_CPU_DESC, bfd_vma, disassemble_info *, char *, int));static int default_print_insn PARAMS ((CGEN_CPU_DESC, bfd_vma, disassemble_info *));/* -- disassembler routines inserted here *//* -- dis.c *//* Immediate values are prefixed with '#'. */#define CGEN_PRINT_NORMAL(cd, info, value, attrs, pc, length) \do { \ if (CGEN_BOOL_ATTR ((attrs), CGEN_OPERAND_HASH_PREFIX)) \ (*info->fprintf_func) (info->stream, "#"); \} while (0)/* Handle '#' prefixes as operands. */static voidprint_hash (cd, dis_info, value, attrs, pc, length) CGEN_CPU_DESC cd ATTRIBUTE_UNUSED; PTR dis_info; long value ATTRIBUTE_UNUSED; unsigned int attrs ATTRIBUTE_UNUSED; bfd_vma pc ATTRIBUTE_UNUSED; int length ATTRIBUTE_UNUSED;{ disassemble_info *info = (disassemble_info *) dis_info; (*info->fprintf_func) (info->stream, "#");}#undef CGEN_PRINT_INSN#define CGEN_PRINT_INSN my_print_insnstatic intmy_print_insn (cd, pc, info) CGEN_CPU_DESC cd; bfd_vma pc; disassemble_info *info;{ char buffer[CGEN_MAX_INSN_SIZE]; char *buf = buffer; int status; int buflen = (pc & 3) == 0 ? 4 : 2; /* Read the base part of the insn. */ status = (*info->read_memory_func) (pc, buf, buflen, info); if (status != 0) { (*info->memory_error_func) (status, pc, info); return -1; } /* 32 bit insn? */ if ((pc & 3) == 0 && (buf[0] & 0x80) != 0) return print_insn (cd, pc, info, buf, buflen); /* Print the first insn. */ if ((pc & 3) == 0) { if (print_insn (cd, pc, info, buf, 2) == 0) (*info->fprintf_func) (info->stream, UNKNOWN_INSN_MSG); buf += 2; } if (buf[0] & 0x80) { /* Parallel. */ (*info->fprintf_func) (info->stream, " || "); buf[0] &= 0x7f; } else (*info->fprintf_func) (info->stream, " -> "); /* The "& 3" is to pass a consistent address. Parallel insns arguably both begin on the word boundary. Also, branch insns are calculated relative to the word boundary. */ if (print_insn (cd, pc & ~ (bfd_vma) 3, info, buf, 2) == 0) (*info->fprintf_func) (info->stream, UNKNOWN_INSN_MSG); return (pc & 3) ? 2 : 4;}/* -- *//* Main entry point for printing operands. XINFO is a `void *' and not a `disassemble_info *' to not put a requirement of dis-asm.h on cgen.h. 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 `print_insn_normal', but keeping it separate makes clear the interface between `print_insn_normal' and each of the handlers.*/voidm32r_cgen_print_operand (cd, opindex, xinfo, fields, attrs, pc, length) CGEN_CPU_DESC cd; int opindex; PTR xinfo; CGEN_FIELDS *fields; void const *attrs ATTRIBUTE_UNUSED; bfd_vma pc; int length;{ disassemble_info *info = (disassemble_info *) xinfo; switch (opindex) { case M32R_OPERAND_ACC : print_keyword (cd, info, & m32r_cgen_opval_h_accums, fields->f_acc, 0); break; case M32R_OPERAND_ACCD : print_keyword (cd, info, & m32r_cgen_opval_h_accums, fields->f_accd, 0); break; case M32R_OPERAND_ACCS : print_keyword (cd, info, & m32r_cgen_opval_h_accums, fields->f_accs, 0); break; case M32R_OPERAND_DCR : print_keyword (cd, info, & m32r_cgen_opval_cr_names, fields->f_r1, 0); break; case M32R_OPERAND_DISP16 : print_address (cd, info, fields->f_disp16, 0|(1<<CGEN_OPERAND_RELOC)|(1<<CGEN_OPERAND_PCREL_ADDR), pc, length); break; case M32R_OPERAND_DISP24 : print_address (cd, info, fields->f_disp24, 0|(1<<CGEN_OPERAND_RELAX)|(1<<CGEN_OPERAND_RELOC)|(1<<CGEN_OPERAND_PCREL_ADDR), pc, length); break; case M32R_OPERAND_DISP8 : print_address (cd, info, fields->f_disp8, 0|(1<<CGEN_OPERAND_RELAX)|(1<<CGEN_OPERAND_RELOC)|(1<<CGEN_OPERAND_PCREL_ADDR), pc, length); break; case M32R_OPERAND_DR : print_keyword (cd, info, & m32r_cgen_opval_gr_names, fields->f_r1, 0); break; case M32R_OPERAND_HASH : print_hash (cd, info, 0, 0|(1<<CGEN_OPERAND_SIGNED), pc, length); break; case M32R_OPERAND_HI16 : print_normal (cd, info, fields->f_hi16, 0|(1<<CGEN_OPERAND_SIGN_OPT), pc, length); break; case M32R_OPERAND_IMM1 : print_normal (cd, info, fields->f_imm1, 0|(1<<CGEN_OPERAND_HASH_PREFIX), pc, length); break; case M32R_OPERAND_SCR : print_keyword (cd, info, & m32r_cgen_opval_cr_names, fields->f_r2, 0); break; case M32R_OPERAND_SIMM16 : print_normal (cd, info, fields->f_simm16, 0|(1<<CGEN_OPERAND_SIGNED)|(1<<CGEN_OPERAND_HASH_PREFIX), pc, length); break; case M32R_OPERAND_SIMM8 : print_normal (cd, info, fields->f_simm8, 0|(1<<CGEN_OPERAND_SIGNED)|(1<<CGEN_OPERAND_HASH_PREFIX), pc, length); break; case M32R_OPERAND_SLO16 : print_normal (cd, info, fields->f_simm16, 0|(1<<CGEN_OPERAND_SIGNED), pc, length); break; case M32R_OPERAND_SR : print_keyword (cd, info, & m32r_cgen_opval_gr_names, fields->f_r2, 0); break; case M32R_OPERAND_SRC1 : print_keyword (cd, info, & m32r_cgen_opval_gr_names, fields->f_r1, 0); break; case M32R_OPERAND_SRC2 : print_keyword (cd, info, & m32r_cgen_opval_gr_names, fields->f_r2, 0); break; case M32R_OPERAND_UIMM16 : print_normal (cd, info, fields->f_uimm16, 0|(1<<CGEN_OPERAND_HASH_PREFIX), pc, length); break; case M32R_OPERAND_UIMM24 : print_address (cd, info, fields->f_uimm24, 0|(1<<CGEN_OPERAND_HASH_PREFIX)|(1<<CGEN_OPERAND_RELOC)|(1<<CGEN_OPERAND_ABS_ADDR), pc, length); break; case M32R_OPERAND_UIMM4 : print_normal (cd, info, fields->f_uimm4, 0|(1<<CGEN_OPERAND_HASH_PREFIX), pc, length); break; case M32R_OPERAND_UIMM5 : print_normal (cd, info, fields->f_uimm5, 0|(1<<CGEN_OPERAND_HASH_PREFIX), pc, length); break; case M32R_OPERAND_ULO16 : print_normal (cd, info, fields->f_uimm16, 0, pc, length); break; default : /* xgettext:c-format */ fprintf (stderr, _("Unrecognized field %d while printing insn.\n"), opindex); abort (); }}cgen_print_fn * const m32r_cgen_print_handlers[] = { print_insn_normal,};voidm32r_cgen_init_dis (cd) CGEN_CPU_DESC cd;{ m32r_cgen_init_opcode_table (cd); m32r_cgen_init_ibld_table (cd); cd->print_handlers = & m32r_cgen_print_handlers[0]; cd->print_operand = m32r_cgen_print_operand;}/* Default print handler. */static voidprint_normal (cd, dis_info, value, attrs, pc, length) CGEN_CPU_DESC cd ATTRIBUTE_UNUSED; PTR dis_info; long value; unsigned int attrs; bfd_vma pc ATTRIBUTE_UNUSED; int length ATTRIBUTE_UNUSED;{ disassemble_info *info = (disassemble_info *) dis_info;#ifdef CGEN_PRINT_NORMAL CGEN_PRINT_NORMAL (cd, info, value, attrs, pc, length);#endif /* Print the operand as directed by the attributes. */ if (CGEN_BOOL_ATTR (attrs, CGEN_OPERAND_SEM_ONLY)) ; /* nothing to do */ else if (CGEN_BOOL_ATTR (attrs, CGEN_OPERAND_SIGNED)) (*info->fprintf_func) (info->stream, "%ld", value); else (*info->fprintf_func) (info->stream, "0x%lx", value);}/* Default address handler. */static voidprint_address (cd, dis_info, value, attrs, pc, length) CGEN_CPU_DESC cd ATTRIBUTE_UNUSED; PTR dis_info; bfd_vma value; unsigned int attrs; bfd_vma pc ATTRIBUTE_UNUSED; int length ATTRIBUTE_UNUSED;{ disassemble_info *info = (disassemble_info *) dis_info;#ifdef CGEN_PRINT_ADDRESS CGEN_PRINT_ADDRESS (cd, info, value, attrs, pc, length);#endif /* Print the operand as directed by the attributes. */ if (CGEN_BOOL_ATTR (attrs, CGEN_OPERAND_SEM_ONLY)) ; /* nothing to do */ else if (CGEN_BOOL_ATTR (attrs, CGEN_OPERAND_PCREL_ADDR)) (*info->print_address_func) (value, info); else if (CGEN_BOOL_ATTR (attrs, CGEN_OPERAND_ABS_ADDR)) (*info->print_address_func) (value, info); else if (CGEN_BOOL_ATTR (attrs, CGEN_OPERAND_SIGNED)) (*info->fprintf_func) (info->stream, "%ld", (long) value); else (*info->fprintf_func) (info->stream, "0x%lx", (long) value);}/* Keyword print handler. */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -