1 #line 2 "../src/kernel/aarch64/asm0.h"
2 /* Copyright (C) 2015  The PARI group.
3 
4 This file is part of the PARI/GP package.
5 
6 PARI/GP is free software; you can redistribute it and/or modify it under the
7 terms of the GNU General Public License as published by the Free Software
8 Foundation; either version 2 of the License, or (at your option) any later
9 version. It is distributed in the hope that it will be useful, but WITHOUT
10 ANY WARRANTY WHATSOEVER.
11 
12 Check the License for details. You should have received a copy of it, along
13 with the package; see the file 'COPYING'. If not, write to the Free Software
14 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */
15 
16 /*
17 ASM addll mulll bfffo
18 NOASM divll
19 */
20 
21 #ifdef ASMINLINE
22 #define LOCAL_HIREMAINDER  register ulong hiremainder
23 #define LOCAL_OVERFLOW     register ulong overflow
24 
25 #define addll(a, b) \
26 __extension__ ({ ulong __value, __arg1 = (a), __arg2 = (b); \
27  __asm__ ("adds %0,%2,%3\n\tadc %1,xzr,xzr\n\t" \
28    : "=&r" (__value), "=&r" (overflow) \
29    : "r" (__arg1), "r" (__arg2): "cc"); \
30  __value; \
31 })
32 
33 #define addllx(a, b) \
34 __extension__ ({ ulong __value, __arg1 = (a), __arg2 = (b); \
35  __asm__ ("subs xzr,%4,#1\n\tadcs %0,%2,%3\n\tadc %1,xzr,xzr\n\t" \
36    : "=&r" (__value), "=&r" (overflow) \
37    : "r" (__arg1), "r" (__arg2), "r" (overflow): "cc"); \
38  __value; \
39 })
40 
41 #define addllx8(a,b,c,overflow) \
42 do { long *__arg1 = a, *__arg2 = b, *__out = c; \
43      ulong __temp1, __temp2; \
44      __asm__( \
45 "subs xzr,%6,#1\n\t" \
46 " ldr %0, [%3]     \n\t ldr %1, [%4]    \n\t adcs %1, %0, %1\n\t str %1, [%5]    \n\t" \
47 " ldr %0, [%3,-8]  \n\t ldr %1, [%4,-8] \n\t adcs %1, %0, %1\n\t str %1, [%5,-8] \n\t" \
48 " ldr %0, [%3,-16] \n\t ldr %1, [%4,-16]\n\t adcs %1, %0, %1\n\t str %1, [%5,-16]\n\t" \
49 " ldr %0, [%3,-24] \n\t ldr %1, [%4,-24]\n\t adcs %1, %0, %1\n\t str %1, [%5,-24]\n\t" \
50 " ldr %0, [%3,-32] \n\t ldr %1, [%4,-32]\n\t adcs %1, %0, %1\n\t str %1, [%5,-32]\n\t" \
51 " ldr %0, [%3,-40] \n\t ldr %1, [%4,-40]\n\t adcs %1, %0, %1\n\t str %1, [%5,-40]\n\t" \
52 " ldr %0, [%3,-48] \n\t ldr %1, [%4,-48]\n\t adcs %1, %0, %1\n\t str %1, [%5,-48]\n\t" \
53 " ldr %0, [%3,-56] \n\t ldr %1, [%4,-56]\n\t adcs %1, %0, %1\n\t str %1, [%5,-56]\n\t" \
54 "adc %2,xzr,xzr\n\t" \
55         : "=&r" (__temp1), "=&r" (__temp2), "=&r" (overflow) \
56         : "r" (__arg1), "r" (__arg2), "r" (__out), "r" (overflow), \
57           "0" ((ulong)0), "1" ((ulong)0) \
58         : "cc"); \
59 } while(0)
60 
61 #define subll(a, b) \
62 __extension__ ({ ulong __value, __arg1 = (a), __arg2 = (b); \
63  __asm__ ("subs %0,%2,%3\n\tngc %1,xzr\n\tsub %1,xzr,%1\n\t" \
64    : "=&r" (__value), "=&r" (overflow) \
65    : "r" (__arg1), "r" (__arg2): "cc"); \
66  __value; \
67 })
68 
69 #define subllx(a, b) \
70 __extension__ ({ ulong __value, __arg1 = (a), __arg2 = (b); \
71  __asm__ ("subs xzr,xzr,%4\n\tsbcs %0,%2,%3\n\tngc %1,xzr\n\tsub %1,xzr,%1\n\t" \
72    : "=&r" (__value), "=&r" (overflow) \
73    : "r" (__arg1), "r" (__arg2), "r" (overflow): "cc"); \
74  __value; \
75 })
76 
77 #define subllx8(a,b,c,overflow) \
78 do { long *__arg1 = a, *__arg2 = b, *__out = c; \
79      ulong __temp1, __temp2; \
80      __asm__( \
81 "subs xzr,xzr,%6\n\t" \
82 " ldr %0, [%3]     \n\t ldr %1, [%4]    \n\t sbcs %1, %0, %1\n\t str %1, [%5]    \n\t" \
83 " ldr %0, [%3,-8]  \n\t ldr %1, [%4,-8] \n\t sbcs %1, %0, %1\n\t str %1, [%5,-8] \n\t" \
84 " ldr %0, [%3,-16] \n\t ldr %1, [%4,-16]\n\t sbcs %1, %0, %1\n\t str %1, [%5,-16]\n\t" \
85 " ldr %0, [%3,-24] \n\t ldr %1, [%4,-24]\n\t sbcs %1, %0, %1\n\t str %1, [%5,-24]\n\t" \
86 " ldr %0, [%3,-32] \n\t ldr %1, [%4,-32]\n\t sbcs %1, %0, %1\n\t str %1, [%5,-32]\n\t" \
87 " ldr %0, [%3,-40] \n\t ldr %1, [%4,-40]\n\t sbcs %1, %0, %1\n\t str %1, [%5,-40]\n\t" \
88 " ldr %0, [%3,-48] \n\t ldr %1, [%4,-48]\n\t sbcs %1, %0, %1\n\t str %1, [%5,-48]\n\t" \
89 " ldr %0, [%3,-56] \n\t ldr %1, [%4,-56]\n\t sbcs %1, %0, %1\n\t str %1, [%5,-56]\n\t" \
90 "ngc %2,xzr\n\tsub %2,xzr,%2\n\t" \
91         : "=&r" (__temp1), "=&r" (__temp2), "=&r" (overflow) \
92         : "r" (__arg1), "r" (__arg2), "r" (__out), "r" (overflow), \
93           "0" ((ulong)0), "1" ((ulong)0) \
94         : "cc"); \
95 } while(0)
96 
97 #define mulll(a, b) \
98 __extension__ ({ ulong __value, __arg1 = (a), __arg2 = (b); \
99  __asm__ ("mul %0,%1,%2\n\t" \
100    : "=r" (__value) : "r" (__arg1), "r" (__arg2)); \
101  __asm__ ("umulh %0,%1,%2\n\t" \
102    : "=r" (hiremainder) : "r" (__arg1), "r" (__arg2)); \
103  __value; \
104 })
105 
106 #define addmul(a, b) \
107 __extension__ ({ ulong __value, __arg1 = (a), __arg2 = (b), __hi; \
108  __asm__ ("madd %0,%1,%2,%3\n\t" \
109    : "=r" (__value) : "r" (__arg1), "r" (__arg2), "r" (hiremainder)); \
110  __asm__ ("umulh %0,%1,%2\n\t" \
111    : "=r" (__hi) : "r" (__arg1), "r" (__arg2)); \
112  hiremainder = (__value < hiremainder) ? __hi+1: __hi;\
113  __value; \
114 })
115 
116 #define bfffo(a) \
117 __extension__ ({ ulong __a = (a), __value; \
118     __asm__ ("clz %0, %1" : "=r" (__value) : "r" (__a)); \
119     __value; \
120 })
121 
122 #endif
123