1 #line 2 "../src/kernel/hppa64/asm0.h"
2 /* $Id: asm0.h 11631 2009-02-28 22:03:38Z bill $
3 
4 Copyright (C) 2004  The PARI group.
5 
6 This file is part of the PARI/GP package.
7 
8 PARI/GP is free software; you can redistribute it and/or modify it under the
9 terms of the GNU General Public License as published by the Free Software
10 Foundation. It is distributed in the hope that it will be useful, but WITHOUT
11 ANY WARRANTY WHATSOEVER.
12 
13 Check the License for details. You should have received a copy of it, along
14 with the package; see the file 'COPYING'. If not, write to the Free Software
15 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
16 
17 /* This file was made using idea from Bruno Haible ix86 asm inline kernel
18  * and code from Nigel Smart hppa asm kernel. mulll was inspired from
19  * longlong.h from the GNU MP package.*/
20 
21 /*
22 ASM addll mulll
23 NOASM bfffo divll
24 */
25 #ifdef ASMINLINE
26 #define LOCAL_HIREMAINDER  register ulong hiremainder
27 #define LOCAL_OVERFLOW     register ulong overflow
28 
29 #define addll(a,b) \
30 ({ ulong __value, __arg1 = (a), __arg2 = (b); \
31    __asm__ ("add %2,%3,%0\n\tadd,dc %%r0,%%r0,%1" \
32         : "=r" (__value), "=r" (overflow) \
33         : "r" (__arg1), "r" (__arg2) \
34         : "cc"); \
35   __value; \
36 })
37 
38 #define addllx(a,b) \
39 ({ ulong __value, __arg1 = (a), __arg2 = (b); \
40    __asm__ ("sub %4,%5,%%r0\n\tadd,dc %2,%3,%0\n\tadd,dc %%r0,%%r0,%1" \
41         : "=r" (__value), "=r" (overflow) \
42         : "r" (__arg1), "r" (__arg2), "r" (overflow), "r" ((ulong) 1)\
43         : "cc"); \
44   __value; \
45 })
46 
47 #define subll(a,b) \
48 ({ ulong __value, __arg1 = (a), __arg2 = (b); \
49    __asm__ ("sub %2,%3,%0\n\tadd,dc %%r0,%%r0,%1\n\tsubi 1,%1,%1" \
50         : "=r" (__value), "=r" (overflow) \
51         : "r" (__arg1), "r" (__arg2) \
52         : "cc"); \
53   __value; \
54 })
55 
56 #define subllx(a,b) \
57 ({ ulong __value, __arg1 = (a), __arg2 = (b); \
58    __asm__ ("sub %%r0,%4,%%r0\n\tsub,db %2,%3,%0\n\tadd,dc %%r0,%%r0,%1\n\tsubi 1,%1,%1" \
59         : "=&r" (__value), "=r" (overflow) \
60         : "r" (__arg1), "r" (__arg2), "r" (overflow)\
61         : "cc"); \
62   __value; \
63 })
64 
65 /* z=a+b; c+= carry; return z */
66 #define __addllc(a,b,c) \
67 ({ ulong __value, __arg1 = (a), __arg2 = (b); \
68    __asm__ ("add %2,%3,%0\n\tadd,dc %4,%%r0,%1" \
69         : "=&r" (__value), "=r" (c) \
70         : "r" (__arg1), "r" (__arg2), "r" (c) \
71         : "cc"); \
72   __value; \
73 })
74 
75 /* 32x32->64 multiply*/
76 #define __mulhh(a,b) \
77 ({ unsigned int __arg1 = (a), __arg2 = (b); \
78    ulong __value; \
79    __asm__ ("xmpyu %1,%2,%0" \
80         : "=f" (__value) \
81         : "f" (__arg1), "f" (__arg2) \
82         : "cc"); \
83    __value; \
84 })
85 
86 #define mulll(arg1,arg2) \
87 ({ \
88   const ulong __x=(arg1), __y=(arg2); \
89   const ulong __xlo = LOWWORD(__x), __xhi = HIGHWORD(__x); \
90   const ulong __ylo = LOWWORD(__y), __yhi = HIGHWORD(__y); \
91   ulong __xylo,__xymid,__xyhi,__xymidhi,__xymidlo; \
92   ulong __xylh,__xyhl; \
93   __xylo = __mulhh(__xlo,__ylo); __xyhi = __mulhh(__xhi,__yhi); \
94   __xylh = __mulhh(__xlo,__yhi); __xyhl = __mulhh(__xhi,__ylo); \
95   __xymid = __xylh+__xyhl; \
96   if (__xymid<__xylh) __xyhi += (1UL << BITS_IN_HALFULONG); \
97   __xymidhi = HIGHWORD(__xymid); \
98   __xymidlo = __xymid << BITS_IN_HALFULONG; \
99   __xylo = __addllc(__xylo,__xymidlo,__xyhi); \
100   hiremainder = __xyhi + __xymidhi; \
101   __xylo; \
102 })
103 
104 #define addmul(arg1,arg2) \
105 ({ \
106   const ulong __x=(arg1), __y=(arg2); \
107   const ulong __xlo = LOWWORD(__x), __xhi = HIGHWORD(__x); \
108   const ulong __ylo = LOWWORD(__y), __yhi = HIGHWORD(__y); \
109   ulong __xylo,__xymid,__xyhi,__xymidhi,__xymidlo; \
110   ulong __xylh,__xyhl; \
111   __xylo = __mulhh(__xlo,__ylo); __xyhi = __mulhh(__xhi,__yhi); \
112   __xylh = __mulhh(__xlo,__yhi); __xyhl = __mulhh(__xhi,__ylo); \
113   __xymid = __xylh+__xyhl; \
114   if (__xymid<__xylh) __xyhi += (1UL << BITS_IN_HALFULONG); \
115   __xylo = __addllc(__xylo,hiremainder,__xyhi); \
116   __xymidhi = HIGHWORD(__xymid); \
117   __xymidlo = __xymid << BITS_IN_HALFULONG; \
118   __xylo = __addllc(__xylo,__xymidlo,__xyhi); \
119   hiremainder = __xyhi + __xymidhi; \
120   __xylo; \
121 })
122 
123 #endif
124