Plan 9 from Bell Labs’s /usr/web/sources/contrib/fernan/nhc98/src/runtime/Integer/asmlong.h

Copyright © 2021 Plan 9 Foundation.
Distributed under the MIT License.
Download the Plan 9 distribution.


#if defined (__a29k__) || defined (___AM29K__)
#define add_ssaaaa(sh, sl, ah, al, bh, bl) \
  __asm__ ("add %1,%4,%5\n"	\
"	addc %0,%2,%3"		\
	 : "=r" ((unsigned long int)(sh)), "=&r" ((unsigned long int)(sl)) \
	 : "%r" ((unsigned long int)(ah)), "rI" ((unsigned long int)(bh)), \
	   "%r" ((unsigned long int)(al)), "rI" ((unsigned long int)(bl)))
#define sub_ddmmss(sh, sl, ah, al, bh, bl) \
  __asm__ ("sub %1,%4,%5\n"	\
"	subc %0,%2,%3"		\
	 : "=r" ((unsigned long int)(sh)), "=&r" ((unsigned long int)(sl)) \
	 : "r" ((unsigned long int)(ah)), "rI" ((unsigned long int)(bh)), \
	   "r" ((unsigned long int)(al)), "rI" ((unsigned long int)(bl)))
#define umul_ppmm(xh, xl, m0, m1) \
  do {									\
    unsigned long int __m0 = (m0), __m1 = (m1);				\
    __asm__ ("multiplu %0,%1,%2" : "=r" ((unsigned long int)(xl))	\
	     : "r" (__m0), "r" (__m1));					\
    __asm__ ("multmu %0,%1,%2" : "=r" ((unsigned long int)(xh))		\
	     : "r" (__m0), "r" (__m1));					\
  } while (0)
#define udiv_qrnnd(q, r, n1, n0, d) \
  __asm__ ("dividu %0,%3,%4"						\
	: "=r" ((unsigned long int)(q)), "=q" ((unsigned long int)(r))	\
	: "1" ((unsigned long int)(n1)), "r" ((unsigned long int)(n0)),	\
	  "r" ((unsigned long int)(d)))
#define count_leading_zeros(count, x) \
    __asm__ ("clz %0,%1" : "=r" ((unsigned long int)(count))		\
	     : "r" ((unsigned long int)(x)))
#endif /* __a29k__ */

#if defined (__arm__)
#define add_ssaaaa(sh, sl, ah, al, bh, bl) \
  __asm__ ("adds %1,%4,%5\n"	\
"	adc %0,%2,%3"		\
	: "=r" ((unsigned long int)(sh)), "=&r" ((unsigned long int)(sl)) \
	: "%r" ((unsigned long int)(ah)), "rI" ((unsigned long int)(bh)), \
	  "%r" ((unsigned long int)(al)), "rI" ((unsigned long int)(bl)))
#define sub_ddmmss(sh, sl, ah, al, bh, bl) \
  __asm__ ("subs %1,%4,%5\n"	\
"	sbc %0,%2,%3"		\
	: "=r" ((unsigned long int)(sh)), "=&r" ((unsigned long int)(sl)) \
	: "r" ((unsigned long int)(ah)), "rI" ((unsigned long int)(bh)), \
	  "r" ((unsigned long int)(al)), "rI" ((unsigned long int)(bl)))
#endif /* __arm__ */

#if defined (__gmicro__)
#define add_ssaaaa(sh, sl, ah, al, bh, bl) \
  __asm__ ("add.w %5,%1\n"	\
"	addx %3,%0"		\
       : "=g" ((unsigned long int)(sh)), "=&g" ((unsigned long int)(sl))\
       : "%0" ((unsigned long int)(ah)), "g" ((unsigned long int)(bh)),	\
	 "%1" ((unsigned long int)(al)), "g" ((unsigned long int)(bl)))
#define sub_ddmmss(sh, sl, ah, al, bh, bl) \
  __asm__ ("sub.w %5,%1\n"	\
"	subx %3,%0"		\
       : "=g" ((unsigned long int)(sh)), "=&g" ((unsigned long int)(sl))\
       : "0" ((unsigned long int)(ah)), "g" ((unsigned long int)(bh)),	\
	 "1" ((unsigned long int)(al)), "g" ((unsigned long int)(bl)))
#define umul_ppmm(ph, pl, m0, m1) \
  __asm__ ("mulx %3,%0,%1"						\
	: "=g" ((unsigned long int)(ph)), "=r" ((unsigned long int)(pl))\
	: "%0" ((unsigned long int)(m0)), "g" ((unsigned long int)(m1)))
#define udiv_qrnnd(q, r, nh, nl, d) \
  __asm__ ("divx %4,%0,%1"						\
	: "=g" ((unsigned long int)(q)), "=r" ((unsigned long int)(r))	\
	: "1" ((unsigned long int)(nh)), "0" ((unsigned long int)(nl)),	\
	  "g" ((unsigned long int)(d)))
#define count_leading_zeros(count, x) \
  __asm__ ("bsch/1 %1,%0"						\
	: "=g" (count)							\
	: "g" ((unsigned long int)(x)), "0" (0UL))
#endif

#if defined (__hppa)
#define add_ssaaaa(sh, sl, ah, al, bh, bl) \
  __asm__ ("add %4,%5,%1\n"	\
"        addc %2,%3,%0"		\
	: "=r" ((unsigned long int)(sh)), "=&r" ((unsigned long int)(sl))\
	: "%r" ((unsigned long int)(ah)), "r" ((unsigned long int)(bh)),\
	  "%r" ((unsigned long int)(al)), "r" ((unsigned long int)(bl)))
#define sub_ddmmss(sh, sl, ah, al, bh, bl) \
  __asm__ ("sub %5,%4,%1\n"	\
"        subb %3,%2,%0"		\
	: "=r" ((unsigned long int)(sh)), "=&r" ((unsigned long int)(sl))\
	: "r" ((unsigned long int)(ah)), "r" ((unsigned long int)(bh)),	\
	  "r" ((unsigned long int)(al)), "r" ((unsigned long int)(bl)))
#endif

#if defined (__i386__) || defined (__i486__)
#define add_ssaaaa(sh, sl, ah, al, bh, bl) \
  __asm__ ("addl %5,%1\n"	\
"	adcl %3,%0"		\
       : "=r" ((unsigned long int)(sh)), "=&r" ((unsigned long int)(sl))\
       : "%0" ((unsigned long int)(ah)), "g" ((unsigned long int)(bh)),	\
	 "%1" ((unsigned long int)(al)), "g" ((unsigned long int)(bl)))
#define sub_ddmmss(sh, sl, ah, al, bh, bl) \
  __asm__ ("subl %5,%1\n"	\
"	sbbl %3,%0"		\
       : "=r" ((unsigned long int)(sh)), "=&r" ((unsigned long int)(sl))\
       : "0" ((unsigned long int)(ah)), "g" ((unsigned long int)(bh)),	\
	 "1" ((unsigned long int)(al)), "g" ((unsigned long int)(bl)))
#define umul_ppmm(w1, w0, u, v) \
  __asm__ ("mull %3"							\
	: "=a" ((unsigned long int)(w0)), "=d" ((unsigned long int)(w1))\
	: "%0" ((unsigned long int)(u)), "rm" ((unsigned long int)(v)))
#define udiv_qrnnd(q, r, n1, n0, d) \
  __asm__ ("divl %4"							\
	: "=a" ((unsigned long int)(q)), "=d" ((unsigned long int)(r))	\
	: "0" ((unsigned long int)(n0)), "1" ((unsigned long int)(n1)),	\
	  "rm" ((unsigned long int)(d)))
#if 0
#define count_leading_zeros(count, x) \
  do {									\
    unsigned long int __cbtmp;						\
    __asm__ ("bsrl %1,%0"						\
	     : "=r" (__cbtmp) : "rm" ((unsigned long int)(x)));		\
    (count) = __cbtmp ^ 31;						\
  } while (0)
#endif
#endif /* 80x86 */

#if defined (__i860__)
#if 0
/* Make sure these patterns really improve the code before
   switching them on.  */
#define add_ssaaaa(sh, sl, ah, al, bh, bl) \
  do {									\
    union								\
      {									\
	long long int ll;						\
	struct {unsigned long int l, h;} i;				\
      }  __a, __b, __s;							\
    __a.i.l = (al); __a.i.h = (ah);					\
    __b.i.l = (bl); __b.i.h = (bh);					\
    __asm__ ("fiadd.dd %1,%2,%0"					\
	     : "=f" (__s.ll)						\
	     : "%f" (__a.ll), "f" (__b.ll));				\
    (sh) = __s.i.h; (sl) = __s.i.l;					\
    } while (0)
#define sub_ddmmss(sh, sl, ah, al, bh, bl) \
  do {									\
    union								\
      {									\
	long long int ll;						\
	struct {unsigned long int l, h;} i;				\
      }  __a, __b, __s;							\
    __a.i.l = (al); __a.i.h = (ah);					\
    __b.i.l = (bl); __b.i.h = (bh);					\
    __asm__ ("fisub.dd %1,%2,%0"					\
	     : "=f" (__s.ll)						\
	     : "%f" (__a.ll), "f" (__b.ll));				\
    (sh) = __s.i.h; (sl) = __s.i.l;					\
    } while (0)
#endif
#endif /* __i860__ */

#if defined (___IBMR2__) /* IBM RS6000 */
#define add_ssaaaa(sh, sl, ah, al, bh, bl) \
  __asm__ ("a %1,%4,%5\n"	\
"	ae %0,%2,%3"		\
	: "=r" ((unsigned long int)(sh)), "=&r" ((unsigned long int)(sl))\
	: "%r" ((unsigned long int)(ah)), "r" ((unsigned long int)(bh)),\
	  "%r" ((unsigned long int)(al)), "r" ((unsigned long int)(bl)))
#define sub_ddmmss(sh, sl, ah, al, bh, bl) \
  __asm__ ("sf %1,%5,%4\n"	\
"	sfe %0,%3,%2"		\
	: "=r" ((unsigned long int)(sh)), "=&r" ((unsigned long int)(sl))\
	: "r" ((unsigned long int)(ah)), "r" ((unsigned long int)(bh)),	\
	  "r" ((unsigned long int)(al)), "r" ((unsigned long int)(bl)))
#define umul_ppmm(xh, xl, m0, m1) \
  do {									\
    unsigned long int __m0 = (m0), __m1 = (m1);				\
    __asm__ ("mul %0,%2,%3"						\
	: "=r" ((unsigned long int)(xh)), "=q" ((unsigned long int)(xl))\
	: "r" (__m0), "r" (__m1));					\
    (xh) += ((((signed long int) __m0 >> 31) & __m1)			\
	     + (((signed long int) __m1 >> 31) & __m0));		\
  } while (0)
#define UMUL_TIME 8
#define udiv_qrnnd(q, r, nh, nl, d) \
  do { /* Use the signed "div" insn, and adjust the result. */		\
    unsigned long int __q, __r, __nh, __nl, __d, __xh, __xl;		\
    __nh = 0;								\
    __nl = (((unsigned long int)(nh)) << 30) | ((unsigned long int)(nl) >> 2);\
    __nh = (unsigned long int)(nh) >> 2;				\
    __d = ((unsigned long int)(d) >> 1);				\
    __asm__ ("div %0,%2,%4"						\
	     : "=r" (__q), "=q" (__r)					\
	     : "r" (__nh), "1" (__nl), "r" (__d));			\
    __q <<= 1;								\
    __asm__ ("mul %0,%2,%3"						\
	     : "=r" (__xh), "=q" (__xl)					\
	     : "r" (__q), "r" ((unsigned long int)(d)));		\
    __xh += (((signed long int) __q >> 31) & (d)) + __q;		\
    if ((nh) < __xh || ((nh) == __xh && (nl) < __xl))			\
      {									\
	do								\
	  {								\
	    sub_ddmmss (__xh, __xl, __xh, __xl, 0, (d));		\
	    __q--;							\
	  }								\
	while ((nh) < __xh || ((nh) == __xh && (nl) < __xl));		\
	__xl = (nl) - __xl;						\
      }									\
    else								\
      {									\
	sub_ddmmss (__xh, __xl, (nh), (nl), __xh, __xl);		\
	if (__xh != 0)							\
	  {								\
	    do								\
	      {								\
		sub_ddmmss (__xh, __xl, __xh, __xl, 0, (d));		\
		__q++;							\
	      }								\
	    while (__xh != 0);						\
	  }								\
	if (__xl >= (d))						\
	  {								\
	    __xl -= (d);						\
	    __q++;							\
	  }								\
      }									\
    (q) = __q;								\
    (r) = __xl;								\
  } while (0)
#define UDIV_TIME 40
#define UDIV_NEEDS_NORMALIZATION 1
#define count_leading_zeros(count, x) \
  __asm__ ("cntlz %0,%1"						\
	: "=r" ((unsigned long int)(count)) : "r" ((unsigned long int)(x)))
#endif /* ___IBMR2__ */

#if defined (__mc68000__)
#define add_ssaaaa(sh, sl, ah, al, bh, bl) \
  __asm__ ("add%.l %5,%1\n\taddx%.l %3,%0"				\
	   : "=d" ((unsigned long int)(sh)),				\
	     "=&d" ((unsigned long int)(sl))				\
	   : "%0" ((unsigned long int)(ah)),				\
	     "d" ((unsigned long int)(bh)),				\
	     "%1" ((unsigned long int)(al)),				\
	     "g" ((unsigned long int)(bl)))
#define sub_ddmmss(sh, sl, ah, al, bh, bl) \
  __asm__ ("sub%.l %5,%1\n\tsubx%.l %3,%0"				\
	   : "=d" ((unsigned long int)(sh)),				\
	     "=&d" ((unsigned long int)(sl))				\
	   : "0" ((unsigned long int)(ah)),				\
	     "d" ((unsigned long int)(bh)),				\
	     "1" ((unsigned long int)(al)),				\
	     "g" ((unsigned long int)(bl)))
#if defined (__mc68020__) || defined (__NeXT__) || defined(mc68020)
#define umul_ppmm(w1, w0, u, v) \
  __asm__ ("mulu%.l %3,%1:%0"						\
	: "=d" ((unsigned long int)(w0)), "=d" ((unsigned long int)(w1))\
	: "%0" ((unsigned long int)(u)), "dmi" ((unsigned long int)(v)))
#define udiv_qrnnd(q, r, n1, n0, d) \
  __asm__ ("divu%.l %4,%1:%0"						\
	: "=d" ((unsigned long int)(q)), "=d" ((unsigned long int)(r))	\
	: "0" ((unsigned long int)(n0)), "1" ((unsigned long int)(n1)),	\
	  "dmi" ((unsigned long int)(d)))
#define count_leading_zeros(count, x) \
  __asm__ ("bfffo %1{%b2:%b2},%0"					\
	: "=d" ((unsigned long int)(count))				\
	: "od" ((unsigned long int)(x)), "n" (0))
#else /* not mc68020 */
#define umul_ppmm(xh, xl, a, b) \
  __asm__ ("| Inlined umul_ppmm\n"	\
"	movel	%2,d0\n"	\
"	movel	%3,d1\n"	\
"	movel	d0,d2\n"	\
"	swap	d0\n"		\
"	movel	d1,d3\n"	\
"	swap	d1\n"		\
"	movew	d2,d4\n"	\
"	mulu	d3,d4\n"	\
"	mulu	d1,d2\n"	\
"	mulu	d0,d3\n"	\
"	mulu	d0,d1\n"	\
"	movel	d4,d0\n"	\
"	eorw	d0,d0\n"	\
"	swap	d0\n"		\
"	addl	d0,d2\n"	\
"	addl	d3,d2\n"	\
"	jcc	1f\n"		\
"	addl	#65536,d1\n"	\
"1:	swap	d2\n"		\
"	moveq	#0,d0\n"	\
"	movew	d2,d0\n"	\
"	movew	d4,d2\n"	\
"	movel	d2,%1\n"	\
"	addl	d1,d0\n"	\
"	movel	d0,%0"		\
       : "=g" ((unsigned long int)(xh)), "=g" ((unsigned long int)(xl))	\
       :"g" ((unsigned long int)(a)), "g" ((unsigned long int)(b))	\
       : "d0", "d1", "d2", "d3", "d4")
#endif /* not mc68020 */
#endif /* mc68000 */

#if defined (__m88000__)
#define add_ssaaaa(sh, sl, ah, al, bh, bl) \
  __asm__ ("addu.co %1,%r4,%r5\n\taddu.ci %0,%r2,%r3"			\
	: "=r" ((unsigned long int)(sh)), "=&r" ((unsigned long int)(sl))\
	: "%rJ" ((unsigned long int)(ah)), "rJ" ((unsigned long int)(bh)),\
	  "%rJ" ((unsigned long int)(al)), "rJ" ((unsigned long int)(bl)))
#define sub_ddmmss(sh, sl, ah, al, bh, bl) \
  __asm__ ("subu.co %1,%r4,%r5\n\t subu.ci %0,%r2,%r3"			\
	: "=r" ((unsigned long int)(sh)), "=&r" ((unsigned long int)(sl))\
	: "rJ" ((unsigned long int)(ah)), "rJ" ((unsigned long int)(bh)),\
	  "rJ" ((unsigned long int)(al)), "rJ" ((unsigned long int)(bl)))
#define UMUL_TIME 17
#define UDIV_TIME 150
#define count_leading_zeros(count, x) \
  do {									\
    unsigned long int __cbtmp;						\
    __asm__ ("ff1 %0,%1"						\
	     : "=r" (__cbtmp) : "r" ((unsigned long int)(x)));		\
    (count) = __cbtmp ^ 31;						\
  } while (0)
#endif /* __m88000__ */

#if defined (__mips__)
#define umul_ppmm(w1, w0, u, v) \
  __asm__ ("multu %2,%3\n"	\
"	mflo %0\n"		\
"	mfhi %1"		\
	: "=r" ((unsigned long int)(w0)), "=r" ((unsigned long int)(w1))\
	: "r" ((unsigned long int)(u)), "r" ((unsigned long int)(v)))
#define UMUL_TIME 5
#define UDIV_TIME 100
#endif /* __mips__ */

#if defined (__ns32000__)
#define __umulsidi3(u, v) \
  ({long long int __w;							\
      __asm__ ("meid %2,%0" : "=g" (__w)				\
	: "%0" ((unsigned long int)(u)), "g" ((unsigned long int)(v)));	\
      __w; })
#define div_qrnnd(q, r, n1, n0, d) \
  __asm__ ("movd %2,r0\n"	\
"	movd %3,r1\n"	\
"	deid %4,r0\n"	\
"	movd r1,%0\n"	\
"	movd r0,%1"	\
	: "=g" ((unsigned long int)(q)), "=g" ((unsigned long int)(r))	\
	: "g" ((unsigned long int)(n0)), "g" ((unsigned long int)(n1)),	\
	  "g" ((unsigned long int)(d)) : "r0", "r1")
#endif /* __ns32000__ */

#if defined (__pyr__)
#define add_ssaaaa(sh, sl, ah, al, bh, bl) \
  __asm__ ("addw	%5,%1\n"	\
"	addwc	%3,%0"							\
	: "=r" ((unsigned long int)(sh)), "=&r" ((unsigned long int)(sl))\
	: "%0" ((unsigned long int)(ah)), "g" ((unsigned long int)(bh)),\
	  "%1" ((unsigned long int)(al)), "g" ((unsigned long int)(bl)))
#define sub_ddmmss(sh, sl, ah, al, bh, bl) \
  __asm__ ("subw	%5,%1\n"	\
"	subwb	%3,%0"							\
	: "=r" ((unsigned long int)(sh)), "=&r" ((unsigned long int)(sl))\
	: "0" ((unsigned long int)(ah)), "g" ((unsigned long int)(bh)),	\
	  "1" ((unsigned long int)(al)), "g" ((unsigned long int)(bl)))
/* This insn doesn't work on ancient pyramids.  */
#define umul_ppmm(w1, w0, u, v) \
  __asm__ ("movw %2,tr11\n"	\
"	uemul %3,tr10\n"	\
"	movw tr10,%0\n"		\
"	movw tr11,%1"							\
	: "=r" ((unsigned long int)(w1)), "=r" ((unsigned long int)(w0))\
	: "r" ((unsigned long int)(u)), "r" ((unsigned long int)(v))	\
	: "tr10", "tr11")
#endif /* __pyr__ */

#if defined (__ibm032__) /* RT/ROMP */
#define add_ssaaaa(sh, sl, ah, al, bh, bl) \
  __asm__ ("a %1,%5\n"	\
"	ae %0,%3"							\
	: "=r" ((unsigned long int)(sh)), "=&r" ((unsigned long int)(sl))\
	: "%0" ((unsigned long int)(ah)), "r" ((unsigned long int)(bh)),\
	  "%1" ((unsigned long int)(al)), "r" ((unsigned long int)(bl)))
#define sub_ddmmss(sh, sl, ah, al, bh, bl) \
  __asm__ ("s %1,%5\n"	\
"	se %0,%3"							\
	: "=r" ((unsigned long int)(sh)), "=&r" ((unsigned long int)(sl))\
	: "0" ((unsigned long int)(ah)), "r" ((unsigned long int)(bh)),	\
	  "1" ((unsigned long int)(al)), "r" ((unsigned long int)(bl)))
#define umul_ppmm(ph, pl, m0, m1) \
  do {									\
    unsigned long int __m0 = (m0), __m1 = (m1);				\
    __asm__ (								\
       "s	r2,r2\n"	\
"	mts	r10,%2\n"	\
"	m	r2,%3\n"	\
"	m	r2,%3\n"	\
"	m	r2,%3\n"	\
"	m	r2,%3\n"	\
"	m	r2,%3\n"	\
"	m	r2,%3\n"	\
"	m	r2,%3\n"	\
"	m	r2,%3\n"	\
"	m	r2,%3\n"	\
"	m	r2,%3\n"	\
"	m	r2,%3\n"	\
"	m	r2,%3\n"	\
"	m	r2,%3\n"	\
"	m	r2,%3\n"	\
"	m	r2,%3\n"	\
"	m	r2,%3\n"	\
"	cas	%0,r2,r0\n"	\
"	mfs	r10,%1"							\
       : "=r" ((unsigned long int)(ph)), "=r" ((unsigned long int)(pl))	\
       : "%r" (__m0), "r" (__m1)					\
       : "r2");								\
    (ph) += ((((signed long int) __m0 >> 31) & __m1)			\
	     + (((signed long int) __m1 >> 31) & __m0));		\
  } while (0)
#define count_leading_zeros(count, x) \
  do {									\
    if ((x) >= 0x10000)							\
      __asm__ ("clz	%0,%1"						\
	       : "=r" ((unsigned long int)(count))			\
	       : "r" ((unsigned long int)(x) >> 16));			\
    else								\
      {									\
	__asm__ ("clz	%0,%1"						\
		 : "=r" ((unsigned long int)(count))			\
		 : "r" ((unsigned long int)(x)));			\
	(count) += 16;							\
      }									\
  } while (0)
#endif

#if defined (__sparc__)
#define add_ssaaaa(sh, sl, ah, al, bh, bl) \
  __asm__ ("addcc %4,%5,%1\n"	\
"	addx %2,%3,%0"		\
	: "=r" ((unsigned long int)(sh)), "=&r" ((unsigned long int)(sl))\
	: "%r" ((unsigned long int)(ah)), "rI" ((unsigned long int)(bh)),\
	  "%r" ((unsigned long int)(al)), "rI" ((unsigned long int)(bl)))
#define sub_ddmmss(sh, sl, ah, al, bh, bl) \
  __asm__ ("subcc %4,%5,%1\n"	\
"	subx %2,%3,%0"		\
	: "=r" ((unsigned long int)(sh)), "=&r" ((unsigned long int)(sl))\
	: "r" ((unsigned long int)(ah)), "rI" ((unsigned long int)(bh)),\
	  "r" ((unsigned long int)(al)), "rI" ((unsigned long int)(bl)))
#if defined (__sparc8__)	/* How do we recog. version 8 SPARC?  */
#define umul_ppmm(w1, w0, u, v) \
  __asm__ ("umul %2,%3,%1;rd %%y,%0"					\
	: "=r" ((unsigned long int)(w1)), "=r" ((unsigned long int)(w0))\
	: "r" ((unsigned long int)(u)), "r" ((unsigned long int)(v)))
#define udiv_qrnnd(q, r, n1, n0, d) \
  __asm__ ("mov %2,%%y;nop;nop;nop;udiv %3,%4,%0;umul %0,%4,%1;sub %3,%1,%1"\
	: "=&r" ((unsigned long int)(q)), "=&r" ((unsigned long int)(r))\
	: "r" ((unsigned long int)(n1)), "r" ((unsigned long int)(n0)),	\
	  "r" ((unsigned long int)(d)))
#else
/* SPARC without integer multiplication and divide instructions.
   (i.e. at least Sun4/20,40,60,65,75,110,260,280,330,360,380,470,490) */
#define umul_ppmm(w1, w0, u, v) \
  __asm__ ("! Inlined umul_ppmm\n"	\
"	wr	%%g0,%2,%%y	! SPARC has 0-3 delay insn after a wr\n" \
"	sra	%3,31,%%g2	! Don't move this insn\n"	\
"	and	%2,%%g2,%%g2	! Don't move this insn\n"	\
"	andcc	%%g0,0,%%g1	! Don't move this insn\n"	\
"	mulscc	%%g1,%3,%%g1\n"	\
"	mulscc	%%g1,%3,%%g1\n"	\
"	mulscc	%%g1,%3,%%g1\n"	\
"	mulscc	%%g1,%3,%%g1\n"	\
"	mulscc	%%g1,%3,%%g1\n"	\
"	mulscc	%%g1,%3,%%g1\n"	\
"	mulscc	%%g1,%3,%%g1\n"	\
"	mulscc	%%g1,%3,%%g1\n"	\
"	mulscc	%%g1,%3,%%g1\n"	\
"	mulscc	%%g1,%3,%%g1\n"	\
"	mulscc	%%g1,%3,%%g1\n"	\
"	mulscc	%%g1,%3,%%g1\n"	\
"	mulscc	%%g1,%3,%%g1\n"	\
"	mulscc	%%g1,%3,%%g1\n"	\
"	mulscc	%%g1,%3,%%g1\n"	\
"	mulscc	%%g1,%3,%%g1\n"	\
"	mulscc	%%g1,%3,%%g1\n"	\
"	mulscc	%%g1,%3,%%g1\n"	\
"	mulscc	%%g1,%3,%%g1\n"	\
"	mulscc	%%g1,%3,%%g1\n"	\
"	mulscc	%%g1,%3,%%g1\n"	\
"	mulscc	%%g1,%3,%%g1\n"	\
"	mulscc	%%g1,%3,%%g1\n"	\
"	mulscc	%%g1,%3,%%g1\n"	\
"	mulscc	%%g1,%3,%%g1\n"	\
"	mulscc	%%g1,%3,%%g1\n"	\
"	mulscc	%%g1,%3,%%g1\n"	\
"	mulscc	%%g1,%3,%%g1\n"	\
"	mulscc	%%g1,%3,%%g1\n"	\
"	mulscc	%%g1,%3,%%g1\n"	\
"	mulscc	%%g1,%3,%%g1\n"	\
"	mulscc	%%g1,%3,%%g1\n"	\
"	mulscc	%%g1,0,%%g1\n"	\
"	add	%%g1,%%g2,%0\n"	\
"	rd	%%y,%1"							\
	: "=r" ((unsigned long int)(w1)), "=r" ((unsigned long int)(w0))\
	: "%rI" ((unsigned long int)(u)), "r" ((unsigned long int)(v))	\
       : "%g1", "%g2")
#define UMUL_TIME 39		/* 39 instructions */
/* It's quite necessary to add this much assembler for the sparc.
   The default udiv_qrnnd (in C) is more than 10 times slower!  */
#define udiv_qrnnd(q, r, n1, n0, d) \
  __asm__ ("! Inlined udiv_qrnnd\n"					\
"	mov	32,%%g1\n"						\
"	subcc	%1,%2,%%g0\n"						\
"1:	bcs	5f\n"							\
"	 addxcc %0,%0,%0	! shift n1n0 and a q-bit in lsb\n"	\
"	sub	%1,%2,%1	! this kills msb of n\n"		\
"	addx	%1,%1,%1	! so this can't give carry\n"		\
"	subcc	%%g1,1,%%g1\n"						\
"2:	bne	1b\n"							\
"	 subcc	%1,%2,%%g0\n"						\
"	bcs	3f\n"							\
"	 addxcc %0,%0,%0	! shift n1n0 and a q-bit in lsb\n"	\
"	b	3f\n"							\
"	 sub	%1,%2,%1	! this kills msb of n\n"		\
"4:	sub	%1,%2,%1\n"						\
"5:	addxcc	%1,%1,%1\n"						\
"	bcc	2b\n"							\
"	 subcc	%%g1,1,%%g1\n"						\
"! Got carry from n.  Subtract next step to cancel this carry.\n"	\
"	bne	4b\n"							\
"	 addcc	%0,%0,%0	! shift n1n0 and a 0-bit in lsb\n"	\
"	sub	%1,%2,%1\n"						\
"3:	xnor	%0,0,%0\n"						\
"	! End of inline udiv_qrnnd"					\
	: "=r&" ((unsigned long int)(q)), "=r&" ((unsigned long int)(r))\
	: "r" ((unsigned long int)(d)), "1" ((unsigned long int)(n1)),	\
	  "0" ((unsigned long int)(n0)) : "%g1")
#define UDIV_TIME (3+7*32)	/* 7 instructions/iteration. 32 iterations. */
#endif
#endif /* __sparc8__ */

#if defined (__vax__)
#define add_ssaaaa(sh, sl, ah, al, bh, bl) \
  __asm__ ("addl2 %5,%1\n"	\
"	adwc %3,%0"							\
	: "=g" ((unsigned long int)(sh)), "=&g" ((unsigned long int)(sl))\
	: "%0" ((unsigned long int)(ah)), "g" ((unsigned long int)(bh)),\
	  "%1" ((unsigned long int)(al)), "g" ((unsigned long int)(bl)))
#define sub_ddmmss(sh, sl, ah, al, bh, bl) \
  __asm__ ("subl2 %5,%1\n"	\
"	sbwc %3,%0"							\
	: "=g" ((unsigned long int)(sh)), "=&g" ((unsigned long int)(sl))\
	: "0" ((unsigned long int)(ah)), "g" ((unsigned long int)(bh)),	\
	  "1" ((unsigned long int)(al)), "g" ((unsigned long int)(bl)))
#define umul_ppmm(xh, xl, m0, m1) \
  do {									\
    union {long long int ll;struct {unsigned long int l, h;} i;} __xx;	\
    unsigned long int __m0 = (m0), __m1 = (m1);				\
    __asm__ ("emul %1,%2,$0,%0"						\
	 : "=r" (__xx.ll) : "g" (__m0), "g" (__m1));			\
    (xh) = __xx.i.h; (xl) = __xx.i.l;					\
    (xh) += ((((signed long int) __m0 >> 31) & __m1)			\
	     + (((signed long int) __m1 >> 31) & __m0));		\
  } while (0)
#endif /* __vax__ */

Bell Labs OSI certified Powered by Plan 9

(Return to Plan 9 Home Page)

Copyright © 2021 Plan 9 Foundation. All Rights Reserved.
Comments to webmaster@9p.io.