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

📄 maverick.c

📁 这个是LINUX下的GDB调度工具的源码
💻 C
📖 第 1 页 / 共 2 页
字号:
/*  maverick.c -- Cirrus/DSP co-processor interface.    Copyright (C) 2003 Free Software Foundation, Inc.    Contributed by Aldy Hernandez (aldyh@redhat.com).     This program 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 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 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 this program; if not, write to the Free Software    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */#include <assert.h>#include "armdefs.h"#include "ansidecl.h"#include "armemu.h"/*#define CIRRUS_DEBUG 1	/**/#if CIRRUS_DEBUG#  define printfdbg printf#else#  define printfdbg printf_nothing#endif#define POS64(i) ( (~(i)) >> 63 )#define NEG64(i) ( (i) >> 63 )/* Define Co-Processor instruction handlers here.  *//* Here's ARMulator's DSP definition.  A few things to note:   1) it has 16 64-bit registers and 4 72-bit accumulators   2) you can only access its registers with MCR and MRC.  *//* We can't define these in here because this file might not be linked   unless the target is arm9e-*.  They are defined in wrapper.c.   Eventually the simulator should be made to handle any coprocessor   at run time.  */struct maverick_regs{  union  {    int i;    float f;  } upper;    union  {    int i;    float f;  } lower;};union maverick_acc_regs{  long double ld;		/* Acc registers are 72-bits.  */};struct maverick_regs DSPregs[16];union maverick_acc_regs DSPacc[4];ARMword DSPsc;#define DEST_REG	(BITS (12, 15))#define SRC1_REG	(BITS (16, 19))#define SRC2_REG	(BITS (0, 3))static int lsw_int_index, msw_int_index;static int lsw_float_index, msw_float_index;static double mv_getRegDouble (int);static long long mv_getReg64int (int);static void mv_setRegDouble (int, double val);static void mv_setReg64int (int, long long val);static union{  double d;  long long ll;  int ints[2];} reg_conv;static voidprintf_nothing (void * foo, ...){}static voidcirrus_not_implemented (char * insn){  fprintf (stderr, "Cirrus instruction '%s' not implemented.\n", insn);  fprintf (stderr, "aborting!\n");    exit (1);}static unsignedDSPInit (ARMul_State * state){  ARMul_ConsolePrint (state, ", DSP present");  return TRUE;}unsignedDSPMRC4 (ARMul_State * state ATTRIBUTE_UNUSED,	 unsigned      type  ATTRIBUTE_UNUSED,	 ARMword       instr,	 ARMword *     value){  switch (BITS (5, 7))    {    case 0: /* cfmvrdl */      /* Move lower half of a DF stored in a DSP reg into an Arm reg.  */      printfdbg ("cfmvrdl\n");      printfdbg ("\tlower half=0x%x\n", DSPregs[SRC1_REG].lower.i);      printfdbg ("\tentire thing=%g\n", mv_getRegDouble (SRC1_REG));            *value = (ARMword) DSPregs[SRC1_REG].lower.i;      break;          case 1: /* cfmvrdh */      /* Move upper half of a DF stored in a DSP reg into an Arm reg.  */      printfdbg ("cfmvrdh\n");      printfdbg ("\tupper half=0x%x\n", DSPregs[SRC1_REG].upper.i);      printfdbg ("\tentire thing=%g\n", mv_getRegDouble (SRC1_REG));            *value = (ARMword) DSPregs[SRC1_REG].upper.i;      break;          case 2: /* cfmvrs */      /* Move SF from upper half of a DSP register to an Arm register.  */      *value = (ARMword) DSPregs[SRC1_REG].upper.i;      printfdbg ("cfmvrs = mvf%d <-- %f\n",		 SRC1_REG,		 DSPregs[SRC1_REG].upper.f);      break;      #ifdef doesnt_work    case 4: /* cfcmps */      {	float a, b;	int n, z, c, v;	a = DSPregs[SRC1_REG].upper.f;	b = DSPregs[SRC2_REG].upper.f;	printfdbg ("cfcmps\n");	printfdbg ("\tcomparing %f and %f\n", a, b);	z = a == b;		/* zero */	n = a != b;		/* negative */	v = a > b;		/* overflow */	c = 0;			/* carry */	*value = (n << 31) | (z << 30) | (c << 29) | (v << 28);	break;      }          case 5: /* cfcmpd */      {	double a, b;	int n, z, c, v;	a = mv_getRegDouble (SRC1_REG);	b = mv_getRegDouble (SRC2_REG);	printfdbg ("cfcmpd\n");	printfdbg ("\tcomparing %g and %g\n", a, b);	z = a == b;		/* zero */	n = a != b;		/* negative */	v = a > b;		/* overflow */	c = 0;			/* carry */	*value = (n << 31) | (z << 30) | (c << 29) | (v << 28);	break;      }#else      case 4: /* cfcmps */        {	  float a, b;	  int n, z, c, v;	  a = DSPregs[SRC1_REG].upper.f;	  b = DSPregs[SRC2_REG].upper.f;  	  printfdbg ("cfcmps\n");	  printfdbg ("\tcomparing %f and %f\n", a, b);	  z = a == b;		/* zero */	  n = a < b;		/* negative */	  c = a > b;		/* carry */	  v = 0;		/* fixme */	  printfdbg ("\tz = %d, n = %d\n", z, n);	  *value = (n << 31) | (z << 30) | (c << 29) | (v << 28);	  break;        }	      case 5: /* cfcmpd */        {	  double a, b;	  int n, z, c, v;	  a = mv_getRegDouble (SRC1_REG);	  b = mv_getRegDouble (SRC2_REG);  	  printfdbg ("cfcmpd\n");	  printfdbg ("\tcomparing %g and %g\n", a, b);  	  z = a == b;		/* zero */	  n = a < b;		/* negative */	  c = a > b;		/* carry */	  v = 0;		/* fixme */	  *value = (n << 31) | (z << 30) | (c << 29) | (v << 28);	  break;        }#endif    default:      fprintf (stderr, "unknown opcode in DSPMRC4 0x%x\n", instr);      cirrus_not_implemented ("unknown");      break;    }  return ARMul_DONE;}unsignedDSPMRC5 (ARMul_State * state ATTRIBUTE_UNUSED,	 unsigned      type  ATTRIBUTE_UNUSED,	 ARMword       instr,	 ARMword *     value){  switch (BITS (5, 7))    {    case 0: /* cfmvr64l */      /* Move lower half of 64bit int from Cirrus to Arm.  */      *value = (ARMword) DSPregs[SRC1_REG].lower.i;      printfdbg ("cfmvr64l ARM_REG = mvfx%d <-- %d\n",		 DEST_REG,		 (int) *value);      break;          case 1: /* cfmvr64h */      /* Move upper half of 64bit int from Cirrus to Arm.  */      *value = (ARMword) DSPregs[SRC1_REG].upper.i;      printfdbg ("cfmvr64h <-- %d\n", (int) *value);      break;          case 4: /* cfcmp32 */      {	int res;	int n, z, c, v;	unsigned int a, b;	printfdbg ("cfcmp32 mvfx%d - mvfx%d\n",		   SRC1_REG,		   SRC2_REG);	/* FIXME: see comment for cfcmps.  */	a = DSPregs[SRC1_REG].lower.i;	b = DSPregs[SRC2_REG].lower.i;	res = DSPregs[SRC1_REG].lower.i - DSPregs[SRC2_REG].lower.i;	/* zero */	z = res == 0;	/* negative */	n = res < 0;	/* overflow */	v = SubOverflow (DSPregs[SRC1_REG].lower.i, DSPregs[SRC2_REG].lower.i,			 res);	/* carry */	c = (NEG (a) && POS (b) ||	     (NEG (a) && POS (res)) || (POS (b) && POS (res)));	*value = (n << 31) | (z << 30) | (c << 29) | (v << 28);	break;      }          case 5: /* cfcmp64 */      {	long long res;	int n, z, c, v;	unsigned long long a, b;	printfdbg ("cfcmp64 mvdx%d - mvdx%d\n",		   SRC1_REG,		   SRC2_REG);	/* fixme: see comment for cfcmps.  */	a = mv_getReg64int (SRC1_REG);	b = mv_getReg64int (SRC2_REG);	res = mv_getReg64int (SRC1_REG) - mv_getReg64int (SRC2_REG);	/* zero */	z = res == 0;	/* negative */	n = res < 0;	/* overflow */	v = ((NEG64 (a) && POS64 (b) && POS64 (res))	     || (POS64 (a) && NEG64 (b) && NEG64 (res)));	/* carry */	c = (NEG64 (a) && POS64 (b) ||	     (NEG64 (a) && POS64 (res)) || (POS64 (b) && POS64 (res)));	*value = (n << 31) | (z << 30) | (c << 29) | (v << 28);	break;      }          default:      fprintf (stderr, "unknown opcode in DSPMRC5 0x%x\n", instr);      cirrus_not_implemented ("unknown");      break;    }  return ARMul_DONE;}unsignedDSPMRC6 (ARMul_State * state ATTRIBUTE_UNUSED,	 unsigned      type  ATTRIBUTE_UNUSED,	 ARMword       instr,	 ARMword *     value){  switch (BITS (5, 7))    {    case 0: /* cfmval32 */      cirrus_not_implemented ("cfmval32");      break;          case 1: /* cfmvam32 */      cirrus_not_implemented ("cfmvam32");      break;          case 2: /* cfmvah32 */      cirrus_not_implemented ("cfmvah32");      break;          case 3: /* cfmva32 */      cirrus_not_implemented ("cfmva32");      break;          case 4: /* cfmva64 */      cirrus_not_implemented ("cfmva64");      break;          case 5: /* cfmvsc32 */      cirrus_not_implemented ("cfmvsc32");      break;          default:      fprintf (stderr, "unknown opcode in DSPMRC6 0x%x\n", instr);      cirrus_not_implemented ("unknown");      break;    }  return ARMul_DONE;}unsignedDSPMCR4 (ARMul_State * state,	 unsigned      type ATTRIBUTE_UNUSED,	 ARMword       instr,	 ARMword       value){  switch (BITS (5, 7))    {    case 0: /* cfmvdlr */      /* Move the lower half of a DF value from an Arm register into	 the lower half of a Cirrus register.  */      printfdbg ("cfmvdlr <-- 0x%x\n", (int) value);      DSPregs[SRC1_REG].lower.i = (int) value;      break;          case 1: /* cfmvdhr */      /* Move the upper half of a DF value from an Arm register into	 the upper half of a Cirrus register.  */      printfdbg ("cfmvdhr <-- 0x%x\n", (int) value);      DSPregs[SRC1_REG].upper.i = (int) value;      break;          case 2: /* cfmvsr */      /* Move SF from Arm register into upper half of Cirrus register.  */      printfdbg ("cfmvsr <-- 0x%x\n", (int) value);      DSPregs[SRC1_REG].upper.i = (int) value;      break;          default:      fprintf (stderr, "unknown opcode in DSPMCR4 0x%x\n", instr);      cirrus_not_implemented ("unknown");      break;    }  return ARMul_DONE;}unsignedDSPMCR5 (ARMul_State * state,	 unsigned      type   ATTRIBUTE_UNUSED,	 ARMword       instr,	 ARMword       value){  union  {    int s;    unsigned int us;  } val;  switch (BITS (5, 7))    {    case 0: /* cfmv64lr */      /* Move lower half of a 64bit int from an ARM register into the         lower half of a DSP register and sign extend it.  */      printfdbg ("cfmv64lr mvdx%d <-- 0x%x\n", SRC1_REG, (int) value);      DSPregs[SRC1_REG].lower.i = (int) value;      break;          case 1: /* cfmv64hr */      /* Move upper half of a 64bit int from an ARM register into the	 upper half of a DSP register.  */      printfdbg ("cfmv64hr ARM_REG = mvfx%d <-- 0x%x\n",		 SRC1_REG,		 (int) value);      DSPregs[SRC1_REG].upper.i = (int) value;      break;          case 2: /* cfrshl32 */      printfdbg ("cfrshl32\n");      val.us = value;      if (val.s > 0)	DSPregs[SRC2_REG].lower.i = DSPregs[SRC1_REG].lower.i << value;      else	DSPregs[SRC2_REG].lower.i = DSPregs[SRC1_REG].lower.i >> -value;      break;          case 3: /* cfrshl64 */      printfdbg ("cfrshl64\n");      val.us = value;      if (val.s > 0)	mv_setReg64int (SRC2_REG, mv_getReg64int (SRC1_REG) << value);      else	mv_setReg64int (SRC2_REG, mv_getReg64int (SRC1_REG) >> -value);      break;          default:      fprintf (stderr, "unknown opcode in DSPMCR5 0x%x\n", instr);      cirrus_not_implemented ("unknown");      break;    }  return ARMul_DONE;}unsignedDSPMCR6 (ARMul_State * state,	 unsigned      type   ATTRIBUTE_UNUSED,	 ARMword       instr,	 ARMword       value){  switch (BITS (5, 7))    {    case 0: /* cfmv32al */      cirrus_not_implemented ("cfmv32al");      break;          case 1: /* cfmv32am */      cirrus_not_implemented ("cfmv32am");      break;          case 2: /* cfmv32ah */      cirrus_not_implemented ("cfmv32ah");      break;          case 3: /* cfmv32a */      cirrus_not_implemented ("cfmv32a");      break;          case 4: /* cfmv64a */      cirrus_not_implemented ("cfmv64a");      break;          case 5: /* cfmv32sc */      cirrus_not_implemented ("cfmv32sc");      break;          default:      fprintf (stderr, "unknown opcode in DSPMCR6 0x%x\n", instr);      cirrus_not_implemented ("unknown");      break;    }  return ARMul_DONE;}unsignedDSPLDC4 (ARMul_State * state ATTRIBUTE_UNUSED,	 unsigned      type,	 ARMword       instr,	 ARMword       data){  static unsigned words;  if (type != ARMul_DATA)    {      words = 0;      return ARMul_DONE;    }    if (BIT (22))    {				/* it's a long access, get two words */      /* cfldrd */      printfdbg ("cfldrd: %x (words = %d) (bigend = %d) DESTREG = %d\n",		 data, words, state->bigendSig, DEST_REG);            if (words == 0)	{	  if (state->bigendSig)	    DSPregs[DEST_REG].upper.i = (int) data;	  else	    DSPregs[DEST_REG].lower.i = (int) data;	}      else	{	  if (state->bigendSig)	    DSPregs[DEST_REG].lower.i = (int) data;	  else	    DSPregs[DEST_REG].upper.i = (int) data;	}            ++ words;            if (words == 2)	{	  printfdbg ("\tmvd%d <-- mem = %g\n", DEST_REG,		     mv_getRegDouble (DEST_REG));	  	  return ARMul_DONE;	}      else	return ARMul_INC;    }  else    {      /* Get just one word.  */            /* cfldrs */      printfdbg ("cfldrs\n");      DSPregs[DEST_REG].upper.i = (int) data;      printfdbg ("\tmvf%d <-- mem = %f\n", DEST_REG,		 DSPregs[DEST_REG].upper.f);      return ARMul_DONE;    }}unsignedDSPLDC5 (ARMul_State * state ATTRIBUTE_UNUSED,	 unsigned      type,	 ARMword       instr,	 ARMword       data){  static unsigned words;  if (type != ARMul_DATA)    {      words = 0;      return ARMul_DONE;    }    if (BIT (22))    {      /* It's a long access, get two words.  */            /* cfldr64 */      printfdbg ("cfldr64: %d\n", data);      if (words == 0)	{	  if (state->bigendSig)	    DSPregs[DEST_REG].upper.i = (int) data;	  else	    DSPregs[DEST_REG].lower.i = (int) data;	}      else	{	  if (state->bigendSig)	    DSPregs[DEST_REG].lower.i = (int) data;	  else	    DSPregs[DEST_REG].upper.i = (int) data;	}            ++ words;            if (words == 2)	{	  printfdbg ("\tmvdx%d <-- mem = %lld\n", DEST_REG,		     mv_getReg64int (DEST_REG));	  	  return ARMul_DONE;	}      else	return ARMul_INC;    }  else    {      /* Get just one word.  */            /* cfldr32 */      printfdbg ("cfldr32 mvfx%d <-- %d\n", DEST_REG, (int) data);            /* 32bit ints should be sign extended to 64bits when loaded.  */      mv_setReg64int (DEST_REG, (long long) data);      return ARMul_DONE;    }}unsignedDSPSTC4 (ARMul_State * state ATTRIBUTE_UNUSED,	 unsigned      type,	 ARMword       instr,	 ARMword *     data){  static unsigned words;  if (type != ARMul_DATA)    {      words = 0;      return ARMul_DONE;    }    if (BIT (22))    {      /* It's a long access, get two words.  */      /* cfstrd */      printfdbg ("cfstrd\n");      if (words == 0)	{	  if (state->bigendSig)	    *data = (ARMword) DSPregs[DEST_REG].upper.i;

⌨️ 快捷键说明

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