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