OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-old/] [binutils-2.18.50/] [libiberty/] [sort.c] - Diff between revs 156 and 816

Go to most recent revision | Only display areas with differences | Details | Blame | View Log

Rev 156 Rev 816
/* Sorting algorithms.
/* Sorting algorithms.
   Copyright (C) 2000 Free Software Foundation, Inc.
   Copyright (C) 2000 Free Software Foundation, Inc.
   Contributed by Mark Mitchell <mark@codesourcery.com>.
   Contributed by Mark Mitchell <mark@codesourcery.com>.
 
 
This file is part of GNU CC.
This file is part of GNU CC.
 
 
GNU CC is free software; you can redistribute it and/or modify it
GNU CC is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
the Free Software Foundation; either version 2, or (at your option)
any later version.
any later version.
 
 
GNU CC is distributed in the hope that it will be useful, but
GNU CC is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
General Public License for more details.
General Public License for more details.
 
 
You should have received a copy of the GNU General Public License
You should have received a copy of the GNU General Public License
along with GNU CC; see the file COPYING.  If not, write to
along with GNU CC; see the file COPYING.  If not, write to
the Free Software Foundation, 51 Franklin Street - Fifth Floor,
the Free Software Foundation, 51 Franklin Street - Fifth Floor,
Boston, MA 02110-1301, USA.  */
Boston, MA 02110-1301, USA.  */
 
 
#ifdef HAVE_CONFIG_H
#ifdef HAVE_CONFIG_H
#include "config.h"
#include "config.h"
#endif
#endif
#include "libiberty.h"
#include "libiberty.h"
#include "sort.h"
#include "sort.h"
#ifdef HAVE_LIMITS_H
#ifdef HAVE_LIMITS_H
#include <limits.h>
#include <limits.h>
#endif
#endif
#ifdef HAVE_SYS_PARAM_H
#ifdef HAVE_SYS_PARAM_H
#include <sys/param.h>
#include <sys/param.h>
#endif
#endif
#ifdef HAVE_STDLIB_H
#ifdef HAVE_STDLIB_H
#include <stdlib.h>
#include <stdlib.h>
#endif
#endif
#ifdef HAVE_STRING_H
#ifdef HAVE_STRING_H
#include <string.h>
#include <string.h>
#endif
#endif
 
 
#ifndef UCHAR_MAX
#ifndef UCHAR_MAX
#define UCHAR_MAX ((unsigned char)(-1))
#define UCHAR_MAX ((unsigned char)(-1))
#endif
#endif
 
 
/* POINTERS and WORK are both arrays of N pointers.  When this
/* POINTERS and WORK are both arrays of N pointers.  When this
   function returns POINTERS will be sorted in ascending order.  */
   function returns POINTERS will be sorted in ascending order.  */
 
 
void sort_pointers (size_t n, void **pointers, void **work)
void sort_pointers (size_t n, void **pointers, void **work)
{
{
  /* The type of a single digit.  This can be any unsigned integral
  /* The type of a single digit.  This can be any unsigned integral
     type.  When changing this, DIGIT_MAX should be changed as
     type.  When changing this, DIGIT_MAX should be changed as
     well.  */
     well.  */
  typedef unsigned char digit_t;
  typedef unsigned char digit_t;
 
 
  /* The maximum value a single digit can have.  */
  /* The maximum value a single digit can have.  */
#define DIGIT_MAX (UCHAR_MAX + 1)
#define DIGIT_MAX (UCHAR_MAX + 1)
 
 
  /* The Ith entry is the number of elements in *POINTERSP that have I
  /* The Ith entry is the number of elements in *POINTERSP that have I
     in the digit on which we are currently sorting.  */
     in the digit on which we are currently sorting.  */
  unsigned int count[DIGIT_MAX];
  unsigned int count[DIGIT_MAX];
  /* Nonzero if we are running on a big-endian machine.  */
  /* Nonzero if we are running on a big-endian machine.  */
  int big_endian_p;
  int big_endian_p;
  size_t i;
  size_t i;
  size_t j;
  size_t j;
 
 
  /* The algorithm used here is radix sort which takes time linear in
  /* The algorithm used here is radix sort which takes time linear in
     the number of elements in the array.  */
     the number of elements in the array.  */
 
 
  /* The algorithm here depends on being able to swap the two arrays
  /* The algorithm here depends on being able to swap the two arrays
     an even number of times.  */
     an even number of times.  */
  if ((sizeof (void *) / sizeof (digit_t)) % 2 != 0)
  if ((sizeof (void *) / sizeof (digit_t)) % 2 != 0)
    abort ();
    abort ();
 
 
  /* Figure out the endianness of the machine.  */
  /* Figure out the endianness of the machine.  */
  for (i = 0, j = 0; i < sizeof (size_t); ++i)
  for (i = 0, j = 0; i < sizeof (size_t); ++i)
    {
    {
      j *= (UCHAR_MAX + 1);
      j *= (UCHAR_MAX + 1);
      j += i;
      j += i;
    }
    }
  big_endian_p = (((char *)&j)[0] == 0);
  big_endian_p = (((char *)&j)[0] == 0);
 
 
  /* Move through the pointer values from least significant to most
  /* Move through the pointer values from least significant to most
     significant digits.  */
     significant digits.  */
  for (i = 0; i < sizeof (void *) / sizeof (digit_t); ++i)
  for (i = 0; i < sizeof (void *) / sizeof (digit_t); ++i)
    {
    {
      digit_t *digit;
      digit_t *digit;
      digit_t *bias;
      digit_t *bias;
      digit_t *top;
      digit_t *top;
      unsigned int *countp;
      unsigned int *countp;
      void **pointerp;
      void **pointerp;
 
 
      /* The offset from the start of the pointer will depend on the
      /* The offset from the start of the pointer will depend on the
         endianness of the machine.  */
         endianness of the machine.  */
      if (big_endian_p)
      if (big_endian_p)
        j = sizeof (void *) / sizeof (digit_t) - i;
        j = sizeof (void *) / sizeof (digit_t) - i;
      else
      else
        j = i;
        j = i;
 
 
      /* Now, perform a stable sort on this digit.  We use counting
      /* Now, perform a stable sort on this digit.  We use counting
         sort.  */
         sort.  */
      memset (count, 0, DIGIT_MAX * sizeof (unsigned int));
      memset (count, 0, DIGIT_MAX * sizeof (unsigned int));
 
 
      /* Compute the address of the appropriate digit in the first and
      /* Compute the address of the appropriate digit in the first and
         one-past-the-end elements of the array.  On a little-endian
         one-past-the-end elements of the array.  On a little-endian
         machine, the least-significant digit is closest to the front.  */
         machine, the least-significant digit is closest to the front.  */
      bias = ((digit_t *) pointers) + j;
      bias = ((digit_t *) pointers) + j;
      top = ((digit_t *) (pointers + n)) + j;
      top = ((digit_t *) (pointers + n)) + j;
 
 
      /* Count how many there are of each value.  At the end of this
      /* Count how many there are of each value.  At the end of this
         loop, COUNT[K] will contain the number of pointers whose Ith
         loop, COUNT[K] will contain the number of pointers whose Ith
         digit is K.  */
         digit is K.  */
      for (digit = bias;
      for (digit = bias;
           digit < top;
           digit < top;
           digit += sizeof (void *) / sizeof (digit_t))
           digit += sizeof (void *) / sizeof (digit_t))
        ++count[*digit];
        ++count[*digit];
 
 
      /* Now, make COUNT[K] contain the number of pointers whose Ith
      /* Now, make COUNT[K] contain the number of pointers whose Ith
         digit is less than or equal to K.  */
         digit is less than or equal to K.  */
      for (countp = count + 1; countp < count + DIGIT_MAX; ++countp)
      for (countp = count + 1; countp < count + DIGIT_MAX; ++countp)
        *countp += countp[-1];
        *countp += countp[-1];
 
 
      /* Now, drop the pointers into their correct locations.  */
      /* Now, drop the pointers into their correct locations.  */
      for (pointerp = pointers + n - 1; pointerp >= pointers; --pointerp)
      for (pointerp = pointers + n - 1; pointerp >= pointers; --pointerp)
        work[--count[((digit_t *) pointerp)[j]]] = *pointerp;
        work[--count[((digit_t *) pointerp)[j]]] = *pointerp;
 
 
      /* Swap WORK and POINTERS so that POINTERS contains the sorted
      /* Swap WORK and POINTERS so that POINTERS contains the sorted
         array.  */
         array.  */
      pointerp = pointers;
      pointerp = pointers;
      pointers = work;
      pointers = work;
      work = pointerp;
      work = pointerp;
    }
    }
}
}
 
 
/* Everything below here is a unit test for the routines in this
/* Everything below here is a unit test for the routines in this
   file.  */
   file.  */
 
 
#ifdef UNIT_TEST
#ifdef UNIT_TEST
 
 
#include <stdio.h>
#include <stdio.h>
 
 
void *xmalloc (size_t n)
void *xmalloc (size_t n)
{
{
  return malloc (n);
  return malloc (n);
}
}
 
 
int main (int argc, char **argv)
int main (int argc, char **argv)
{
{
  int k;
  int k;
  int result;
  int result;
  size_t i;
  size_t i;
  void **pointers;
  void **pointers;
  void **work;
  void **work;
 
 
  if (argc > 1)
  if (argc > 1)
    k = atoi (argv[1]);
    k = atoi (argv[1]);
  else
  else
    k = 10;
    k = 10;
 
 
  pointers = XNEWVEC (void*, k);
  pointers = XNEWVEC (void*, k);
  work = XNEWVEC (void*, k);
  work = XNEWVEC (void*, k);
 
 
  for (i = 0; i < k; ++i)
  for (i = 0; i < k; ++i)
    {
    {
      pointers[i] = (void *) random ();
      pointers[i] = (void *) random ();
      printf ("%x\n", pointers[i]);
      printf ("%x\n", pointers[i]);
    }
    }
 
 
  sort_pointers (k, pointers, work);
  sort_pointers (k, pointers, work);
 
 
  printf ("\nSorted\n\n");
  printf ("\nSorted\n\n");
 
 
  result = 0;
  result = 0;
 
 
  for (i = 0; i < k; ++i)
  for (i = 0; i < k; ++i)
    {
    {
      printf ("%x\n", pointers[i]);
      printf ("%x\n", pointers[i]);
      if (i > 0 && (char*) pointers[i] < (char*) pointers[i - 1])
      if (i > 0 && (char*) pointers[i] < (char*) pointers[i - 1])
        result = 1;
        result = 1;
    }
    }
 
 
  free (pointers);
  free (pointers);
  free (work);
  free (work);
 
 
  return result;
  return result;
}
}
 
 
#endif
#endif
 
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.