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

📄 convex-pinsn.c

📁 早期freebsd实现
💻 C
字号:
/* Print Convex instructions for GDB, the GNU debugger.   Copyright 1989, 1991 Free Software Foundation, Inc.This file is part of GDB.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 of the License, 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 SoftwareFoundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */#include "defs.h"#include "symtab.h"/* reg (fmt_field, inst_field) --   the {first,second,third} operand of instruction as fmt_field = [ijk]   gets the value of the field from the [ijk] position of the instruction */#define reg(a,b) ((char (*)[3])(op[fmt->a]))[inst.f0.b]/* lit (fmt_field) -- field [ijk] is a literal (PSW, VL, eg) */#define lit(i) op[fmt->i]/* aj[j] -- name for A register j */#define aj ((char (*)[3])(op[A]))union inst {    struct {	unsigned   : 7;	unsigned i : 3;	unsigned j : 3;	unsigned k : 3;	unsigned   : 16;	unsigned   : 32;    } f0;    struct {	unsigned   : 8;	unsigned indir : 1;	unsigned len : 1;	unsigned j : 3;	unsigned k : 3;	unsigned   : 16;	unsigned   : 32;    } f1;    unsigned char byte[8];    unsigned short half[4];    char signed_byte[8];    short signed_half[4];};struct opform {    int mask;			/* opcode mask */    int shift;			/* opcode align */    struct formstr *formstr[3];	/* ST, E0, E1 */};struct formstr {    unsigned lop:8, rop:5;	/* opcode */    unsigned fmt:5;		/* inst format */    unsigned i:5, j:5, k:2;	/* operand formats */};#include "convx-opcode.h"unsigned char formdecode [] = {    1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,    9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,    1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,    1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,    2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,    2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,    3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,    4,4,4,4,4,4,4,4,5,5,5,5,6,6,7,8,    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,};struct opform opdecode[] = {    0x7e00, 9, format0, e0_format0, e1_format0,    0x3f00, 8, format1, e0_format1, e1_format1,    0x1fc0, 6, format2, e0_format2, e1_format2,    0x0fc0, 6, format3, e0_format3, e1_format3,    0x0700, 8, format4, e0_format4, e1_format4,    0x03c0, 6, format5, e0_format5, e1_format5,    0x01f8, 3, format6, e0_format6, e1_format6,    0x00f8, 3, format7, e0_format7, e1_format7,    0x0000, 0, formatx, formatx, formatx,    0x0f80, 7, formatx, formatx, formatx,    0x0f80, 7, formatx, formatx, formatx,};/* Print the instruction at address MEMADDR in debugged memory,   on STREAM.  Returns length of the instruction, in bytes.  */intprint_insn (memaddr, stream)     CORE_ADDR memaddr;     FILE *stream;{  union inst inst;  struct formstr *fmt;  register int format, op1, pfx;  int l;  read_memory (memaddr, &inst, sizeof inst);  /* Remove and note prefix, if present */      pfx = inst.half[0];  if ((pfx & 0xfff0) == 0x7ef0)    {      pfx = ((pfx >> 3) & 1) + 1;      *(long long *) &inst = *(long long *) &inst.half[1];    }  else pfx = 0;  /* Split opcode into format.op1 and look up in appropriate table */  format = formdecode[inst.byte[0]];  op1 = (inst.half[0] & opdecode[format].mask) >> opdecode[format].shift;  if (format == 9)    {      if (pfx)	fmt = formatx;      else if (inst.f1.j == 0)	fmt = &format1a[op1];      else if (inst.f1.j == 1)	fmt = &format1b[op1];      else	fmt = formatx;    }  else    fmt = &opdecode[format].formstr[pfx][op1];  /* Print it */  if (fmt->fmt == xxx)    {      /* noninstruction */      fprintf (stream, "0x%04x", pfx ? pfx : inst.half[0]);      return 2;    }  if (pfx)    pfx = 2;  fprintf (stream, "%s%s%s", lop[fmt->lop], rop[fmt->rop],	   &"        "[strlen(lop[fmt->lop]) + strlen(rop[fmt->rop])]);  switch (fmt->fmt)    {    case rrr:			/* three register */      fprintf (stream, "%s,%s,%s", reg(i,i), reg(j,j), reg(k,k));      return pfx + 2;    case rr:			/* two register */      fprintf (stream, "%s,%s", reg(i,j), reg(j,k));      return pfx + 2;    case rxr:			/* two register, reversed i and j fields */      fprintf (stream, "%s,%s", reg(i,k), reg(j,j));      return pfx + 2;    case r:			/* one register */      fprintf (stream, "%s", reg(i,k));      return pfx + 2;    case nops:			/* no operands */      return pfx + 2;    case nr:			/* short immediate, one register */      fprintf (stream, "#%d,%s", inst.f0.j, reg(i,k));      return pfx + 2;    case pcrel:			/* pc relative */      print_address (memaddr + 2 * inst.signed_byte[1], stream);      return pfx + 2;    case lr:			/* literal, one register */      fprintf (stream, "%s,%s", lit(i), reg(j,k));      return pfx + 2;    case rxl:			/* one register, literal */      fprintf (stream, "%s,%s", reg(i,k), lit(j));      return pfx + 2;    case rlr:			/* register, literal, register */      fprintf (stream, "%s,%s,%s", reg(i,j), lit(j), reg(k,k));      return pfx + 2;    case rrl:			/* register, register, literal */      fprintf (stream, "%s,%s,%s", reg(i,j), reg(j,k), lit(k));      return pfx + 2;    case iml:			/* immediate, literal */      if (inst.f1.len)	{	  fprintf (stream, "#%#x,%s",		   (inst.signed_half[1] << 16) + inst.half[2], lit(i));	  return pfx + 6;	}      else	{	  fprintf (stream, "#%d,%s", inst.signed_half[1], lit(i));	  return pfx + 4;	}    case imr:			/* immediate, register */      if (inst.f1.len)	{	  fprintf (stream, "#%#x,%s",		   (inst.signed_half[1] << 16) + inst.half[2], reg(i,k));	  return pfx + 6;	}      else	{	  fprintf (stream, "#%d,%s", inst.signed_half[1], reg(i,k));	  return pfx + 4;	}    case a1r:			/* memory, register */      l = print_effa (inst, stream);      fprintf (stream, ",%s", reg(i,k));      return pfx + l;    case a1l:			/* memory, literal  */      l = print_effa (inst, stream);      fprintf (stream, ",%s", lit(i));      return pfx + l;    case a2r:			/* register, memory */      fprintf (stream, "%s,", reg(i,k));      return pfx + print_effa (inst, stream);    case a2l:			/* literal, memory */      fprintf (stream, "%s,", lit(i));      return pfx + print_effa (inst, stream);    case a3:			/* memory */      return pfx + print_effa (inst, stream);    case a4:			/* system call */      l = 29; goto a4a5;    case a5:			/* trap */      l = 27;    a4a5:      if (inst.f1.len)	{	  unsigned int m = (inst.signed_half[1] << 16) + inst.half[2];	  fprintf (stream, "#%d,#%d", m >> l, m & (-1 >> (32-l)));	  return pfx + 6;	}      else	{	  unsigned int m = inst.signed_half[1];	  fprintf (stream, "#%d,#%d", m >> l, m & (-1 >> (32-l)));	  return pfx + 4;	}    }}/* print effective address @nnn(aj), return instruction length */int print_effa (inst, stream)     union inst inst;     FILE *stream;{  int n, l;  if (inst.f1.len)    {      n = (inst.signed_half[1] << 16) + inst.half[2];      l = 6;    }  else    {      n = inst.signed_half[1];      l = 4;    }	  if (inst.f1.indir)    printf ("@");  if (!inst.f1.j)    {      print_address (n, stream);      return l;    }  fprintf (stream, (n & 0xf0000000) == 0x80000000 ? "%#x(%s)" : "%d(%s)",	   n, aj[inst.f1.j]);  return l;}

⌨️ 快捷键说明

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