new alpha division routines

Richard Henderson rth@redhat.com
Mon Mar 29 20:03:00 GMT 2004


Duh.


r~
-------------- next part --------------
#include <unistd.h>
#include <fcntl.h>

static int fd = -1;

static unsigned long __attribute__((used))
udivmod4 (unsigned long x, unsigned long y, unsigned long *rp)
{
  unsigned long q, mask, data[2];

  if (fd < 0)
    {
      fd = open ("/tmp/div_data", O_CREAT | O_APPEND | O_WRONLY, 0660);
      fcntl (fd, F_SETFD, FD_CLOEXEC);
    }
  data[0] = x;
  data[1] = y;
  write (fd, data, sizeof(data));

  q = 0;
  mask = 1;
  while ((long) y > 0 && y < x)
    y <<= 1, mask <<= 1;

  do
    {
      if (y <= x)
	{
	  q += mask;
	  x -= y;
	}
      mask >>= 1;
      y >>= 1;
    }
  while (mask);

  *rp = x;
  return q;
}

asm("						\n\
	.align	4				\n\
	.globl	__divqu				\n\
	.type	__divqu, @function		\n\
__divqu:					\n\
	lda	$sp, -46*8($sp)			\n\
	bsr	$28, saveregs			\n\
	ldgp	$29, 0($28)			\n\
	mov	$24, $16			\n\
	mov	$25, $17			\n\
	lda	$18, 44*8($sp)			\n\
	bsr	$26, udivmod4	!samegp		\n\
	mov	$0, $27				\n\
	bsr	$28, loadregs			\n\
	lda	$sp, 46*8($sp)			\n\
	ret	$31, ($23), 1			\n\
						\n\
	.align	4				\n\
	.globl	__remqu				\n\
	.type	__remqu, @function		\n\
__remqu:					\n\
	lda	$sp, -46*8($sp)			\n\
	bsr	$28, saveregs			\n\
	ldgp	$29, 0($28)			\n\
	mov	$24, $16			\n\
	mov	$25, $17			\n\
	lda	$18, 44*8($sp)			\n\
	bsr	$26, udivmod4	!samegp		\n\
	ldq	$27, 44*8($sp)			\n\
	bsr	$28, loadregs			\n\
	lda	$sp, 46*8($sp)			\n\
	ret	$31, ($23), 1			\n\
						\n\
	.align	4				\n\
	.globl	__divq				\n\
	.type	__divq, @function		\n\
__divq:						\n\
	lda	$sp, -46*8($sp)			\n\
	bsr	$28, saveregs			\n\
	ldgp	$29, 0($28)			\n\
	negq	$24, $16			\n\
	negq	$25, $17			\n\
	cmovge	$24, $24, $16			\n\
	cmovge	$25, $25, $17			\n\
	lda	$18, 44*8($sp)			\n\
	bsr	$26, udivmod4	!samegp		\n\
	ldq	$24, 17*8($sp)			\n\
	ldq	$25, 18*8($sp)			\n\
	negq	$0, $27				\n\
	xor	$24, $25, $28			\n\
	cmovge	$28, $0, $27			\n\
	bsr	$28, loadregs			\n\
	lda	$sp, 46*8($sp)			\n\
	ret	$31, ($23), 1			\n\
						\n\
	.align	4				\n\
	.globl	__remq				\n\
	.type	__remq, @function		\n\
__remq:						\n\
	lda	$sp, -46*8($sp)			\n\
	bsr	$28, saveregs			\n\
	ldgp	$29, 0($28)			\n\
	negq	$24, $16			\n\
	negq	$25, $17			\n\
	cmovge	$24, $24, $16			\n\
	cmovge	$25, $25, $17			\n\
	lda	$18, 44*8($sp)			\n\
	bsr	$26, udivmod4	!samegp		\n\
	ldq	$27, 44*8($sp)			\n\
	ldq	$24, 17*8($sp)			\n\
	negq	$27, $28			\n\
	cmovlt	$24, $28, $27			\n\
	bsr	$28, loadregs			\n\
	lda	$sp, 46*8($sp)			\n\
	ret	$31, ($23), 1			\n\
						\n\
	.align	4				\n\
saveregs:					\n\
	stq	$0,   0*8($sp)			\n\
	stq	$1,   1*8($sp)			\n\
	stq	$2,   2*8($sp)			\n\
	stq	$3,   3*8($sp)			\n\
	stq	$4,   4*8($sp)			\n\
	stq	$5,   5*8($sp)			\n\
	stq	$6,   6*8($sp)			\n\
	stq	$7,   7*8($sp)			\n\
	stq	$8,   8*8($sp)			\n\
	stq	$16,  9*8($sp)			\n\
	stq	$17, 10*8($sp)			\n\
	stq	$18, 11*8($sp)			\n\
	stq	$19, 12*8($sp)			\n\
	stq	$20, 13*8($sp)			\n\
	stq	$21, 14*8($sp)			\n\
	stq	$22, 15*8($sp)			\n\
	stq	$23, 16*8($sp)			\n\
	stq	$24, 17*8($sp)			\n\
	stq	$25, 18*8($sp)			\n\
	stq	$26, 19*8($sp)			\n\
	stq	$29, 20*8($sp)			\n\
	stt	$f0, 21*8($sp)			\n\
	stt	$f1, 22*8($sp)			\n\
	stt	$f10, 23*8($sp)			\n\
	stt	$f11, 24*8($sp)			\n\
	stt	$f12, 25*8($sp)			\n\
	stt	$f13, 26*8($sp)			\n\
	stt	$f14, 27*8($sp)			\n\
	stt	$f15, 28*8($sp)			\n\
	stt	$f16, 29*8($sp)			\n\
	stt	$f17, 30*8($sp)			\n\
	stt	$f18, 31*8($sp)			\n\
	stt	$f19, 32*8($sp)			\n\
	stt	$f20, 33*8($sp)			\n\
	stt	$f21, 34*8($sp)			\n\
	stt	$f22, 35*8($sp)			\n\
	stt	$f23, 36*8($sp)			\n\
	stt	$f24, 37*8($sp)			\n\
	stt	$f25, 38*8($sp)			\n\
	stt	$f26, 39*8($sp)			\n\
	stt	$f27, 40*8($sp)			\n\
	stt	$f28, 41*8($sp)			\n\
	stt	$f29, 42*8($sp)			\n\
	stt	$f30, 43*8($sp)			\n\
	ret	$31, ($28), 0			\n\
						\n\
	.align	4				\n\
loadregs:					\n\
	ldq	$0,   0*8($sp)			\n\
	ldq	$1,   1*8($sp)			\n\
	ldq	$2,   2*8($sp)			\n\
	ldq	$3,   3*8($sp)			\n\
	ldq	$4,   4*8($sp)			\n\
	ldq	$5,   5*8($sp)			\n\
	ldq	$6,   6*8($sp)			\n\
	ldq	$7,   7*8($sp)			\n\
	ldq	$8,   8*8($sp)			\n\
	ldq	$16,  9*8($sp)			\n\
	ldq	$17, 10*8($sp)			\n\
	ldq	$18, 11*8($sp)			\n\
	ldq	$19, 12*8($sp)			\n\
	ldq	$20, 13*8($sp)			\n\
	ldq	$21, 14*8($sp)			\n\
	ldq	$22, 15*8($sp)			\n\
	ldq	$23, 16*8($sp)			\n\
	ldq	$24, 17*8($sp)			\n\
	ldq	$25, 18*8($sp)			\n\
	ldq	$26, 19*8($sp)			\n\
	ldq	$29, 20*8($sp)			\n\
	ldt	$f0, 21*8($sp)			\n\
	ldt	$f1, 22*8($sp)			\n\
	ldt	$f10, 23*8($sp)			\n\
	ldt	$f11, 24*8($sp)			\n\
	ldt	$f12, 25*8($sp)			\n\
	ldt	$f13, 26*8($sp)			\n\
	ldt	$f14, 27*8($sp)			\n\
	ldt	$f15, 28*8($sp)			\n\
	ldt	$f16, 29*8($sp)			\n\
	ldt	$f17, 30*8($sp)			\n\
	ldt	$f18, 31*8($sp)			\n\
	ldt	$f19, 32*8($sp)			\n\
	ldt	$f20, 33*8($sp)			\n\
	ldt	$f21, 34*8($sp)			\n\
	ldt	$f22, 35*8($sp)			\n\
	ldt	$f23, 36*8($sp)			\n\
	ldt	$f24, 37*8($sp)			\n\
	ldt	$f25, 38*8($sp)			\n\
	ldt	$f26, 39*8($sp)			\n\
	ldt	$f27, 40*8($sp)			\n\
	ldt	$f28, 41*8($sp)			\n\
	ldt	$f29, 42*8($sp)			\n\
	ldt	$f30, 43*8($sp)			\n\
	ret	$31, ($28), 0			\n\
");
-------------- next part --------------
#include <stdio.h>

int main()
{
  unsigned long x_lt_y = 0;
  unsigned long y_pow_2 = 0;
  unsigned long y_eq_10 = 0;
  unsigned long y_eq_100 = 0;
  unsigned long y_eq_1000 = 0;
  unsigned long y_eq_10000 = 0;
  unsigned long y_eq_100000 = 0;
  unsigned long y_eq_1000000 = 0;
  unsigned long x_lt_2to48 = 0;
  unsigned long x_eq_m1 = 0;
  unsigned long count = 0;
  unsigned long data[2];
  
  while (fread (data, 8, 2, stdin) == 2)
    {
      unsigned long x = data[0];
      unsigned long y = data[1];

      count        += 1;
      x_lt_2to48   += (x < (1ul << 48));
      x_lt_y       += (x < y);
      y_pow_2      += ((y & -y) == y);
      y_eq_10      += (y == 10);
      y_eq_100     += (y == 100);
      y_eq_1000    += (y == 1000);
      y_eq_10000   += (y == 10000);
      y_eq_100000  += (y == 100000);
      y_eq_1000000 += (y == 1000000);
      x_eq_m1      += (x == -1ul);
    }

  printf ("count         %12lu\n", count);
  printf ("x_lt_2to48    %12lu\n", x_lt_2to48);
  printf ("x_lt_y        %12lu\n", x_lt_y);
  printf ("y_pow_2       %12lu\n", y_pow_2);
  printf ("y_eq_10       %12lu\n", y_eq_10);
  printf ("y_eq_100      %12lu\n", y_eq_100);
  printf ("y_eq_1000     %12lu\n", y_eq_1000);
  printf ("y_eq_10000    %12lu\n", y_eq_10000);
  printf ("y_eq_100000   %12lu\n", y_eq_100000);
  printf ("y_eq_1000000  %12lu\n", y_eq_1000000);
  printf ("x_eq_m1       %12lu\n", x_eq_m1);

  return 0;
}
-------------- next part --------------
#include <sys/types.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>


asm("						\n\
	.ent	doit				\n\
doit:						\n\
	ldgp	$29, 0($27)			\n\
	subq	$30, 48, $30			\n\
	stq	$26, 0($30)			\n\
	stq	$9, 8($30)			\n\
	stq	$10, 16($30)			\n\
	stq	$11, 24($30)			\n\
	stq	$12, 32($30)			\n\
	.frame	$30, 48, $26			\n\
	.mask	0x4001e00, 0			\n\
	.prologue 1				\n\
						\n\
	lda	$8, __divqu			\n\
	ldq	$24, 0($16)			\n\
	ldq	$25, 8($16)			\n\
	ldq	$9, 16($16)			\n\
	ldq	$10, 24($16)			\n\
	addq	$16, 32, $11			\n\
	subq	$17, 2, $12			\n\
	jsr	$23, ($8), __divqu		\n\
1:	mov	$9, $24				\n\
	mov	$10, $25			\n\
	ldq	$9, 0($11)			\n\
	ldq	$10, 8($11)			\n\
	jsr	$23, ($8), __divqu		\n\
	subq	$12, 1, $12			\n\
	addq	$11, 16, $11			\n\
	bne	$12, 1b				\n\
						\n\
	ldq	$26, 0($30)			\n\
	ldq	$9, 8($30)			\n\
	ldq	$10, 16($30)			\n\
	ldq	$11, 24($30)			\n\
	ldq	$12, 32($30)			\n\
	addq	$30, 48, $30			\n\
	ret					\n\
	.end	doit				\n\
");


int main(int ac, char *av[])
{
  int fd;
  struct stat sb;
  void *v;

  fd = open(ac > 2 ? av[1] : "div_data", O_RDONLY);
  if (fd < 0)
    return 1;
  fstat(fd, &sb);

  v = mmap(0, sb.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
  if (v == MAP_FAILED)
    return 1;

  doit(v, sb.st_size / 16);

  return 0;
}


More information about the Libc-alpha mailing list