Mercurial > hg > CbC > CbC_gcc
comparison gcc/config/arm/arm-builtins.c @ 145:1830386684a0
gcc-9.2.0
author | anatofuz |
---|---|
date | Thu, 13 Feb 2020 11:34:05 +0900 |
parents | 84e7813d76e9 |
children |
comparison
equal
deleted
inserted
replaced
131:84e7813d76e9 | 145:1830386684a0 |
---|---|
1 /* Description of builtins used by the ARM backend. | 1 /* Description of builtins used by the ARM backend. |
2 Copyright (C) 2014-2018 Free Software Foundation, Inc. | 2 Copyright (C) 2014-2020 Free Software Foundation, Inc. |
3 | 3 |
4 This file is part of GCC. | 4 This file is part of GCC. |
5 | 5 |
6 GCC is free software; you can redistribute it and/or modify it | 6 GCC is free software; you can redistribute it and/or modify it |
7 under the terms of the GNU General Public License as published | 7 under the terms of the GNU General Public License as published |
39 #include "explow.h" | 39 #include "explow.h" |
40 #include "expr.h" | 40 #include "expr.h" |
41 #include "langhooks.h" | 41 #include "langhooks.h" |
42 #include "case-cfn-macros.h" | 42 #include "case-cfn-macros.h" |
43 #include "sbitmap.h" | 43 #include "sbitmap.h" |
44 #include "stringpool.h" | |
44 | 45 |
45 #define SIMD_MAX_BUILTIN_ARGS 7 | 46 #define SIMD_MAX_BUILTIN_ARGS 7 |
46 | 47 |
47 enum arm_type_qualifiers | 48 enum arm_type_qualifiers |
48 { | 49 { |
80 /* Lane indices for single lane structure loads and stores. */ | 81 /* Lane indices for single lane structure loads and stores. */ |
81 qualifier_struct_load_store_lane_index = 0x400, | 82 qualifier_struct_load_store_lane_index = 0x400, |
82 /* A void pointer. */ | 83 /* A void pointer. */ |
83 qualifier_void_pointer = 0x800, | 84 qualifier_void_pointer = 0x800, |
84 /* A const void pointer. */ | 85 /* A const void pointer. */ |
85 qualifier_const_void_pointer = 0x802 | 86 qualifier_const_void_pointer = 0x802, |
87 /* Lane indices selected in pairs - must be within range of previous | |
88 argument = a vector. */ | |
89 qualifier_lane_pair_index = 0x1000, | |
90 /* Lane indices selected in quadtuplets - must be within range of previous | |
91 argument = a vector. */ | |
92 qualifier_lane_quadtup_index = 0x2000 | |
86 }; | 93 }; |
87 | 94 |
88 /* The qualifier_internal allows generation of a unary builtin from | 95 /* The qualifier_internal allows generation of a unary builtin from |
89 a pattern with a third pseudo-operand such as a match_scratch. | 96 a pattern with a third pseudo-operand such as a match_scratch. |
90 T (T). */ | 97 T (T). */ |
116 arm_unsigned_uternop_qualifiers[SIMD_MAX_BUILTIN_ARGS] | 123 arm_unsigned_uternop_qualifiers[SIMD_MAX_BUILTIN_ARGS] |
117 = { qualifier_unsigned, qualifier_unsigned, qualifier_unsigned, | 124 = { qualifier_unsigned, qualifier_unsigned, qualifier_unsigned, |
118 qualifier_unsigned }; | 125 qualifier_unsigned }; |
119 #define UTERNOP_QUALIFIERS (arm_unsigned_uternop_qualifiers) | 126 #define UTERNOP_QUALIFIERS (arm_unsigned_uternop_qualifiers) |
120 | 127 |
128 /* T (T, unsigned T, T). */ | |
129 static enum arm_type_qualifiers | |
130 arm_usternop_qualifiers[SIMD_MAX_BUILTIN_ARGS] | |
131 = { qualifier_none, qualifier_none, qualifier_unsigned, | |
132 qualifier_none }; | |
133 #define USTERNOP_QUALIFIERS (arm_usternop_qualifiers) | |
134 | |
121 /* T (T, immediate). */ | 135 /* T (T, immediate). */ |
122 static enum arm_type_qualifiers | 136 static enum arm_type_qualifiers |
123 arm_binop_imm_qualifiers[SIMD_MAX_BUILTIN_ARGS] | 137 arm_binop_imm_qualifiers[SIMD_MAX_BUILTIN_ARGS] |
124 = { qualifier_none, qualifier_none, qualifier_immediate }; | 138 = { qualifier_none, qualifier_none, qualifier_immediate }; |
125 #define BINOP_IMM_QUALIFIERS (arm_binop_imm_qualifiers) | 139 #define BINOP_IMM_QUALIFIERS (arm_binop_imm_qualifiers) |
140 | |
141 /* T (T, unsigned immediate). */ | |
142 static enum arm_type_qualifiers | |
143 arm_sat_binop_imm_qualifiers[SIMD_MAX_BUILTIN_ARGS] | |
144 = { qualifier_unsigned, qualifier_none, qualifier_unsigned_immediate }; | |
145 #define SAT_BINOP_UNSIGNED_IMM_QUALIFIERS \ | |
146 (arm_sat_binop_imm_qualifiers) | |
147 | |
148 /* unsigned T (T, unsigned immediate). */ | |
149 static enum arm_type_qualifiers | |
150 arm_unsigned_sat_binop_unsigned_imm_qualifiers[SIMD_MAX_BUILTIN_ARGS] | |
151 = { qualifier_unsigned, qualifier_none, qualifier_unsigned_immediate }; | |
152 #define UNSIGNED_SAT_BINOP_UNSIGNED_IMM_QUALIFIERS \ | |
153 (arm_unsigned_sat_binop_unsigned_imm_qualifiers) | |
126 | 154 |
127 /* T (T, lane index). */ | 155 /* T (T, lane index). */ |
128 static enum arm_type_qualifiers | 156 static enum arm_type_qualifiers |
129 arm_getlane_qualifiers[SIMD_MAX_BUILTIN_ARGS] | 157 arm_getlane_qualifiers[SIMD_MAX_BUILTIN_ARGS] |
130 = { qualifier_none, qualifier_none, qualifier_lane_index }; | 158 = { qualifier_none, qualifier_none, qualifier_lane_index }; |
142 arm_mac_lane_qualifiers[SIMD_MAX_BUILTIN_ARGS] | 170 arm_mac_lane_qualifiers[SIMD_MAX_BUILTIN_ARGS] |
143 = { qualifier_none, qualifier_none, qualifier_none, | 171 = { qualifier_none, qualifier_none, qualifier_none, |
144 qualifier_none, qualifier_lane_index }; | 172 qualifier_none, qualifier_lane_index }; |
145 #define MAC_LANE_QUALIFIERS (arm_mac_lane_qualifiers) | 173 #define MAC_LANE_QUALIFIERS (arm_mac_lane_qualifiers) |
146 | 174 |
175 /* T (T, T, T, lane pair index). */ | |
176 static enum arm_type_qualifiers | |
177 arm_mac_lane_pair_qualifiers[SIMD_MAX_BUILTIN_ARGS] | |
178 = { qualifier_none, qualifier_none, qualifier_none, | |
179 qualifier_none, qualifier_lane_pair_index }; | |
180 #define MAC_LANE_PAIR_QUALIFIERS (arm_mac_lane_pair_qualifiers) | |
181 | |
147 /* unsigned T (unsigned T, unsigned T, unsigend T, lane index). */ | 182 /* unsigned T (unsigned T, unsigned T, unsigend T, lane index). */ |
148 static enum arm_type_qualifiers | 183 static enum arm_type_qualifiers |
149 arm_umac_lane_qualifiers[SIMD_MAX_BUILTIN_ARGS] | 184 arm_umac_lane_qualifiers[SIMD_MAX_BUILTIN_ARGS] |
150 = { qualifier_unsigned, qualifier_unsigned, qualifier_unsigned, | 185 = { qualifier_unsigned, qualifier_unsigned, qualifier_unsigned, |
151 qualifier_unsigned, qualifier_lane_index }; | 186 qualifier_unsigned, qualifier_lane_index }; |
152 #define UMAC_LANE_QUALIFIERS (arm_umac_lane_qualifiers) | 187 #define UMAC_LANE_QUALIFIERS (arm_umac_lane_qualifiers) |
188 | |
189 /* T (T, unsigned T, T, lane index). */ | |
190 static enum arm_type_qualifiers | |
191 arm_usmac_lane_quadtup_qualifiers[SIMD_MAX_BUILTIN_ARGS] | |
192 = { qualifier_none, qualifier_none, qualifier_unsigned, | |
193 qualifier_none, qualifier_lane_quadtup_index }; | |
194 #define USMAC_LANE_QUADTUP_QUALIFIERS (arm_usmac_lane_quadtup_qualifiers) | |
195 | |
196 /* T (T, T, unsigend T, lane index). */ | |
197 static enum arm_type_qualifiers | |
198 arm_sumac_lane_quadtup_qualifiers[SIMD_MAX_BUILTIN_ARGS] | |
199 = { qualifier_none, qualifier_none, qualifier_none, | |
200 qualifier_unsigned, qualifier_lane_quadtup_index }; | |
201 #define SUMAC_LANE_QUADTUP_QUALIFIERS (arm_sumac_lane_quadtup_qualifiers) | |
153 | 202 |
154 /* T (T, T, immediate). */ | 203 /* T (T, T, immediate). */ |
155 static enum arm_type_qualifiers | 204 static enum arm_type_qualifiers |
156 arm_ternop_imm_qualifiers[SIMD_MAX_BUILTIN_ARGS] | 205 arm_ternop_imm_qualifiers[SIMD_MAX_BUILTIN_ARGS] |
157 = { qualifier_none, qualifier_none, qualifier_none, qualifier_immediate }; | 206 = { qualifier_none, qualifier_none, qualifier_none, qualifier_immediate }; |
273 arm_storestruct_lane_qualifiers[SIMD_MAX_BUILTIN_ARGS] | 322 arm_storestruct_lane_qualifiers[SIMD_MAX_BUILTIN_ARGS] |
274 = { qualifier_void, qualifier_pointer_map_mode, | 323 = { qualifier_void, qualifier_pointer_map_mode, |
275 qualifier_none, qualifier_struct_load_store_lane_index }; | 324 qualifier_none, qualifier_struct_load_store_lane_index }; |
276 #define STORE1LANE_QUALIFIERS (arm_storestruct_lane_qualifiers) | 325 #define STORE1LANE_QUALIFIERS (arm_storestruct_lane_qualifiers) |
277 | 326 |
327 /* int (void). */ | |
328 static enum arm_type_qualifiers | |
329 arm_sat_occurred_qualifiers[SIMD_MAX_BUILTIN_ARGS] | |
330 = { qualifier_none, qualifier_void }; | |
331 #define SAT_OCCURRED_QUALIFIERS (arm_sat_occurred_qualifiers) | |
332 | |
333 /* void (int). */ | |
334 static enum arm_type_qualifiers | |
335 arm_set_sat_qualifiers[SIMD_MAX_BUILTIN_ARGS] | |
336 = { qualifier_void, qualifier_none }; | |
337 #define SET_SAT_QUALIFIERS (arm_set_sat_qualifiers) | |
338 | |
278 #define v8qi_UP E_V8QImode | 339 #define v8qi_UP E_V8QImode |
279 #define v4hi_UP E_V4HImode | 340 #define v4hi_UP E_V4HImode |
280 #define v4hf_UP E_V4HFmode | 341 #define v4hf_UP E_V4HFmode |
342 #define v4bf_UP E_V4BFmode | |
281 #define v2si_UP E_V2SImode | 343 #define v2si_UP E_V2SImode |
282 #define v2sf_UP E_V2SFmode | 344 #define v2sf_UP E_V2SFmode |
283 #define di_UP E_DImode | 345 #define di_UP E_DImode |
284 #define v16qi_UP E_V16QImode | 346 #define v16qi_UP E_V16QImode |
285 #define v8hi_UP E_V8HImode | 347 #define v8hi_UP E_V8HImode |
286 #define v8hf_UP E_V8HFmode | 348 #define v8hf_UP E_V8HFmode |
349 #define v8bf_UP E_V8BFmode | |
287 #define v4si_UP E_V4SImode | 350 #define v4si_UP E_V4SImode |
288 #define v4sf_UP E_V4SFmode | 351 #define v4sf_UP E_V4SFmode |
289 #define v2di_UP E_V2DImode | 352 #define v2di_UP E_V2DImode |
290 #define ti_UP E_TImode | 353 #define ti_UP E_TImode |
291 #define ei_UP E_EImode | 354 #define ei_UP E_EImode |
292 #define oi_UP E_OImode | 355 #define oi_UP E_OImode |
293 #define hf_UP E_HFmode | 356 #define hf_UP E_HFmode |
357 #define bf_UP E_BFmode | |
294 #define si_UP E_SImode | 358 #define si_UP E_SImode |
295 #define void_UP E_VOIDmode | 359 #define void_UP E_VOIDmode |
296 | 360 #define sf_UP E_SFmode |
297 #define UP(X) X##_UP | 361 #define UP(X) X##_UP |
298 | 362 |
299 typedef struct { | 363 typedef struct { |
300 const char *name; | 364 const char *name; |
301 machine_mode mode; | 365 machine_mode mode; |
364 }; | 428 }; |
365 | 429 |
366 #undef CF | 430 #undef CF |
367 #undef VAR1 | 431 #undef VAR1 |
368 #define VAR1(T, N, A) \ | 432 #define VAR1(T, N, A) \ |
369 {#N, UP (A), CODE_FOR_##N, 0, T##_QUALIFIERS}, | 433 {#N, UP (A), CODE_FOR_arm_##N, 0, T##_QUALIFIERS}, |
370 | 434 |
371 static arm_builtin_datum acle_builtin_data[] = | 435 static arm_builtin_datum acle_builtin_data[] = |
372 { | 436 { |
373 #include "arm_acle_builtins.def" | 437 #include "arm_acle_builtins.def" |
374 }; | 438 }; |
662 #undef VAR1 | 726 #undef VAR1 |
663 #define VAR1(T, N, X) \ | 727 #define VAR1(T, N, X) \ |
664 ARM_BUILTIN_##N, | 728 ARM_BUILTIN_##N, |
665 | 729 |
666 ARM_BUILTIN_ACLE_BASE, | 730 ARM_BUILTIN_ACLE_BASE, |
731 ARM_BUILTIN_SAT_IMM_CHECK = ARM_BUILTIN_ACLE_BASE, | |
667 | 732 |
668 #include "arm_acle_builtins.def" | 733 #include "arm_acle_builtins.def" |
669 | 734 |
670 ARM_BUILTIN_MAX | 735 ARM_BUILTIN_MAX |
671 }; | 736 }; |
766 }; | 831 }; |
767 #undef ENTRY | 832 #undef ENTRY |
768 | 833 |
769 /* The user-visible __fp16 type. */ | 834 /* The user-visible __fp16 type. */ |
770 tree arm_fp16_type_node = NULL_TREE; | 835 tree arm_fp16_type_node = NULL_TREE; |
836 | |
837 /* Back-end node type for brain float (bfloat) types. */ | |
838 tree arm_bf16_type_node = NULL_TREE; | |
839 tree arm_bf16_ptr_type_node = NULL_TREE; | |
840 | |
771 static tree arm_simd_intOI_type_node = NULL_TREE; | 841 static tree arm_simd_intOI_type_node = NULL_TREE; |
772 static tree arm_simd_intEI_type_node = NULL_TREE; | 842 static tree arm_simd_intEI_type_node = NULL_TREE; |
773 static tree arm_simd_intCI_type_node = NULL_TREE; | 843 static tree arm_simd_intCI_type_node = NULL_TREE; |
774 static tree arm_simd_intXI_type_node = NULL_TREE; | 844 static tree arm_simd_intXI_type_node = NULL_TREE; |
775 static tree arm_simd_polyQI_type_node = NULL_TREE; | 845 static tree arm_simd_polyQI_type_node = NULL_TREE; |
816 | 886 |
817 const char * | 887 const char * |
818 arm_mangle_builtin_type (const_tree type) | 888 arm_mangle_builtin_type (const_tree type) |
819 { | 889 { |
820 const char *mangle; | 890 const char *mangle; |
821 /* Walk through all the AArch64 builtins types tables to filter out the | 891 /* Walk through all the Arm builtins types tables to filter out the |
822 incoming type. */ | 892 incoming type. */ |
823 if ((mangle = arm_mangle_builtin_vector_type (type)) | 893 if ((mangle = arm_mangle_builtin_vector_type (type)) |
824 || (mangle = arm_mangle_builtin_scalar_type (type))) | 894 || (mangle = arm_mangle_builtin_scalar_type (type))) |
825 return mangle; | 895 return mangle; |
826 | 896 |
857 return arm_fp16_type_node; | 927 return arm_fp16_type_node; |
858 case E_SFmode: | 928 case E_SFmode: |
859 return float_type_node; | 929 return float_type_node; |
860 case E_DFmode: | 930 case E_DFmode: |
861 return double_type_node; | 931 return double_type_node; |
932 case E_BFmode: | |
933 return arm_bf16_type_node; | |
862 default: | 934 default: |
863 gcc_unreachable (); | 935 gcc_unreachable (); |
864 } | 936 } |
865 #undef QUAL_TYPE | 937 #undef QUAL_TYPE |
866 } | 938 } |
962 arm_simd_types[Float16x4_t].eltype = arm_fp16_type_node; | 1034 arm_simd_types[Float16x4_t].eltype = arm_fp16_type_node; |
963 arm_simd_types[Float16x8_t].eltype = arm_fp16_type_node; | 1035 arm_simd_types[Float16x8_t].eltype = arm_fp16_type_node; |
964 arm_simd_types[Float32x2_t].eltype = float_type_node; | 1036 arm_simd_types[Float32x2_t].eltype = float_type_node; |
965 arm_simd_types[Float32x4_t].eltype = float_type_node; | 1037 arm_simd_types[Float32x4_t].eltype = float_type_node; |
966 | 1038 |
1039 /* Init Bfloat vector types with underlying __bf16 scalar type. */ | |
1040 arm_simd_types[Bfloat16x4_t].eltype = arm_bf16_type_node; | |
1041 arm_simd_types[Bfloat16x8_t].eltype = arm_bf16_type_node; | |
1042 | |
967 for (i = 0; i < nelts; i++) | 1043 for (i = 0; i < nelts; i++) |
968 { | 1044 { |
969 tree eltype = arm_simd_types[i].eltype; | 1045 tree eltype = arm_simd_types[i].eltype; |
970 machine_mode mode = arm_simd_types[i].mode; | 1046 machine_mode mode = arm_simd_types[i].mode; |
971 | 1047 |
1147 fndecl = add_builtin_function (namebuf, ftype, fcode, BUILT_IN_MD, | 1223 fndecl = add_builtin_function (namebuf, ftype, fcode, BUILT_IN_MD, |
1148 NULL, NULL_TREE); | 1224 NULL, NULL_TREE); |
1149 arm_builtin_decls[fcode] = fndecl; | 1225 arm_builtin_decls[fcode] = fndecl; |
1150 } | 1226 } |
1151 | 1227 |
1228 /* Initialize the backend REAL_TYPE type supporting bfloat types. */ | |
1229 static void | |
1230 arm_init_bf16_types (void) | |
1231 { | |
1232 arm_bf16_type_node = make_node (REAL_TYPE); | |
1233 TYPE_PRECISION (arm_bf16_type_node) = 16; | |
1234 SET_TYPE_MODE (arm_bf16_type_node, BFmode); | |
1235 layout_type (arm_bf16_type_node); | |
1236 | |
1237 lang_hooks.types.register_builtin_type (arm_bf16_type_node, "__bf16"); | |
1238 arm_bf16_ptr_type_node = build_pointer_type (arm_bf16_type_node); | |
1239 } | |
1240 | |
1152 /* Set up ACLE builtins, even builtins for instructions that are not | 1241 /* Set up ACLE builtins, even builtins for instructions that are not |
1153 in the current target ISA to allow the user to compile particular modules | 1242 in the current target ISA to allow the user to compile particular modules |
1154 with different target specific options that differ from the command line | 1243 with different target specific options that differ from the command line |
1155 options. Such builtins will be rejected in arm_expand_builtin. */ | 1244 options. Such builtins will be rejected in arm_expand_builtin. */ |
1156 | 1245 |
1157 static void | 1246 static void |
1158 arm_init_acle_builtins (void) | 1247 arm_init_acle_builtins (void) |
1159 { | 1248 { |
1160 unsigned int i, fcode = ARM_BUILTIN_ACLE_PATTERN_START; | 1249 unsigned int i, fcode = ARM_BUILTIN_ACLE_PATTERN_START; |
1250 | |
1251 tree sat_check_fpr = build_function_type_list (void_type_node, | |
1252 intSI_type_node, | |
1253 intSI_type_node, | |
1254 intSI_type_node, | |
1255 NULL); | |
1256 arm_builtin_decls[ARM_BUILTIN_SAT_IMM_CHECK] | |
1257 = add_builtin_function ("__builtin_sat_imm_check", sat_check_fpr, | |
1258 ARM_BUILTIN_SAT_IMM_CHECK, BUILT_IN_MD, | |
1259 NULL, NULL_TREE); | |
1161 | 1260 |
1162 for (i = 0; i < ARRAY_SIZE (acle_builtin_data); i++, fcode++) | 1261 for (i = 0; i < ARRAY_SIZE (acle_builtin_data); i++, fcode++) |
1163 { | 1262 { |
1164 arm_builtin_datum *d = &acle_builtin_data[i]; | 1263 arm_builtin_datum *d = &acle_builtin_data[i]; |
1165 arm_init_builtin (fcode, d, "__builtin_arm"); | 1264 arm_init_builtin (fcode, d, "__builtin_arm"); |
1905 | 2004 |
1906 /* This creates the arm_simd_floatHF_type_node so must come before | 2005 /* This creates the arm_simd_floatHF_type_node so must come before |
1907 arm_init_neon_builtins which uses it. */ | 2006 arm_init_neon_builtins which uses it. */ |
1908 arm_init_fp16_builtins (); | 2007 arm_init_fp16_builtins (); |
1909 | 2008 |
2009 arm_init_bf16_types (); | |
2010 | |
1910 if (TARGET_MAYBE_HARD_FLOAT) | 2011 if (TARGET_MAYBE_HARD_FLOAT) |
1911 { | 2012 { |
1912 arm_init_neon_builtins (); | 2013 arm_init_neon_builtins (); |
1913 arm_init_vfp_builtins (); | 2014 arm_init_vfp_builtins (); |
1914 arm_init_crypto_builtins (); | 2015 arm_init_crypto_builtins (); |
1981 tree arg2 = CALL_EXPR_ARG (exp, 2); | 2082 tree arg2 = CALL_EXPR_ARG (exp, 2); |
1982 | 2083 |
1983 rtx op0 = expand_normal (arg0); | 2084 rtx op0 = expand_normal (arg0); |
1984 rtx op1 = expand_normal (arg1); | 2085 rtx op1 = expand_normal (arg1); |
1985 rtx op2 = expand_normal (arg2); | 2086 rtx op2 = expand_normal (arg2); |
1986 rtx op3 = NULL_RTX; | 2087 |
1987 | |
1988 /* The sha1c, sha1p, sha1m crypto builtins require a different vec_select | |
1989 lane operand depending on endianness. */ | |
1990 bool builtin_sha1cpm_p = false; | |
1991 | |
1992 if (insn_data[icode].n_operands == 5) | |
1993 { | |
1994 gcc_assert (icode == CODE_FOR_crypto_sha1c | |
1995 || icode == CODE_FOR_crypto_sha1p | |
1996 || icode == CODE_FOR_crypto_sha1m); | |
1997 builtin_sha1cpm_p = true; | |
1998 } | |
1999 machine_mode tmode = insn_data[icode].operand[0].mode; | 2088 machine_mode tmode = insn_data[icode].operand[0].mode; |
2000 machine_mode mode0 = insn_data[icode].operand[1].mode; | 2089 machine_mode mode0 = insn_data[icode].operand[1].mode; |
2001 machine_mode mode1 = insn_data[icode].operand[2].mode; | 2090 machine_mode mode1 = insn_data[icode].operand[2].mode; |
2002 machine_mode mode2 = insn_data[icode].operand[3].mode; | 2091 machine_mode mode2 = insn_data[icode].operand[3].mode; |
2003 | |
2004 | 2092 |
2005 if (VECTOR_MODE_P (mode0)) | 2093 if (VECTOR_MODE_P (mode0)) |
2006 op0 = safe_vector_operand (op0, mode0); | 2094 op0 = safe_vector_operand (op0, mode0); |
2007 if (VECTOR_MODE_P (mode1)) | 2095 if (VECTOR_MODE_P (mode1)) |
2008 op1 = safe_vector_operand (op1, mode1); | 2096 op1 = safe_vector_operand (op1, mode1); |
2022 op0 = copy_to_mode_reg (mode0, op0); | 2110 op0 = copy_to_mode_reg (mode0, op0); |
2023 if (! (*insn_data[icode].operand[2].predicate) (op1, mode1)) | 2111 if (! (*insn_data[icode].operand[2].predicate) (op1, mode1)) |
2024 op1 = copy_to_mode_reg (mode1, op1); | 2112 op1 = copy_to_mode_reg (mode1, op1); |
2025 if (! (*insn_data[icode].operand[3].predicate) (op2, mode2)) | 2113 if (! (*insn_data[icode].operand[3].predicate) (op2, mode2)) |
2026 op2 = copy_to_mode_reg (mode2, op2); | 2114 op2 = copy_to_mode_reg (mode2, op2); |
2027 if (builtin_sha1cpm_p) | 2115 |
2028 op3 = GEN_INT (TARGET_BIG_END ? 1 : 0); | 2116 pat = GEN_FCN (icode) (target, op0, op1, op2); |
2029 | |
2030 if (builtin_sha1cpm_p) | |
2031 pat = GEN_FCN (icode) (target, op0, op1, op2, op3); | |
2032 else | |
2033 pat = GEN_FCN (icode) (target, op0, op1, op2); | |
2034 if (! pat) | 2117 if (! pat) |
2035 return 0; | 2118 return 0; |
2036 emit_insn (pat); | 2119 emit_insn (pat); |
2037 return target; | 2120 return target; |
2038 } | 2121 } |
2084 tree exp, rtx target, int do_load) | 2167 tree exp, rtx target, int do_load) |
2085 { | 2168 { |
2086 rtx pat; | 2169 rtx pat; |
2087 tree arg0 = CALL_EXPR_ARG (exp, 0); | 2170 tree arg0 = CALL_EXPR_ARG (exp, 0); |
2088 rtx op0 = expand_normal (arg0); | 2171 rtx op0 = expand_normal (arg0); |
2089 rtx op1 = NULL_RTX; | |
2090 machine_mode tmode = insn_data[icode].operand[0].mode; | 2172 machine_mode tmode = insn_data[icode].operand[0].mode; |
2091 machine_mode mode0 = insn_data[icode].operand[1].mode; | 2173 machine_mode mode0 = insn_data[icode].operand[1].mode; |
2092 bool builtin_sha1h_p = false; | |
2093 | |
2094 if (insn_data[icode].n_operands == 3) | |
2095 { | |
2096 gcc_assert (icode == CODE_FOR_crypto_sha1h); | |
2097 builtin_sha1h_p = true; | |
2098 } | |
2099 | 2174 |
2100 if (! target | 2175 if (! target |
2101 || GET_MODE (target) != tmode | 2176 || GET_MODE (target) != tmode |
2102 || ! (*insn_data[icode].operand[0].predicate) (target, tmode)) | 2177 || ! (*insn_data[icode].operand[0].predicate) (target, tmode)) |
2103 target = gen_reg_rtx (tmode); | 2178 target = gen_reg_rtx (tmode); |
2109 op0 = safe_vector_operand (op0, mode0); | 2184 op0 = safe_vector_operand (op0, mode0); |
2110 | 2185 |
2111 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0)) | 2186 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0)) |
2112 op0 = copy_to_mode_reg (mode0, op0); | 2187 op0 = copy_to_mode_reg (mode0, op0); |
2113 } | 2188 } |
2114 if (builtin_sha1h_p) | 2189 |
2115 op1 = GEN_INT (TARGET_BIG_END ? 1 : 0); | 2190 pat = GEN_FCN (icode) (target, op0); |
2116 | 2191 |
2117 if (builtin_sha1h_p) | |
2118 pat = GEN_FCN (icode) (target, op0, op1); | |
2119 else | |
2120 pat = GEN_FCN (icode) (target, op0); | |
2121 if (! pat) | 2192 if (! pat) |
2122 return 0; | 2193 return 0; |
2123 emit_insn (pat); | 2194 emit_insn (pat); |
2124 return target; | 2195 return target; |
2125 } | 2196 } |
2127 typedef enum { | 2198 typedef enum { |
2128 ARG_BUILTIN_COPY_TO_REG, | 2199 ARG_BUILTIN_COPY_TO_REG, |
2129 ARG_BUILTIN_CONSTANT, | 2200 ARG_BUILTIN_CONSTANT, |
2130 ARG_BUILTIN_LANE_INDEX, | 2201 ARG_BUILTIN_LANE_INDEX, |
2131 ARG_BUILTIN_STRUCT_LOAD_STORE_LANE_INDEX, | 2202 ARG_BUILTIN_STRUCT_LOAD_STORE_LANE_INDEX, |
2203 ARG_BUILTIN_LANE_PAIR_INDEX, | |
2204 ARG_BUILTIN_LANE_QUADTUP_INDEX, | |
2132 ARG_BUILTIN_NEON_MEMORY, | 2205 ARG_BUILTIN_NEON_MEMORY, |
2133 ARG_BUILTIN_MEMORY, | 2206 ARG_BUILTIN_MEMORY, |
2134 ARG_BUILTIN_STOP | 2207 ARG_BUILTIN_STOP |
2135 } builtin_arg; | 2208 } builtin_arg; |
2136 | 2209 |
2264 if (CONST_INT_P (op[argc])) | 2337 if (CONST_INT_P (op[argc])) |
2265 { | 2338 { |
2266 machine_mode vmode = mode[argc - 1]; | 2339 machine_mode vmode = mode[argc - 1]; |
2267 neon_lane_bounds (op[argc], 0, GET_MODE_NUNITS (vmode), exp); | 2340 neon_lane_bounds (op[argc], 0, GET_MODE_NUNITS (vmode), exp); |
2268 } | 2341 } |
2269 /* If the lane index isn't a constant then the next | 2342 /* If the lane index isn't a constant then error out. */ |
2270 case will error. */ | 2343 goto constant_arg; |
2271 /* Fall through. */ | 2344 |
2345 case ARG_BUILTIN_LANE_PAIR_INDEX: | |
2346 /* Previous argument must be a vector, which this indexes. The | |
2347 indexing will always select i and i+1 out of the vector, which | |
2348 puts a limit on i. */ | |
2349 gcc_assert (argc > 0); | |
2350 if (CONST_INT_P (op[argc])) | |
2351 { | |
2352 machine_mode vmode = mode[argc - 1]; | |
2353 neon_lane_bounds (op[argc], 0, | |
2354 GET_MODE_NUNITS (vmode) / 2, exp); | |
2355 } | |
2356 /* If the lane index isn't a constant then error out. */ | |
2357 goto constant_arg; | |
2358 | |
2359 case ARG_BUILTIN_LANE_QUADTUP_INDEX: | |
2360 /* Previous argument must be a vector, which this indexes. */ | |
2361 gcc_assert (argc > 0); | |
2362 if (CONST_INT_P (op[argc])) | |
2363 { | |
2364 machine_mode vmode = mode[argc - 1]; | |
2365 neon_lane_bounds (op[argc], 0, | |
2366 GET_MODE_NUNITS (vmode) / 4, exp); | |
2367 } | |
2368 /* If the lane index isn't a constant then error out. */ | |
2369 goto constant_arg; | |
2370 | |
2272 case ARG_BUILTIN_CONSTANT: | 2371 case ARG_BUILTIN_CONSTANT: |
2273 constant_arg: | 2372 constant_arg: |
2274 if (!(*insn_data[icode].operand[opno].predicate) | 2373 if (!(*insn_data[icode].operand[opno].predicate) |
2275 (op[argc], mode[argc])) | 2374 (op[argc], mode[argc])) |
2276 { | 2375 { |
2311 } | 2410 } |
2312 | 2411 |
2313 if (have_retval) | 2412 if (have_retval) |
2314 switch (argc) | 2413 switch (argc) |
2315 { | 2414 { |
2415 case 0: | |
2416 pat = GEN_FCN (icode) (target); | |
2417 break; | |
2316 case 1: | 2418 case 1: |
2317 pat = GEN_FCN (icode) (target, op[0]); | 2419 pat = GEN_FCN (icode) (target, op[0]); |
2318 break; | 2420 break; |
2319 | 2421 |
2320 case 2: | 2422 case 2: |
2425 int operands_k = k - is_void; | 2527 int operands_k = k - is_void; |
2426 int expr_args_k = k - 1; | 2528 int expr_args_k = k - 1; |
2427 | 2529 |
2428 if (d->qualifiers[qualifiers_k] & qualifier_lane_index) | 2530 if (d->qualifiers[qualifiers_k] & qualifier_lane_index) |
2429 args[k] = ARG_BUILTIN_LANE_INDEX; | 2531 args[k] = ARG_BUILTIN_LANE_INDEX; |
2532 else if (d->qualifiers[qualifiers_k] & qualifier_lane_pair_index) | |
2533 args[k] = ARG_BUILTIN_LANE_PAIR_INDEX; | |
2534 else if (d->qualifiers[qualifiers_k] & qualifier_lane_quadtup_index) | |
2535 args[k] = ARG_BUILTIN_LANE_QUADTUP_INDEX; | |
2430 else if (d->qualifiers[qualifiers_k] & qualifier_struct_load_store_lane_index) | 2536 else if (d->qualifiers[qualifiers_k] & qualifier_struct_load_store_lane_index) |
2431 args[k] = ARG_BUILTIN_STRUCT_LOAD_STORE_LANE_INDEX; | 2537 args[k] = ARG_BUILTIN_STRUCT_LOAD_STORE_LANE_INDEX; |
2432 else if (d->qualifiers[qualifiers_k] & qualifier_immediate) | 2538 else if (d->qualifiers[qualifiers_k] & qualifier_immediate) |
2433 args[k] = ARG_BUILTIN_CONSTANT; | 2539 args[k] = ARG_BUILTIN_CONSTANT; |
2434 else if (d->qualifiers[qualifiers_k] & qualifier_maybe_immediate) | 2540 else if (d->qualifiers[qualifiers_k] & qualifier_maybe_immediate) |
2467 arm_expand_builtin_args. */ | 2573 arm_expand_builtin_args. */ |
2468 | 2574 |
2469 static rtx | 2575 static rtx |
2470 arm_expand_acle_builtin (int fcode, tree exp, rtx target) | 2576 arm_expand_acle_builtin (int fcode, tree exp, rtx target) |
2471 { | 2577 { |
2472 | 2578 if (fcode == ARM_BUILTIN_SAT_IMM_CHECK) |
2579 { | |
2580 /* Check the saturation immediate bounds. */ | |
2581 | |
2582 rtx min_sat = expand_normal (CALL_EXPR_ARG (exp, 1)); | |
2583 rtx max_sat = expand_normal (CALL_EXPR_ARG (exp, 2)); | |
2584 gcc_assert (CONST_INT_P (min_sat)); | |
2585 gcc_assert (CONST_INT_P (max_sat)); | |
2586 rtx sat_imm = expand_normal (CALL_EXPR_ARG (exp, 0)); | |
2587 if (CONST_INT_P (sat_imm)) | |
2588 { | |
2589 if (!IN_RANGE (sat_imm, min_sat, max_sat)) | |
2590 error ("%Ksaturation bit range must be in the range [%wd, %wd]", | |
2591 exp, UINTVAL (min_sat), UINTVAL (max_sat)); | |
2592 } | |
2593 else | |
2594 error ("%Ksaturation bit range must be a constant immediate", exp); | |
2595 /* Don't generate any RTL. */ | |
2596 return const0_rtx; | |
2597 } | |
2473 arm_builtin_datum *d | 2598 arm_builtin_datum *d |
2474 = &acle_builtin_data[fcode - ARM_BUILTIN_ACLE_PATTERN_START]; | 2599 = &acle_builtin_data[fcode - ARM_BUILTIN_ACLE_PATTERN_START]; |
2475 | 2600 |
2476 return arm_expand_builtin_1 (fcode, exp, target, d); | 2601 return arm_expand_builtin_1 (fcode, exp, target, d); |
2477 } | 2602 } |
2486 { | 2611 { |
2487 if (fcode >= ARM_BUILTIN_NEON_BASE && ! TARGET_NEON) | 2612 if (fcode >= ARM_BUILTIN_NEON_BASE && ! TARGET_NEON) |
2488 { | 2613 { |
2489 fatal_error (input_location, | 2614 fatal_error (input_location, |
2490 "You must enable NEON instructions" | 2615 "You must enable NEON instructions" |
2491 " (e.g. -mfloat-abi=softfp -mfpu=neon)" | 2616 " (e.g. %<-mfloat-abi=softfp%> %<-mfpu=neon%>)" |
2492 " to use these intrinsics."); | 2617 " to use these intrinsics."); |
2493 return const0_rtx; | 2618 return const0_rtx; |
2494 } | 2619 } |
2495 | 2620 |
2496 if (fcode == ARM_BUILTIN_NEON_LANE_CHECK) | 2621 if (fcode == ARM_BUILTIN_NEON_LANE_CHECK) |
2557 tree arg2; | 2682 tree arg2; |
2558 rtx op0; | 2683 rtx op0; |
2559 rtx op1; | 2684 rtx op1; |
2560 rtx op2; | 2685 rtx op2; |
2561 rtx pat; | 2686 rtx pat; |
2562 unsigned int fcode = DECL_FUNCTION_CODE (fndecl); | 2687 unsigned int fcode = DECL_MD_FUNCTION_CODE (fndecl); |
2563 size_t i; | 2688 size_t i; |
2564 machine_mode tmode; | 2689 machine_mode tmode; |
2565 machine_mode mode0; | 2690 machine_mode mode0; |
2566 machine_mode mode1; | 2691 machine_mode mode1; |
2567 machine_mode mode2; | 2692 machine_mode mode2; |
2584 if (fcode >= ARM_BUILTIN_CRYPTO_BASE | 2709 if (fcode >= ARM_BUILTIN_CRYPTO_BASE |
2585 && (!TARGET_CRYPTO || !TARGET_HARD_FLOAT)) | 2710 && (!TARGET_CRYPTO || !TARGET_HARD_FLOAT)) |
2586 { | 2711 { |
2587 fatal_error (input_location, | 2712 fatal_error (input_location, |
2588 "You must enable crypto instructions" | 2713 "You must enable crypto instructions" |
2589 " (e.g. include -mfloat-abi=softfp -mfpu=crypto-neon...)" | 2714 " (e.g. include %<-mfloat-abi=softfp%> " |
2715 "%<-mfpu=crypto-neon%>)" | |
2590 " to use these intrinsics."); | 2716 " to use these intrinsics."); |
2591 return const0_rtx; | 2717 return const0_rtx; |
2592 } | 2718 } |
2593 | 2719 |
2594 switch (fcode) | 2720 switch (fcode) |
3296 *update = build2 (COMPOUND_EXPR, void_type_node, | 3422 *update = build2 (COMPOUND_EXPR, void_type_node, |
3297 build2 (COMPOUND_EXPR, void_type_node, | 3423 build2 (COMPOUND_EXPR, void_type_node, |
3298 reload_fenv, restore_fnenv), update_call); | 3424 reload_fenv, restore_fnenv), update_call); |
3299 } | 3425 } |
3300 | 3426 |
3427 /* Implement TARGET_CHECK_BUILTIN_CALL. Record a read of the Q bit through | |
3428 intrinsics in the machine function. */ | |
3429 bool | |
3430 arm_check_builtin_call (location_t , vec<location_t> , tree fndecl, | |
3431 tree, unsigned int, tree *) | |
3432 { | |
3433 int fcode = DECL_MD_FUNCTION_CODE (fndecl); | |
3434 if (fcode == ARM_BUILTIN_saturation_occurred | |
3435 || fcode == ARM_BUILTIN_set_saturation) | |
3436 { | |
3437 if (cfun && cfun->decl) | |
3438 DECL_ATTRIBUTES (cfun->decl) | |
3439 = tree_cons (get_identifier ("acle qbit"), NULL_TREE, | |
3440 DECL_ATTRIBUTES (cfun->decl)); | |
3441 } | |
3442 if (fcode == ARM_BUILTIN_sel) | |
3443 { | |
3444 if (cfun && cfun->decl) | |
3445 DECL_ATTRIBUTES (cfun->decl) | |
3446 = tree_cons (get_identifier ("acle gebits"), NULL_TREE, | |
3447 DECL_ATTRIBUTES (cfun->decl)); | |
3448 } | |
3449 return true; | |
3450 } | |
3451 | |
3301 #include "gt-arm-builtins.h" | 3452 #include "gt-arm-builtins.h" |