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

📄 libgcc2.c

📁 GCC编译器源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
/* Like bcmp except the sign is meaningful.   Result is negative if S1 is less than S2,   positive if S1 is greater, 0 if S1 and S2 are equal.  */int__gcc_bcmp (unsigned char *s1, unsigned char *s2, size_t size){  while (size > 0)    {      unsigned char c1 = *s1++, c2 = *s2++;      if (c1 != c2)	return c1 - c2;      size--;    }  return 0;}#endif#ifdef L__dummyvoid__dummy () {}#endif#ifdef L_varargs#ifdef __i860__#if defined(__svr4__) || defined(__alliant__)	asm ("	.text");	asm ("	.align	4");/* The Alliant needs the added underscore.  */	asm (".globl	__builtin_saveregs");asm ("__builtin_saveregs:");	asm (".globl	___builtin_saveregs");asm ("___builtin_saveregs:");        asm ("	andnot	0x0f,%sp,%sp");	/* round down to 16-byte boundary */	asm ("	adds	-96,%sp,%sp");  /* allocate stack space for reg save					   area and also for a new va_list					   structure */	/* Save all argument registers in the arg reg save area.  The	   arg reg save area must have the following layout (according	   to the svr4 ABI):		struct {		  union  {		    float freg[8];		    double dreg[4];		  } float_regs;		  long	ireg[12];		};	*/	asm ("	fst.q	%f8,  0(%sp)"); /* save floating regs (f8-f15)  */	asm ("	fst.q	%f12,16(%sp)"); 	asm ("	st.l	%r16,32(%sp)"); /* save integer regs (r16-r27) */	asm ("	st.l	%r17,36(%sp)"); 	asm ("	st.l	%r18,40(%sp)");	asm ("	st.l	%r19,44(%sp)");	asm ("	st.l	%r20,48(%sp)");	asm ("	st.l	%r21,52(%sp)");	asm ("	st.l	%r22,56(%sp)");	asm ("	st.l	%r23,60(%sp)");	asm ("	st.l	%r24,64(%sp)");	asm ("	st.l	%r25,68(%sp)");	asm ("	st.l	%r26,72(%sp)");	asm ("	st.l	%r27,76(%sp)");	asm ("	adds	80,%sp,%r16");  /* compute the address of the new					   va_list structure.  Put in into					   r16 so that it will be returned					   to the caller.  */	/* Initialize all fields of the new va_list structure.  This	   structure looks like:		typedef struct {		    unsigned long	ireg_used;		    unsigned long	freg_used;		    long		*reg_base;		    long		*mem_ptr;		} va_list;	*/	asm ("	st.l	%r0, 0(%r16)"); /* nfixed */	asm ("	st.l	%r0, 4(%r16)"); /* nfloating */	asm ("  st.l    %sp, 8(%r16)"); /* __va_ctl points to __va_struct.  */	asm ("	bri	%r1");		/* delayed return */	asm ("	st.l	%r28,12(%r16)"); /* pointer to overflow args */#else /* not __svr4__ */#if defined(__PARAGON__)	/*	 *	we'll use SVR4-ish varargs but need SVR3.2 assembler syntax,	 *	and we stand a better chance of hooking into libraries	 *	compiled by PGI.  [andyp@ssd.intel.com]	 */	asm ("	.text");	asm ("	.align	4");	asm (".globl	__builtin_saveregs");asm ("__builtin_saveregs:");	asm (".globl	___builtin_saveregs");asm ("___builtin_saveregs:");        asm ("	andnot	0x0f,sp,sp");	/* round down to 16-byte boundary */	asm ("	adds	-96,sp,sp");	/* allocate stack space for reg save					   area and also for a new va_list					   structure */	/* Save all argument registers in the arg reg save area.  The	   arg reg save area must have the following layout (according	   to the svr4 ABI):		struct {		  union  {		    float freg[8];		    double dreg[4];		  } float_regs;		  long	ireg[12];		};	*/	asm ("	fst.q	f8,  0(sp)");	asm ("	fst.q	f12,16(sp)"); 	asm ("	st.l	r16,32(sp)");	asm ("	st.l	r17,36(sp)"); 	asm ("	st.l	r18,40(sp)");	asm ("	st.l	r19,44(sp)");	asm ("	st.l	r20,48(sp)");	asm ("	st.l	r21,52(sp)");	asm ("	st.l	r22,56(sp)");	asm ("	st.l	r23,60(sp)");	asm ("	st.l	r24,64(sp)");	asm ("	st.l	r25,68(sp)");	asm ("	st.l	r26,72(sp)");	asm ("	st.l	r27,76(sp)");	asm ("	adds	80,sp,r16");  /* compute the address of the new					   va_list structure.  Put in into					   r16 so that it will be returned					   to the caller.  */	/* Initialize all fields of the new va_list structure.  This	   structure looks like:		typedef struct {		    unsigned long	ireg_used;		    unsigned long	freg_used;		    long		*reg_base;		    long		*mem_ptr;		} va_list;	*/	asm ("	st.l	r0, 0(r16)"); /* nfixed */	asm ("	st.l	r0, 4(r16)"); /* nfloating */	asm ("  st.l    sp, 8(r16)"); /* __va_ctl points to __va_struct.  */	asm ("	bri	r1");		/* delayed return */	asm ("	 st.l	r28,12(r16)"); /* pointer to overflow args */#else /* not __PARAGON__ */	asm ("	.text");	asm ("	.align	4");	asm (".globl	___builtin_saveregs");	asm ("___builtin_saveregs:");	asm ("	mov	sp,r30");	asm ("	andnot	0x0f,sp,sp");	asm ("	adds	-96,sp,sp");  /* allocate sufficient space on the stack *//* Fill in the __va_struct.  */	asm ("	st.l	r16, 0(sp)"); /* save integer regs (r16-r27) */	asm ("	st.l	r17, 4(sp)"); /* int	fixed[12] */	asm ("	st.l	r18, 8(sp)");	asm ("	st.l	r19,12(sp)");	asm ("	st.l	r20,16(sp)");	asm ("	st.l	r21,20(sp)");	asm ("	st.l	r22,24(sp)");	asm ("	st.l	r23,28(sp)");	asm ("	st.l	r24,32(sp)");	asm ("	st.l	r25,36(sp)");	asm ("	st.l	r26,40(sp)");	asm ("	st.l	r27,44(sp)");	asm ("	fst.q	f8, 48(sp)"); /* save floating regs (f8-f15) */	asm ("	fst.q	f12,64(sp)"); /* int floating[8] *//* Fill in the __va_ctl.  */	asm ("  st.l    sp, 80(sp)"); /* __va_ctl points to __va_struct.  */	asm ("	st.l	r28,84(sp)"); /* pointer to more args */	asm ("	st.l	r0, 88(sp)"); /* nfixed */	asm ("	st.l	r0, 92(sp)"); /* nfloating */	asm ("	adds	80,sp,r16");  /* return address of the __va_ctl.  */	asm ("	bri	r1");	asm ("	mov	r30,sp");				/* recover stack and pass address to start 				   of data.  */#endif /* not __PARAGON__ */#endif /* not __svr4__ */#else /* not __i860__ */#ifdef __sparc__	asm (".global __builtin_saveregs");	asm ("__builtin_saveregs:");	asm (".global ___builtin_saveregs");	asm ("___builtin_saveregs:");#ifdef NEED_PROC_COMMAND	asm (".proc 020");#endif	asm ("st %i0,[%fp+68]");	asm ("st %i1,[%fp+72]");	asm ("st %i2,[%fp+76]");	asm ("st %i3,[%fp+80]");	asm ("st %i4,[%fp+84]");	asm ("retl");	asm ("st %i5,[%fp+88]");#ifdef NEED_TYPE_COMMAND	asm (".type __builtin_saveregs,#function");	asm (".size __builtin_saveregs,.-__builtin_saveregs");#endif#else /* not __sparc__ */#if defined(__MIPSEL__) | defined(__R3000__) | defined(__R2000__) | defined(__mips__)  asm ("	.text");  asm ("	.ent __builtin_saveregs");  asm ("	.globl __builtin_saveregs");  asm ("__builtin_saveregs:");  asm ("	sw	$4,0($30)");  asm ("	sw	$5,4($30)");  asm ("	sw	$6,8($30)");  asm ("	sw	$7,12($30)");  asm ("	j	$31");  asm ("	.end __builtin_saveregs");#else /* not __mips__, etc.  */void *__builtin_saveregs (){  abort ();}#endif /* not __mips__ */#endif /* not __sparc__ */#endif /* not __i860__ */#endif#ifdef L_eprintf#ifndef inhibit_libc#undef NULL /* Avoid errors if stdio.h and our stddef.h mismatch.  */#include <stdio.h>/* This is used by the `assert' macro.  */void__eprintf (const char *string, const char *expression,	   int line, const char *filename){  fprintf (stderr, string, expression, line, filename);  fflush (stderr);  abort ();}#endif#endif#ifdef L_bb/* Structure emitted by -a  */struct bb{  long zero_word;  const char *filename;  long *counts;  long ncounts;  struct bb *next;  const unsigned long *addresses;  /* Older GCC's did not emit these fields.  */  long nwords;  const char **functions;  const long *line_nums;  const char **filenames;  char *flags;};#ifdef BLOCK_PROFILER_CODEBLOCK_PROFILER_CODE#else#ifndef inhibit_libc/* Simple minded basic block profiling output dumper for   systems that don't provide tcov support.  At present,   it requires atexit and stdio.  */#undef NULL /* Avoid errors if stdio.h and our stddef.h mismatch.  */#include <stdio.h>char *ctime ();#include "gbl-ctors.h"#include "gcov-io.h"static struct bb *bb_head;/* Return the number of digits needed to print a value *//* __inline__ */ static int num_digits (long value, int base){  int minus = (value < 0 && base != 16);  unsigned long v = (minus) ? -value : value;  int ret = minus;  do    {      v /= base;      ret++;    }  while (v);  return ret;}void__bb_exit_func (void){  FILE *da_file, *file;  long time_value;  int i;  if (bb_head == 0)    return;  i = strlen (bb_head->filename) - 3;  if (!strcmp (bb_head->filename+i, ".da"))    {      /* Must be -fprofile-arcs not -a.	 Dump data in a form that gcov expects.  */      struct bb *ptr;      for (ptr = bb_head; ptr != (struct bb *) 0; ptr = ptr->next)	{	  /* If the file exists, and the number of counts in it is the same,	     then merge them in.  */	     	  if ((da_file = fopen (ptr->filename, "r")) != 0)	    {	      long n_counts = 0;	      unsigned char tmp;	      int i;	      int ret = 0;	      	      if (__read_long (&n_counts, da_file, 8) != 0)		{		  fprintf (stderr, "arc profiling: Can't read output file %s.\n",			   ptr->filename);		  continue;		}	      if (n_counts == ptr->ncounts)		{		  int i;		  for (i = 0; i < n_counts; i++)		    {		      long v = 0;		      unsigned char tmp;		      int j;		      int ret = 0;		      if (__read_long (&v, da_file, 8) != 0)			{			  fprintf (stderr, "arc profiling: Can't read output file %s.\n",				   ptr->filename);			  break;			}		      ptr->counts[i] += v;		    }		}	      if (fclose (da_file) == EOF)		fprintf (stderr, "arc profiling: Error closing output file %s.\n",			 ptr->filename);	    }	  if ((da_file = fopen (ptr->filename, "w")) == 0)	    {	      fprintf (stderr, "arc profiling: Can't open output file %s.\n",		       ptr->filename);	      continue;	    }	  /* ??? Should first write a header to the file.  Preferably, a 4 byte	     magic number, 4 bytes containing the time the program was	     compiled, 4 bytes containing the last modification time of the	     source file, and 4 bytes indicating the compiler options used.	     That way we can easily verify that the proper source/executable/	     data file combination is being used from gcov.  */	  if (__write_long (ptr->ncounts, da_file, 8) != 0)	    {	      	      fprintf (stderr, "arc profiling: Error writing output file %s.\n",		       ptr->filename);	    }	  else	    {	      int j;	      long *count_ptr = ptr->counts;	      int ret = 0;	      for (j = ptr->ncounts; j > 0; j--)		{		  if (__write_long (*count_ptr, da_file, 8) != 0)		    {		      ret=1;		      break;		    }		  count_ptr++;		}	      if (ret)		fprintf (stderr, "arc profiling: Error writing output file %s.\n",			 ptr->filename);	    }	  	  if (fclose (da_file) == EOF)	    fprintf (stderr, "arc profiling: Error closing output file %s.\n",		     ptr->filename);	}      return;    }  /* Must be basic block profiling.  Emit a human readable output file.  */  file = fopen ("bb.out", "a");  if (!file)    perror ("bb.out");  else    {      struct bb *ptr;      /* This is somewhat type incorrect, but it avoids worrying about	 exactly where time.h is included from.  It should be ok unless	 a void * differs from other pointer formats, or if sizeof (long)	 is < sizeof (time_t).  It would be nice if we could assume the	 use of rationale standards here.  */      time ((void *) &time_value);      fprintf (file, "Basic block profiling finished on %s\n", ctime ((void *) &time_value));      /* We check the length field explicitly in order to allow compatibility	 with older GCC's which did not provide it.  */      for (ptr = bb_head; ptr != (struct bb *) 0; ptr = ptr->next)	{	  int i;	  int func_p	= (ptr->nwords >= sizeof (struct bb)			   && ptr->nwords <= 1000			   && ptr->functions);	  int line_p	= (func_p && ptr->line_nums);	  int file_p	= (func_p && ptr->filenames);	  int addr_p	= (ptr->addresses != 0);	  long ncounts	= ptr->ncounts;	  long cnt_max  = 0;	  long line_max = 0;	  long addr_max = 0;	  int file_len	= 0;	  int func_len	= 0;	  int blk_len	= num_digits (ncounts, 10);	  int cnt_len;	  int line_len;	  int addr_len;	  fprintf (file, "File %s, %ld basic blocks \n\n",		   ptr->filename, ncounts);	  /* Get max values for each field.  */	  for (i = 0; i < ncounts; i++)	    {	      const char *p;	      int len;	      if (cnt_max < ptr->counts[i])		cnt_max = ptr->counts[i];	      if (addr_p && addr_max < ptr->addresses[i])		addr_max = ptr->addresses[i];	      if (line_p && line_max < ptr->line_nums[i])		line_max = ptr->line_nums[i];	      if (func_p)		{		  p = (ptr->functions[i]) ? (ptr->functions[i]) : "<none>";		  len = strlen (p);		  if (func_len < len)		    func_len = len;		}	      if (file_p)		{		  p = (ptr->filenames[i]) ? (ptr->filenames[i]) : "<none>";		  len = strlen (p);		  if (file_len < len)		    file_len = len;		}	    }	  addr_len = num_digits (addr_max, 16);	  cnt_len  = num_digits (cnt_max, 10);	  line_len = num_digits (line_max, 10);	  /* Now print out the basic block information.  */	  for (i = 0; i < ncounts; i++)	    {	      fprintf (file,		       "    Block #%*d: executed %*ld time(s)",		       blk_len, i+1,		       cnt_len, ptr->counts[i]);	      if (addr_p)		fprintf (file, " address= 0x%.*lx", addr_len,			 ptr->addresses[i]);	      if (func_p)		fprintf (file, " function= %-*s", func_len,			 (ptr->functions[i]) ? ptr->functions[i] : "<none>");	      if (line_p)		fprintf (file, " line= %*ld", line_len, ptr->line_nums[i]);	      if (file_p)		fprintf (file, " file= %s",			 (ptr->filenames[i]) ? ptr->filenames[i] : "<none>");	      fprintf (file, "\n");	    }	  fprintf (file, "\n");	  fflush (file);	}      fprintf (file, "\n\n");      fclose (file);    }}void__bb_init_func (struct bb *blocks){  /* User is supposed to check whether the first word is non-0,     but just in case....  */  if (blocks->zero_word)    return;#ifdef ON_EXIT  /* Initialize destructor.  */  if (!bb_head)    ON_EXIT (__bb_exit_func, 0);#endif  /* Set up linked list.  */  blocks->zero_word = 1;  blocks->next = bb_head;  bb_head = blocks;}#ifndef MACHINE_STATE_SAVE#define MACHINE_STATE_SAVE(ID)#endif#ifndef MACHINE_STATE_RESTORE#define MACHINE_STATE_RESTORE(ID)#endif

⌨️ 快捷键说明

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