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

📄 armsupp.c

📁 这个是LINUX下的GDB调度工具的源码
💻 C
📖 第 1 页 / 共 2 页
字号:
    {      CLEARN;      CLEARZ;    }}/* Compute whether an addition of A and B, giving RESULT, overflowed.  */intAddOverflow (ARMword a, ARMword b, ARMword result){  return ((NEG (a) && NEG (b) && POS (result))	  || (POS (a) && POS (b) && NEG (result)));}/* Compute whether a subtraction of A and B, giving RESULT, overflowed.  */intSubOverflow (ARMword a, ARMword b, ARMword result){  return ((NEG (a) && POS (b) && POS (result))	  || (POS (a) && NEG (b) && NEG (result)));}/* Assigns the C flag after an addition of a and b to give result.  */voidARMul_AddCarry (ARMul_State * state, ARMword a, ARMword b, ARMword result){  ASSIGNC ((NEG (a) && NEG (b)) ||	   (NEG (a) && POS (result)) || (NEG (b) && POS (result)));}/* Assigns the V flag after an addition of a and b to give result.  */voidARMul_AddOverflow (ARMul_State * state, ARMword a, ARMword b, ARMword result){  ASSIGNV (AddOverflow (a, b, result));}/* Assigns the C flag after an subtraction of a and b to give result.  */voidARMul_SubCarry (ARMul_State * state, ARMword a, ARMword b, ARMword result){  ASSIGNC ((NEG (a) && POS (b)) ||	   (NEG (a) && POS (result)) || (POS (b) && POS (result)));}/* Assigns the V flag after an subtraction of a and b to give result.  */voidARMul_SubOverflow (ARMul_State * state, ARMword a, ARMword b, ARMword result){  ASSIGNV (SubOverflow (a, b, result));}/* This function does the work of generating the addresses used in an   LDC instruction.  The code here is always post-indexed, it's up to the   caller to get the input address correct and to handle base register   modification. It also handles the Busy-Waiting.  */voidARMul_LDC (ARMul_State * state, ARMword instr, ARMword address){  unsigned cpab;  ARMword data;  UNDEF_LSCPCBaseWb;  if (! CP_ACCESS_ALLOWED (state, CPNum))    {      ARMul_UndefInstr (state, instr);      return;    }  if (ADDREXCEPT (address))    INTERNALABORT (address);  cpab = (state->LDC[CPNum]) (state, ARMul_FIRST, instr, 0);  while (cpab == ARMul_BUSY)    {      ARMul_Icycles (state, 1, 0);      if (IntPending (state))	{	  cpab = (state->LDC[CPNum]) (state, ARMul_INTERRUPT, instr, 0);	  return;	}      else	cpab = (state->LDC[CPNum]) (state, ARMul_BUSY, instr, 0);    }  if (cpab == ARMul_CANT)    {      CPTAKEABORT;      return;    }  cpab = (state->LDC[CPNum]) (state, ARMul_TRANSFER, instr, 0);  data = ARMul_LoadWordN (state, address);  BUSUSEDINCPCN;  if (BIT (21))    LSBase = state->Base;  cpab = (state->LDC[CPNum]) (state, ARMul_DATA, instr, data);  while (cpab == ARMul_INC)    {      address += 4;      data = ARMul_LoadWordN (state, address);      cpab = (state->LDC[CPNum]) (state, ARMul_DATA, instr, data);    }  if (state->abortSig || state->Aborted)    TAKEABORT;}/* This function does the work of generating the addresses used in an   STC instruction.  The code here is always post-indexed, it's up to the   caller to get the input address correct and to handle base register   modification. It also handles the Busy-Waiting.  */voidARMul_STC (ARMul_State * state, ARMword instr, ARMword address){  unsigned cpab;  ARMword data;  UNDEF_LSCPCBaseWb;  if (! CP_ACCESS_ALLOWED (state, CPNum))    {      ARMul_UndefInstr (state, instr);      return;    }  if (ADDREXCEPT (address) || VECTORACCESS (address))    INTERNALABORT (address);  cpab = (state->STC[CPNum]) (state, ARMul_FIRST, instr, &data);  while (cpab == ARMul_BUSY)    {      ARMul_Icycles (state, 1, 0);      if (IntPending (state))	{	  cpab = (state->STC[CPNum]) (state, ARMul_INTERRUPT, instr, 0);	  return;	}      else	cpab = (state->STC[CPNum]) (state, ARMul_BUSY, instr, &data);    }  if (cpab == ARMul_CANT)    {      CPTAKEABORT;      return;    }#ifndef MODE32  if (ADDREXCEPT (address) || VECTORACCESS (address))    INTERNALABORT (address);#endif  BUSUSEDINCPCN;  if (BIT (21))    LSBase = state->Base;  cpab = (state->STC[CPNum]) (state, ARMul_DATA, instr, &data);  ARMul_StoreWordN (state, address, data);  while (cpab == ARMul_INC)    {      address += 4;      cpab = (state->STC[CPNum]) (state, ARMul_DATA, instr, &data);      ARMul_StoreWordN (state, address, data);    }  if (state->abortSig || state->Aborted)    TAKEABORT;}/* This function does the Busy-Waiting for an MCR instruction.  */voidARMul_MCR (ARMul_State * state, ARMword instr, ARMword source){  unsigned cpab;  if (! CP_ACCESS_ALLOWED (state, CPNum))    {      ARMul_UndefInstr (state, instr);      return;    }  cpab = (state->MCR[CPNum]) (state, ARMul_FIRST, instr, source);  while (cpab == ARMul_BUSY)    {      ARMul_Icycles (state, 1, 0);      if (IntPending (state))	{	  cpab = (state->MCR[CPNum]) (state, ARMul_INTERRUPT, instr, 0);	  return;	}      else	cpab = (state->MCR[CPNum]) (state, ARMul_BUSY, instr, source);    }  if (cpab == ARMul_CANT)    ARMul_Abort (state, ARMul_UndefinedInstrV);  else    {      BUSUSEDINCPCN;      ARMul_Ccycles (state, 1, 0);    }}/* This function does the Busy-Waiting for an MRC instruction.  */ARMwordARMul_MRC (ARMul_State * state, ARMword instr){  unsigned cpab;  ARMword result = 0;  if (! CP_ACCESS_ALLOWED (state, CPNum))    {      ARMul_UndefInstr (state, instr);      return;    }  cpab = (state->MRC[CPNum]) (state, ARMul_FIRST, instr, &result);  while (cpab == ARMul_BUSY)    {      ARMul_Icycles (state, 1, 0);      if (IntPending (state))	{	  cpab = (state->MRC[CPNum]) (state, ARMul_INTERRUPT, instr, 0);	  return (0);	}      else	cpab = (state->MRC[CPNum]) (state, ARMul_BUSY, instr, &result);    }  if (cpab == ARMul_CANT)    {      ARMul_Abort (state, ARMul_UndefinedInstrV);      /* Parent will destroy the flags otherwise.  */      result = ECC;    }  else    {      BUSUSEDINCPCN;      ARMul_Ccycles (state, 1, 0);      ARMul_Icycles (state, 1, 0);    }  return result;}/* This function does the Busy-Waiting for an CDP instruction.  */voidARMul_CDP (ARMul_State * state, ARMword instr){  unsigned cpab;  if (! CP_ACCESS_ALLOWED (state, CPNum))    {      ARMul_UndefInstr (state, instr);      return;    }  cpab = (state->CDP[CPNum]) (state, ARMul_FIRST, instr);  while (cpab == ARMul_BUSY)    {      ARMul_Icycles (state, 1, 0);      if (IntPending (state))	{	  cpab = (state->CDP[CPNum]) (state, ARMul_INTERRUPT, instr);	  return;	}      else	cpab = (state->CDP[CPNum]) (state, ARMul_BUSY, instr);    }  if (cpab == ARMul_CANT)    ARMul_Abort (state, ARMul_UndefinedInstrV);  else    BUSUSEDN;}/* This function handles Undefined instructions, as CP isntruction.  */voidARMul_UndefInstr (ARMul_State * state, ARMword instr ATTRIBUTE_UNUSED){  ARMul_Abort (state, ARMul_UndefinedInstrV);}/* Return TRUE if an interrupt is pending, FALSE otherwise.  */unsignedIntPending (ARMul_State * state){  if (state->Exception)    {      /* Any exceptions.  */      if (state->NresetSig == LOW)	{	  ARMul_Abort (state, ARMul_ResetV);	  return TRUE;	}      else if (!state->NfiqSig && !FFLAG)	{	  ARMul_Abort (state, ARMul_FIQV);	  return TRUE;	}      else if (!state->NirqSig && !IFLAG)	{	  ARMul_Abort (state, ARMul_IRQV);	  return TRUE;	}    }  return FALSE;}/* Align a word access to a non word boundary.  */ARMwordARMul_Align (state, address, data)     ARMul_State * state ATTRIBUTE_UNUSED;     ARMword address;     ARMword data;{  /* This code assumes the address is really unaligned,     as a shift by 32 is undefined in C.  */  address = (address & 3) << 3;	/* Get the word address.  */  return ((data >> address) | (data << (32 - address)));	/* rot right */}/* This routine is used to call another routine after a certain number of   cycles have been executed. The first parameter is the number of cycles   delay before the function is called, the second argument is a pointer   to the function. A delay of zero doesn't work, just call the function.  */voidARMul_ScheduleEvent (ARMul_State * state, unsigned long delay,		     unsigned (*what) (ARMul_State *)){  unsigned long when;  struct EventNode *event;  if (state->EventSet++ == 0)    state->Now = ARMul_Time (state);  when = (state->Now + delay) % EVENTLISTSIZE;  event = (struct EventNode *) malloc (sizeof (struct EventNode));  event->func = what;  event->next = *(state->EventPtr + when);  *(state->EventPtr + when) = event;}/* This routine is called at the beginning of   every cycle, to envoke scheduled events.  */voidARMul_EnvokeEvent (ARMul_State * state){  static unsigned long then;  then = state->Now;  state->Now = ARMul_Time (state) % EVENTLISTSIZE;  if (then < state->Now)    /* Schedule events.  */    EnvokeList (state, then, state->Now);  else if (then > state->Now)    {      /* Need to wrap around the list.  */      EnvokeList (state, then, EVENTLISTSIZE - 1L);      EnvokeList (state, 0L, state->Now);    }}/* Envokes all the entries in a range.  */static voidEnvokeList (ARMul_State * state, unsigned long from, unsigned long to){  for (; from <= to; from++)    {      struct EventNode *anevent;      anevent = *(state->EventPtr + from);      while (anevent)	{	  (anevent->func) (state);	  state->EventSet--;	  anevent = anevent->next;	}      *(state->EventPtr + from) = NULL;    }}/* This routine is returns the number of clock ticks since the last reset.  */unsigned longARMul_Time (ARMul_State * state){  return (state->NumScycles + state->NumNcycles +	  state->NumIcycles + state->NumCcycles + state->NumFcycles);}

⌨️ 快捷键说明

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