2 * Copyright (C) 2024 Mikulas Patocka
4 * This file is part of Ajla.
6 * Ajla 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 3 of the License, or (at your option) any later
11 * Ajla is distributed in the hope that it will be useful, but WITHOUT ANY
12 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
13 * A PARTICULAR PURPOSE. See the GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License along with
16 * Ajla. If not, see <https://www.gnu.org/licenses/>.
19 #if TYPE_BITS <= EFFICIENT_WORD_SIZE
20 #define maybe_inline ipret_inline
22 #define maybe_inline attr_noinline
25 #if defined(INLINE_ASM_GCC_X86) && !(defined(HAVE_BUILTIN_ADD_SUB_OVERFLOW) && !defined(INLINE_ASM_GCC_LABELS) && TYPE_BITS <= EFFICIENT_WORD_SIZE)
28 gen_x86_binary(add, type, utype, add, b, "=q", "q", "q"X86_ASM_M)
29 gen_x86_binary(subtract, type, utype, sub, b, "=q", "q", "q"X86_ASM_M)
30 gen_generic_multiply(type, utype)
32 gen_x86_binary(add, type, utype, add, w, "=r", "r", "r"X86_ASM_M)
33 gen_x86_binary(subtract, type, utype, sub, w, "=r", "r", "r"X86_ASM_M)
34 gen_x86_binary(multiply, type, utype, imul, w, "=r", "r", "r"X86_ASM_M)
36 gen_x86_binary(add, type, utype, add, l, "=r", "r", "r"X86_ASM_M)
37 gen_x86_binary(subtract, type, utype, sub, l, "=r", "r", "r"X86_ASM_M)
38 gen_x86_binary(multiply, type, utype, imul, l, "=r", "r", "r"X86_ASM_M)
39 #elif TYPE_MASK == 8 && defined(INLINE_ASM_GCC_I386)
40 gen_x86_binary_2reg(add, type, utype, add, adc, l, e)
41 gen_x86_binary_2reg(subtract, type, utype, sub, sbb, l, e)
42 gen_generic_multiply(type, utype)
44 gen_x86_binary(add, type, utype, add, q, "=r", "r", "r"X86_ASM_M)
45 gen_x86_binary(subtract, type, utype, sub, q, "=r", "r", "r"X86_ASM_M)
46 gen_x86_binary(multiply, type, utype, imul, q, "=r", "r", "r"X86_ASM_M)
47 #elif TYPE_MASK == 16 && !defined(INLINE_ASM_GCC_I386) && defined(HAVE_ASSEMBLER___INT128)
48 gen_x86_binary_2reg(add, type, utype, add, adc, q, r)
49 gen_x86_binary_2reg(subtract, type, utype, sub, sbb, q, r)
50 gen_generic_multiply(type, utype)
52 gen_generic_addsub(add, type, utype, 0)
53 gen_generic_addsub(subtract, type, utype, 1)
54 gen_generic_multiply(type, utype)
57 #elif defined(INLINE_ASM_GCC_ARM) && !(defined(HAVE_BUILTIN_ADD_SUB_OVERFLOW) && !defined(INLINE_ASM_GCC_LABELS) && TYPE_BITS <= EFFICIENT_WORD_SIZE)
59 gen_arm_addsub(add, type, utype, adds, "")
60 gen_arm_addsub(subtract, type, utype, subs, "")
62 gen_arm_multiply(type, utype)
64 gen_generic_multiply(type, utype)
66 #elif TYPE_MASK == 8 && ARM_VERSION >= 5
67 gen_arm_addsub_2reg(add, type, utype, adds, adcs)
68 gen_arm_addsub_2reg(subtract, type, utype, subs, sbcs)
69 gen_generic_multiply(type, utype)
71 gen_generic_addsub(add, type, utype, 0)
72 gen_generic_addsub(subtract, type, utype, 1)
73 gen_generic_multiply(type, utype)
76 #elif defined(INLINE_ASM_GCC_ARM64) && !(defined(HAVE_BUILTIN_ADD_SUB_OVERFLOW) && !defined(INLINE_ASM_GCC_LABELS))
79 gen_arm_addsub(add, type, utype, adds, "w")
80 gen_arm_addsub(subtract, type, utype, subs, "w")
81 gen_generic_multiply(type, utype)
83 gen_arm_addsub(add, type, utype, adds, "x")
84 gen_arm_addsub(subtract, type, utype, subs, "x")
85 gen_generic_multiply(type, utype)
86 #elif TYPE_MASK == 16 && defined(HAVE_ASSEMBLER___INT128)
87 gen_arm_addsub_2reg(add, type, utype, adds, adcs)
88 gen_arm_addsub_2reg(subtract, type, utype, subs, sbcs)
89 gen_generic_multiply(type, utype)
91 gen_generic_addsub(add, type, utype, 0)
92 gen_generic_addsub(subtract, type, utype, 1)
93 gen_generic_multiply(type, utype)
98 gen_generic_addsub(add, type, utype, 0)
99 gen_generic_addsub(subtract, type, utype, 1)
100 gen_generic_multiply(type, utype)
104 gen_generic_divmod(divide, type, utype, /)
105 #if INT_DIVIDE_ALT1_TYPES & TYPE_MASK
106 gen_generic_divmod_alt1(divide, type, utype)
108 gen_generic_divmod(modulo, type, utype, %)
109 #if INT_MODULO_ALT1_TYPES & TYPE_MASK
110 gen_generic_divmod_alt1(modulo, type, utype)
113 gen_generic_int_power(type, utype)
115 gen_generic_shl(type, utype)
116 gen_generic_shr(type, utype)
118 gen_generic_btx(bts, type, utype, 0)
119 gen_generic_btx(btr, type, utype, 1)
120 gen_generic_btx(btc, type, utype, 2)
121 gen_generic_bt(type, utype)
123 gen_generic_not(type, utype)
125 #if defined(INLINE_ASM_GCC_X86) && defined(INLINE_ASM_GCC_LABELS)
128 gen_x86_neg(type, utype, b, "q")
129 gen_x86_inc_dec(inc, type, utype, b, "q")
130 gen_x86_inc_dec(dec, type, utype, b, "q")
132 gen_x86_neg(type, utype, w, "r")
133 gen_x86_inc_dec(inc, type, utype, w, "r")
134 gen_x86_inc_dec(dec, type, utype, w, "r")
136 gen_x86_neg(type, utype, l, "r")
137 gen_x86_inc_dec(inc, type, utype, l, "r")
138 gen_x86_inc_dec(dec, type, utype, l, "r")
139 #elif TYPE_MASK == 8 && defined(INLINE_ASM_GCC_I386)
140 gen_x86_neg_2reg(type, utype, l, e)
141 gen_generic_inc_dec(type, utype)
143 gen_x86_neg(type, utype, q, "r")
144 gen_x86_inc_dec(inc, type, utype, q, "r")
145 gen_x86_inc_dec(dec, type, utype, q, "r")
146 #elif TYPE_MASK == 16 && !defined(INLINE_ASM_GCC_I386) && defined(HAVE_ASSEMBLER___INT128)
147 gen_x86_neg_2reg(type, utype, q, r)
148 gen_generic_inc_dec(type, utype)
150 gen_generic_neg(type, utype)
151 gen_generic_inc_dec(type, utype)
154 #elif defined(INLINE_ASM_GCC_ARM) && defined(INLINE_ASM_GCC_LABELS)
157 gen_arm_neg(type, utype, "")
158 #elif TYPE_MASK == 8 && defined(ARM_ASM_STRD)
159 gen_arm_neg_2reg(type, utype)
161 gen_generic_neg(type, utype)
163 gen_generic_inc_dec(type, utype)
165 #elif defined(INLINE_ASM_GCC_ARM64) && defined(INLINE_ASM_GCC_LABELS)
168 gen_arm_neg(type, utype, "w")
170 gen_arm_neg(type, utype, "x")
171 #elif TYPE_MASK == 16 && defined(HAVE_ASSEMBLER___INT128)
172 gen_arm_neg_2reg(type, utype)
174 gen_generic_neg(type, utype)
176 gen_generic_inc_dec(type, utype)
180 gen_generic_neg(type, utype)
181 gen_generic_inc_dec(type, utype)
185 gen_generic_int_bsfr(bsf, type, utype, TYPE_BITS, false)
186 gen_generic_int_bsfr(bsr, type, utype, TYPE_BITS, true)
187 gen_generic_int_popcnt(type, utype, TYPE_BITS)
188 #if INT_POPCNT_ALT1_TYPES & TYPE_MASK
189 gen_generic_int_popcnt_alt1(type, utype, TYPE_BITS)