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

📄 libgcc2.c

📁 C++ 编写的EROS RTOS
💻 C
📖 第 1 页 / 共 4 页
字号:
	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 (string, expression, line, filename)     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;};#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 ();#ifdef HAVE_ATEXIT#ifdef WINNTextern int atexit (void (*) (void));#elseextern void atexit (void (*) (void));#endif#define ON_EXIT(FUNC,ARG) atexit ((FUNC))#else#ifdef sunextern void on_exit (void*, void*);#define ON_EXIT(FUNC,ARG) on_exit ((FUNC), (ARG))#endif#endifstatic 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 *file = fopen ("bb.out", "a");  long time_value;  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);	  int line_p	= (func_p && ptr->line_nums);	  int file_p	= (func_p && ptr->filenames);	  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_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) address= 0x%.*lx",		       blk_len, i+1,		       cnt_len, ptr->counts[i],		       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;}#endif /* not inhibit_libc */#endif /* not BLOCK_PROFILER_CODE */#endif /* L_bb *//* Default free-store management functions for C++, per sections 12.5 and   17.3.3 of the Working Paper. */#ifdef L_op_new/* operator new (size_t), described in 17.3.3.5.  This function is used by   C++ programs to allocate a block of memory to hold a single object. */typedef void (*vfp)(void);extern vfp __new_handler;extern void __default_new_handler (void);#ifdef WEAK_ALIASvoid * __builtin_new (size_t sz)     __attribute__ ((weak, alias ("___builtin_new")));void *___builtin_new (size_t sz)#elsevoid *__builtin_new (size_t sz)#endif{  void *p;  vfp handler = (__new_handler) ? __new_handler : __default_new_handler;  /* malloc (0) is unpredictable; avoid it.  */  if (sz == 0)    sz = 1;  p = (void *) malloc (sz);  while (p == 0)    {      (*handler) ();      p = (void *) malloc (sz);    }    return p;}#endif /* L_op_new */#ifdef L_op_vnew/* void * operator new [] (size_t), described in 17.3.3.6.  This function   is used by C++ programs to allocate a block of memory for an array.  */extern void * __builtin_new (size_t);#ifdef WEAK_ALIASvoid * __builtin_vec_new (size_t sz)     __attribute__ ((weak, alias ("___builtin_vec_new")));void *___builtin_vec_new (size_t sz)#elsevoid *__builtin_vec_new (size_t sz)#endif{  return __builtin_new (sz);}#endif /* L_op_vnew */#ifdef L_new_handler/* set_new_handler (fvoid_t *) and the default new handler, described in   17.3.3.2 and 17.3.3.5.  These functions define the result of a failure   to allocate the amount of memory requested from operator new or new []. */#ifndef inhibit_libc/* This gets us __GNU_LIBRARY__.  */#undef NULL /* Avoid errors if stdio.h and our stddef.h mismatch.  */#include <stdio.h>#ifdef __GNU_LIBRARY__  /* Avoid forcing the library's meaning of `write' on the user program     by using the "internal" name (for use within the library)  */#define write(fd, buf, n)	__write((fd), (buf), (n))#endif#endif /* inhibit_libc */typedef void (*vfp)(void);void __default_new_handler (void);vfp __new_handler = (vfp)0;vfpset_new_handler (vfp handler){  vfp prev_handler;  prev_handler = __new_handler;  if (handler == 0) handler = __default_new_handler;  __new_handler = handler;  return prev_handler;}#define MESSAGE "Virtual memory exceeded in `new'\n"void__default_new_handler (){#ifndef inhibit_libc  /* don't use fprintf (stderr, ...) because it may need to call malloc.  */  /* This should really print the name of the program, but that is hard to     do.  We need a standard, clean way to get at the name.  */  write (2, MESSAGE, sizeof (MESSAGE));#endif  /* don't call exit () because that may call global destructors which     may cause a loop.  */  _exit (-1);}#endif#ifdef L_op_delete/* operator delete (void *), described in 17.3.3.3.  This function is used   by C++ programs to return to the free store a block of memory allocated   as a single object. */#ifdef WEAK_ALIASvoid __builtin_delete (void *ptr)     __attribute__ ((weak, alias ("___builtin_delete")));void___builtin_delete (void *ptr)#elsevoid__builtin_delete (void *ptr)#endif{  if (ptr)    free (ptr);}#endif#ifdef L_op_vdel/* operator delete [] (void *), described in 17.3.3.4.  This function is   used by C++ programs to return to the free store a block of memory   allocated as an array. */extern void __builtin_delete (void *);#ifdef WEAK_ALIASvoid __builtin_vec_delete (void *ptr)     __attribute__ ((weak, alias ("___builtin_vec_delete")));void___builtin_vec_delete (void *ptr)#elsevoid__builtin_vec_delete (void *ptr)#endif{  __builtin_delete (ptr);}#endif/* End of C++ free-store management functions */#ifdef L_shtabunsigned int __shtab[] = {    0x00000001, 0x00000002, 0x00000004, 0x00000008,    0x00000010, 0x00000020, 0x00000040, 0x00000080,    0x00000100, 0x00000200, 0x00000400, 0x00000800,    0x00001000, 0x00002000, 0x00004000, 0x00008000,    0x00010000, 0x00020000, 0x00040000, 0x00080000,    0x00100000, 0x00200000, 0x00400000, 0x00800000,    0x01000000, 0x02000000, 0x04000000, 0x08000000,    0x10000000, 0x20000000, 0x40000000, 0x80000000  };#endif#ifdef L_clear_cache/* Clear part of an instruction cache.  */#define INSN_CACHE_PLANE_SIZE (INSN_CACHE_SIZE / INSN_CACHE_DEPTH)void__clear_cache (beg, end)     char *beg, *end;{#ifdef CLEAR_INSN_CACHE   CLEAR_INSN_CACHE (beg, end);#else#ifdef INSN_CACHE_SIZE  static char array[INSN_CACHE_SIZE + INSN_CACHE_PLANE_SIZE + INSN_CACHE_LINE_WIDTH];  static int initialized;  int offset;  void *start_addr  void *end_addr;  typedef (*function_ptr) ();#if (INSN_CACHE_SIZE / INSN_CACHE_LINE_WIDTH) < 16  /* It's cheaper to clear the whole cache.     Put in a series of jump instructions so that calling the beginning     of the cache will clear the whole thing.  */  if (! initialized)    {      int ptr = (((int) array + INSN_CACHE_LINE_WIDTH - 1)		 & -INSN_CACHE_LINE_WIDTH);      int end_ptr = ptr + INSN_CACHE_SIZE;      while (ptr < end_ptr)	{	  *(INSTRUCTION_TYPE *)ptr	    = JUMP_AHEAD_INSTRUCTION + INSN_CACHE_LINE_WIDTH;	  ptr += INSN_CACHE_LINE_WIDTH;	}      *(INSTRUCTION_TYPE *)(ptr - INSN_CACHE_LINE_WIDTH) = RETURN_INSTRUCTION;      initialized = 1;    }  /* Call the beginning of the sequence.  */  (((function_ptr) (((int) array + INSN_CACHE_LINE_WIDTH - 1)		    & -INSN_CACHE_LINE_WIDTH))   ());#else /* Cache is large.  */  if (! initialized)    {      int ptr = (((int) array + INSN_CACHE_LINE_WIDTH - 1)		 & -INSN_CACHE_LINE_WIDTH);      while (ptr < (int) array + sizeof array)

⌨️ 快捷键说明

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