annotate gcc/config/nds32/nds32-predicates.c @ 131:84e7813d76e9

gcc-8.2
author mir3636
date Thu, 25 Oct 2018 07:37:49 +0900
parents 04ced10e8804
children 1830386684a0
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
111
kono
parents:
diff changeset
1 /* Predicate functions of Andes NDS32 cpu for GNU compiler
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2 Copyright (C) 2012-2018 Free Software Foundation, Inc.
111
kono
parents:
diff changeset
3 Contributed by Andes Technology Corporation.
kono
parents:
diff changeset
4
kono
parents:
diff changeset
5 This file is part of GCC.
kono
parents:
diff changeset
6
kono
parents:
diff changeset
7 GCC is free software; you can redistribute it and/or modify it
kono
parents:
diff changeset
8 under the terms of the GNU General Public License as published
kono
parents:
diff changeset
9 by the Free Software Foundation; either version 3, or (at your
kono
parents:
diff changeset
10 option) any later version.
kono
parents:
diff changeset
11
kono
parents:
diff changeset
12 GCC is distributed in the hope that it will be useful, but WITHOUT
kono
parents:
diff changeset
13 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
kono
parents:
diff changeset
14 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
kono
parents:
diff changeset
15 License for more details.
kono
parents:
diff changeset
16
kono
parents:
diff changeset
17 You should have received a copy of the GNU General Public License
kono
parents:
diff changeset
18 along with GCC; see the file COPYING3. If not see
kono
parents:
diff changeset
19 <http://www.gnu.org/licenses/>. */
kono
parents:
diff changeset
20
kono
parents:
diff changeset
21 /* ------------------------------------------------------------------------ */
kono
parents:
diff changeset
22
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
23 #define IN_TARGET_CODE 1
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
24
111
kono
parents:
diff changeset
25 #include "config.h"
kono
parents:
diff changeset
26 #include "system.h"
kono
parents:
diff changeset
27 #include "coretypes.h"
kono
parents:
diff changeset
28 #include "backend.h"
kono
parents:
diff changeset
29 #include "target.h"
kono
parents:
diff changeset
30 #include "rtl.h"
kono
parents:
diff changeset
31 #include "tree.h"
kono
parents:
diff changeset
32 #include "memmodel.h"
kono
parents:
diff changeset
33 #include "tm_p.h"
kono
parents:
diff changeset
34 #include "optabs.h" /* For GEN_FCN. */
kono
parents:
diff changeset
35 #include "emit-rtl.h"
kono
parents:
diff changeset
36 #include "recog.h"
kono
parents:
diff changeset
37 #include "tm-constrs.h"
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
38 #include "insn-attr.h"
111
kono
parents:
diff changeset
39
kono
parents:
diff changeset
40 /* ------------------------------------------------------------------------ */
kono
parents:
diff changeset
41
kono
parents:
diff changeset
42 /* A subroutine that checks multiple load and store
kono
parents:
diff changeset
43 using consecutive registers.
kono
parents:
diff changeset
44 OP is a parallel rtx we would like to check.
kono
parents:
diff changeset
45 LOAD_P indicates whether we are checking load operation.
kono
parents:
diff changeset
46 PAR_INDEX is starting element of parallel rtx.
kono
parents:
diff changeset
47 FIRST_ELT_REGNO is used to tell starting register number.
kono
parents:
diff changeset
48 COUNT helps us to check consecutive register numbers. */
kono
parents:
diff changeset
49 static bool
kono
parents:
diff changeset
50 nds32_consecutive_registers_load_store_p (rtx op,
kono
parents:
diff changeset
51 bool load_p,
kono
parents:
diff changeset
52 int par_index,
kono
parents:
diff changeset
53 int first_elt_regno,
kono
parents:
diff changeset
54 int count)
kono
parents:
diff changeset
55 {
kono
parents:
diff changeset
56 int i;
kono
parents:
diff changeset
57 int check_regno;
kono
parents:
diff changeset
58 rtx elt;
kono
parents:
diff changeset
59 rtx elt_reg;
kono
parents:
diff changeset
60 rtx elt_mem;
kono
parents:
diff changeset
61
kono
parents:
diff changeset
62 for (i = 0; i < count; i++)
kono
parents:
diff changeset
63 {
kono
parents:
diff changeset
64 /* Pick up each element from parallel rtx. */
kono
parents:
diff changeset
65 elt = XVECEXP (op, 0, i + par_index);
kono
parents:
diff changeset
66
kono
parents:
diff changeset
67 /* If this element is not a 'set' rtx, return false immediately. */
kono
parents:
diff changeset
68 if (GET_CODE (elt) != SET)
kono
parents:
diff changeset
69 return false;
kono
parents:
diff changeset
70
kono
parents:
diff changeset
71 /* Pick up reg and mem of this element. */
kono
parents:
diff changeset
72 elt_reg = load_p ? SET_DEST (elt) : SET_SRC (elt);
kono
parents:
diff changeset
73 elt_mem = load_p ? SET_SRC (elt) : SET_DEST (elt);
kono
parents:
diff changeset
74
kono
parents:
diff changeset
75 /* If elt_reg is not a expected reg rtx, return false. */
kono
parents:
diff changeset
76 if (GET_CODE (elt_reg) != REG || GET_MODE (elt_reg) != SImode)
kono
parents:
diff changeset
77 return false;
kono
parents:
diff changeset
78 /* If elt_mem is not a expected mem rtx, return false. */
kono
parents:
diff changeset
79 if (GET_CODE (elt_mem) != MEM || GET_MODE (elt_mem) != SImode)
kono
parents:
diff changeset
80 return false;
kono
parents:
diff changeset
81
kono
parents:
diff changeset
82 /* The consecutive registers should be in (Rb,Rb+1...Re) order. */
kono
parents:
diff changeset
83 check_regno = first_elt_regno + i;
kono
parents:
diff changeset
84
kono
parents:
diff changeset
85 /* If the register number is not continuous, return false. */
kono
parents:
diff changeset
86 if (REGNO (elt_reg) != (unsigned int) check_regno)
kono
parents:
diff changeset
87 return false;
kono
parents:
diff changeset
88 }
kono
parents:
diff changeset
89
kono
parents:
diff changeset
90 return true;
kono
parents:
diff changeset
91 }
kono
parents:
diff changeset
92
kono
parents:
diff changeset
93 /* Function to check whether the OP is a valid load/store operation.
kono
parents:
diff changeset
94 This is a helper function for the predicates:
kono
parents:
diff changeset
95 'nds32_load_multiple_operation' and 'nds32_store_multiple_operation'
kono
parents:
diff changeset
96 in predicates.md file.
kono
parents:
diff changeset
97
kono
parents:
diff changeset
98 The OP is supposed to be a parallel rtx.
kono
parents:
diff changeset
99 For each element within this parallel rtx:
kono
parents:
diff changeset
100 (set (reg) (mem addr)) is the form for load operation.
kono
parents:
diff changeset
101 (set (mem addr) (reg)) is the form for store operation.
kono
parents:
diff changeset
102 We have to extract reg and mem of every element and
kono
parents:
diff changeset
103 check if the information is valid for multiple load/store operation. */
kono
parents:
diff changeset
104 bool
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
105 nds32_valid_multiple_load_store_p (rtx op, bool load_p, bool bim_p)
111
kono
parents:
diff changeset
106 {
kono
parents:
diff changeset
107 int count;
kono
parents:
diff changeset
108 int first_elt_regno;
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
109 int update_base_elt_idx;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
110 int offset;
111
kono
parents:
diff changeset
111 rtx elt;
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
112 rtx update_base;
111
kono
parents:
diff changeset
113
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
114 /* Get the counts of elements in the parallel rtx.
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
115 Last one is update base register if bim_p.
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
116 and pick up the first element. */
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
117 if (bim_p)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
118 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
119 count = XVECLEN (op, 0) - 1;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
120 elt = XVECEXP (op, 0, 1);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
121 }
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
122 else
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
123 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
124 count = XVECLEN (op, 0);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
125 elt = XVECEXP (op, 0, 0);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
126 }
111
kono
parents:
diff changeset
127
kono
parents:
diff changeset
128 /* Perform some quick check for the first element in the parallel rtx. */
kono
parents:
diff changeset
129 if (GET_CODE (elt) != SET
kono
parents:
diff changeset
130 || count <= 1
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
131 || count > 25)
111
kono
parents:
diff changeset
132 return false;
kono
parents:
diff changeset
133
kono
parents:
diff changeset
134 /* Pick up regno of first element for further detail checking.
kono
parents:
diff changeset
135 Note that the form is different between load and store operation. */
kono
parents:
diff changeset
136 if (load_p)
kono
parents:
diff changeset
137 {
kono
parents:
diff changeset
138 if (GET_CODE (SET_DEST (elt)) != REG
kono
parents:
diff changeset
139 || GET_CODE (SET_SRC (elt)) != MEM)
kono
parents:
diff changeset
140 return false;
kono
parents:
diff changeset
141
kono
parents:
diff changeset
142 first_elt_regno = REGNO (SET_DEST (elt));
kono
parents:
diff changeset
143 }
kono
parents:
diff changeset
144 else
kono
parents:
diff changeset
145 {
kono
parents:
diff changeset
146 if (GET_CODE (SET_SRC (elt)) != REG
kono
parents:
diff changeset
147 || GET_CODE (SET_DEST (elt)) != MEM)
kono
parents:
diff changeset
148 return false;
kono
parents:
diff changeset
149
kono
parents:
diff changeset
150 first_elt_regno = REGNO (SET_SRC (elt));
kono
parents:
diff changeset
151 }
kono
parents:
diff changeset
152
kono
parents:
diff changeset
153 /* Perform detail check for each element.
kono
parents:
diff changeset
154 Refer to nds32-multiple.md for more information
kono
parents:
diff changeset
155 about following checking.
kono
parents:
diff changeset
156 The starting element of parallel rtx is index 0. */
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
157 if (!nds32_consecutive_registers_load_store_p (op, load_p, bim_p ? 1 : 0,
111
kono
parents:
diff changeset
158 first_elt_regno,
kono
parents:
diff changeset
159 count))
kono
parents:
diff changeset
160 return false;
kono
parents:
diff changeset
161
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
162 if (bim_p)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
163 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
164 update_base_elt_idx = 0;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
165 update_base = XVECEXP (op, 0, update_base_elt_idx);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
166 if (!REG_P (SET_DEST (update_base)))
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
167 return false;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
168 if (GET_CODE (SET_SRC (update_base)) != PLUS)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
169 return false;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
170 else
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
171 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
172 offset = count * UNITS_PER_WORD;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
173 elt = XEXP (SET_SRC (update_base), 1);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
174 if (GET_CODE (elt) != CONST_INT
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
175 || (INTVAL (elt) != offset))
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
176 return false;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
177 }
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
178 }
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
179
111
kono
parents:
diff changeset
180 /* Pass all test, this is a valid rtx. */
kono
parents:
diff changeset
181 return true;
kono
parents:
diff changeset
182 }
kono
parents:
diff changeset
183
kono
parents:
diff changeset
184 /* Function to check whether the OP is a valid stack push/pop operation.
kono
parents:
diff changeset
185 For a valid stack operation, it must satisfy following conditions:
kono
parents:
diff changeset
186 1. Consecutive registers push/pop operations.
kono
parents:
diff changeset
187 2. Valid $fp/$gp/$lp push/pop operations.
kono
parents:
diff changeset
188 3. The last element must be stack adjustment rtx.
kono
parents:
diff changeset
189 See the prologue/epilogue implementation for details. */
kono
parents:
diff changeset
190 bool
kono
parents:
diff changeset
191 nds32_valid_stack_push_pop_p (rtx op, bool push_p)
kono
parents:
diff changeset
192 {
kono
parents:
diff changeset
193 int index;
kono
parents:
diff changeset
194 int total_count;
kono
parents:
diff changeset
195 int rest_count;
kono
parents:
diff changeset
196 int first_regno;
kono
parents:
diff changeset
197 int save_fp, save_gp, save_lp;
kono
parents:
diff changeset
198 rtx elt;
kono
parents:
diff changeset
199 rtx elt_reg;
kono
parents:
diff changeset
200 rtx elt_mem;
kono
parents:
diff changeset
201 rtx elt_plus;
kono
parents:
diff changeset
202
kono
parents:
diff changeset
203 /* Get the counts of elements in the parallel rtx. */
kono
parents:
diff changeset
204 total_count = XVECLEN (op, 0);
kono
parents:
diff changeset
205
kono
parents:
diff changeset
206 /* Perform some quick check for that every element should be 'set'. */
kono
parents:
diff changeset
207 for (index = 0; index < total_count; index++)
kono
parents:
diff changeset
208 {
kono
parents:
diff changeset
209 elt = XVECEXP (op, 0, index);
kono
parents:
diff changeset
210 if (GET_CODE (elt) != SET)
kono
parents:
diff changeset
211 return false;
kono
parents:
diff changeset
212 }
kono
parents:
diff changeset
213
kono
parents:
diff changeset
214 /* For push operation, the parallel rtx looks like:
kono
parents:
diff changeset
215 (parallel [(set (mem (plus (reg:SI SP_REGNUM) (const_int -32)))
kono
parents:
diff changeset
216 (reg:SI Rb))
kono
parents:
diff changeset
217 (set (mem (plus (reg:SI SP_REGNUM) (const_int -28)))
kono
parents:
diff changeset
218 (reg:SI Rb+1))
kono
parents:
diff changeset
219 ...
kono
parents:
diff changeset
220 (set (mem (plus (reg:SI SP_REGNUM) (const_int -16)))
kono
parents:
diff changeset
221 (reg:SI Re))
kono
parents:
diff changeset
222 (set (mem (plus (reg:SI SP_REGNUM) (const_int -12)))
kono
parents:
diff changeset
223 (reg:SI FP_REGNUM))
kono
parents:
diff changeset
224 (set (mem (plus (reg:SI SP_REGNUM) (const_int -8)))
kono
parents:
diff changeset
225 (reg:SI GP_REGNUM))
kono
parents:
diff changeset
226 (set (mem (plus (reg:SI SP_REGNUM) (const_int -4)))
kono
parents:
diff changeset
227 (reg:SI LP_REGNUM))
kono
parents:
diff changeset
228 (set (reg:SI SP_REGNUM)
kono
parents:
diff changeset
229 (plus (reg:SI SP_REGNUM) (const_int -32)))])
kono
parents:
diff changeset
230
kono
parents:
diff changeset
231 For pop operation, the parallel rtx looks like:
kono
parents:
diff changeset
232 (parallel [(set (reg:SI Rb)
kono
parents:
diff changeset
233 (mem (reg:SI SP_REGNUM)))
kono
parents:
diff changeset
234 (set (reg:SI Rb+1)
kono
parents:
diff changeset
235 (mem (plus (reg:SI SP_REGNUM) (const_int 4))))
kono
parents:
diff changeset
236 ...
kono
parents:
diff changeset
237 (set (reg:SI Re)
kono
parents:
diff changeset
238 (mem (plus (reg:SI SP_REGNUM) (const_int 16))))
kono
parents:
diff changeset
239 (set (reg:SI FP_REGNUM)
kono
parents:
diff changeset
240 (mem (plus (reg:SI SP_REGNUM) (const_int 20))))
kono
parents:
diff changeset
241 (set (reg:SI GP_REGNUM)
kono
parents:
diff changeset
242 (mem (plus (reg:SI SP_REGNUM) (const_int 24))))
kono
parents:
diff changeset
243 (set (reg:SI LP_REGNUM)
kono
parents:
diff changeset
244 (mem (plus (reg:SI SP_REGNUM) (const_int 28))))
kono
parents:
diff changeset
245 (set (reg:SI SP_REGNUM)
kono
parents:
diff changeset
246 (plus (reg:SI SP_REGNUM) (const_int 32)))]) */
kono
parents:
diff changeset
247
kono
parents:
diff changeset
248 /* 1. Consecutive registers push/pop operations.
kono
parents:
diff changeset
249 We need to calculate how many registers should be consecutive.
kono
parents:
diff changeset
250 The $sp adjustment rtx, $fp push rtx, $gp push rtx,
kono
parents:
diff changeset
251 and $lp push rtx are excluded. */
kono
parents:
diff changeset
252
kono
parents:
diff changeset
253 /* Detect whether we have $fp, $gp, or $lp in the parallel rtx. */
kono
parents:
diff changeset
254 save_fp = reg_mentioned_p (gen_rtx_REG (SImode, FP_REGNUM), op);
kono
parents:
diff changeset
255 save_gp = reg_mentioned_p (gen_rtx_REG (SImode, GP_REGNUM), op);
kono
parents:
diff changeset
256 save_lp = reg_mentioned_p (gen_rtx_REG (SImode, LP_REGNUM), op);
kono
parents:
diff changeset
257 /* Exclude last $sp adjustment rtx. */
kono
parents:
diff changeset
258 rest_count = total_count - 1;
kono
parents:
diff changeset
259 /* Exclude $fp, $gp, and $lp if they are in the parallel rtx. */
kono
parents:
diff changeset
260 if (save_fp)
kono
parents:
diff changeset
261 rest_count--;
kono
parents:
diff changeset
262 if (save_gp)
kono
parents:
diff changeset
263 rest_count--;
kono
parents:
diff changeset
264 if (save_lp)
kono
parents:
diff changeset
265 rest_count--;
kono
parents:
diff changeset
266
kono
parents:
diff changeset
267 if (rest_count > 0)
kono
parents:
diff changeset
268 {
kono
parents:
diff changeset
269 elt = XVECEXP (op, 0, 0);
kono
parents:
diff changeset
270 /* Pick up register element. */
kono
parents:
diff changeset
271 elt_reg = push_p ? SET_SRC (elt) : SET_DEST (elt);
kono
parents:
diff changeset
272 first_regno = REGNO (elt_reg);
kono
parents:
diff changeset
273
kono
parents:
diff changeset
274 /* The 'push' operation is a kind of store operation.
kono
parents:
diff changeset
275 The 'pop' operation is a kind of load operation.
kono
parents:
diff changeset
276 Pass corresponding false/true as second argument (bool load_p).
kono
parents:
diff changeset
277 The par_index is supposed to start with index 0. */
kono
parents:
diff changeset
278 if (!nds32_consecutive_registers_load_store_p (op,
kono
parents:
diff changeset
279 !push_p ? true : false,
kono
parents:
diff changeset
280 0,
kono
parents:
diff changeset
281 first_regno,
kono
parents:
diff changeset
282 rest_count))
kono
parents:
diff changeset
283 return false;
kono
parents:
diff changeset
284 }
kono
parents:
diff changeset
285
kono
parents:
diff changeset
286 /* 2. Valid $fp/$gp/$lp push/pop operations.
kono
parents:
diff changeset
287 Remember to set start index for checking them. */
kono
parents:
diff changeset
288
kono
parents:
diff changeset
289 /* The rest_count is the start index for checking $fp/$gp/$lp. */
kono
parents:
diff changeset
290 index = rest_count;
kono
parents:
diff changeset
291 /* If index < 0, this parallel rtx is definitely
kono
parents:
diff changeset
292 not a valid stack push/pop operation. */
kono
parents:
diff changeset
293 if (index < 0)
kono
parents:
diff changeset
294 return false;
kono
parents:
diff changeset
295
kono
parents:
diff changeset
296 /* Check $fp/$gp/$lp one by one.
kono
parents:
diff changeset
297 We use 'push_p' to pick up reg rtx and mem rtx. */
kono
parents:
diff changeset
298 if (save_fp)
kono
parents:
diff changeset
299 {
kono
parents:
diff changeset
300 elt = XVECEXP (op, 0, index);
kono
parents:
diff changeset
301 elt_mem = push_p ? SET_DEST (elt) : SET_SRC (elt);
kono
parents:
diff changeset
302 elt_reg = push_p ? SET_SRC (elt) : SET_DEST (elt);
kono
parents:
diff changeset
303 index++;
kono
parents:
diff changeset
304
kono
parents:
diff changeset
305 if (GET_CODE (elt_mem) != MEM
kono
parents:
diff changeset
306 || GET_CODE (elt_reg) != REG
kono
parents:
diff changeset
307 || REGNO (elt_reg) != FP_REGNUM)
kono
parents:
diff changeset
308 return false;
kono
parents:
diff changeset
309 }
kono
parents:
diff changeset
310 if (save_gp)
kono
parents:
diff changeset
311 {
kono
parents:
diff changeset
312 elt = XVECEXP (op, 0, index);
kono
parents:
diff changeset
313 elt_mem = push_p ? SET_DEST (elt) : SET_SRC (elt);
kono
parents:
diff changeset
314 elt_reg = push_p ? SET_SRC (elt) : SET_DEST (elt);
kono
parents:
diff changeset
315 index++;
kono
parents:
diff changeset
316
kono
parents:
diff changeset
317 if (GET_CODE (elt_mem) != MEM
kono
parents:
diff changeset
318 || GET_CODE (elt_reg) != REG
kono
parents:
diff changeset
319 || REGNO (elt_reg) != GP_REGNUM)
kono
parents:
diff changeset
320 return false;
kono
parents:
diff changeset
321 }
kono
parents:
diff changeset
322 if (save_lp)
kono
parents:
diff changeset
323 {
kono
parents:
diff changeset
324 elt = XVECEXP (op, 0, index);
kono
parents:
diff changeset
325 elt_mem = push_p ? SET_DEST (elt) : SET_SRC (elt);
kono
parents:
diff changeset
326 elt_reg = push_p ? SET_SRC (elt) : SET_DEST (elt);
kono
parents:
diff changeset
327 index++;
kono
parents:
diff changeset
328
kono
parents:
diff changeset
329 if (GET_CODE (elt_mem) != MEM
kono
parents:
diff changeset
330 || GET_CODE (elt_reg) != REG
kono
parents:
diff changeset
331 || REGNO (elt_reg) != LP_REGNUM)
kono
parents:
diff changeset
332 return false;
kono
parents:
diff changeset
333 }
kono
parents:
diff changeset
334
kono
parents:
diff changeset
335 /* 3. The last element must be stack adjustment rtx.
kono
parents:
diff changeset
336 Its form of rtx should be:
kono
parents:
diff changeset
337 (set (reg:SI SP_REGNUM)
kono
parents:
diff changeset
338 (plus (reg:SI SP_REGNUM) (const_int X)))
kono
parents:
diff changeset
339 The X could be positive or negative value. */
kono
parents:
diff changeset
340
kono
parents:
diff changeset
341 /* Pick up the last element. */
kono
parents:
diff changeset
342 elt = XVECEXP (op, 0, total_count - 1);
kono
parents:
diff changeset
343
kono
parents:
diff changeset
344 /* Extract its destination and source rtx. */
kono
parents:
diff changeset
345 elt_reg = SET_DEST (elt);
kono
parents:
diff changeset
346 elt_plus = SET_SRC (elt);
kono
parents:
diff changeset
347
kono
parents:
diff changeset
348 /* Check this is (set (stack_reg) (plus stack_reg const)) pattern. */
kono
parents:
diff changeset
349 if (GET_CODE (elt_reg) != REG
kono
parents:
diff changeset
350 || GET_CODE (elt_plus) != PLUS
kono
parents:
diff changeset
351 || REGNO (elt_reg) != SP_REGNUM)
kono
parents:
diff changeset
352 return false;
kono
parents:
diff changeset
353
kono
parents:
diff changeset
354 /* Pass all test, this is a valid rtx. */
kono
parents:
diff changeset
355 return true;
kono
parents:
diff changeset
356 }
kono
parents:
diff changeset
357
kono
parents:
diff changeset
358 /* Function to check if 'bclr' instruction can be used with IVAL. */
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
359 bool
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
360 nds32_can_use_bclr_p (HOST_WIDE_INT ival)
111
kono
parents:
diff changeset
361 {
kono
parents:
diff changeset
362 int one_bit_count;
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
363 unsigned HOST_WIDE_INT mask = GET_MODE_MASK (SImode);
111
kono
parents:
diff changeset
364
kono
parents:
diff changeset
365 /* Calculate the number of 1-bit of (~ival), if there is only one 1-bit,
kono
parents:
diff changeset
366 it means the original ival has only one 0-bit,
kono
parents:
diff changeset
367 So it is ok to perform 'bclr' operation. */
kono
parents:
diff changeset
368
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
369 one_bit_count = popcount_hwi ((unsigned HOST_WIDE_INT) (~ival) & mask);
111
kono
parents:
diff changeset
370
kono
parents:
diff changeset
371 /* 'bclr' is a performance extension instruction. */
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
372 return (TARGET_EXT_PERF && (one_bit_count == 1));
111
kono
parents:
diff changeset
373 }
kono
parents:
diff changeset
374
kono
parents:
diff changeset
375 /* Function to check if 'bset' instruction can be used with IVAL. */
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
376 bool
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
377 nds32_can_use_bset_p (HOST_WIDE_INT ival)
111
kono
parents:
diff changeset
378 {
kono
parents:
diff changeset
379 int one_bit_count;
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
380 unsigned HOST_WIDE_INT mask = GET_MODE_MASK (SImode);
111
kono
parents:
diff changeset
381
kono
parents:
diff changeset
382 /* Caculate the number of 1-bit of ival, if there is only one 1-bit,
kono
parents:
diff changeset
383 it is ok to perform 'bset' operation. */
kono
parents:
diff changeset
384
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
385 one_bit_count = popcount_hwi ((unsigned HOST_WIDE_INT) (ival) & mask);
111
kono
parents:
diff changeset
386
kono
parents:
diff changeset
387 /* 'bset' is a performance extension instruction. */
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
388 return (TARGET_EXT_PERF && (one_bit_count == 1));
111
kono
parents:
diff changeset
389 }
kono
parents:
diff changeset
390
kono
parents:
diff changeset
391 /* Function to check if 'btgl' instruction can be used with IVAL. */
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
392 bool
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
393 nds32_can_use_btgl_p (HOST_WIDE_INT ival)
111
kono
parents:
diff changeset
394 {
kono
parents:
diff changeset
395 int one_bit_count;
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
396 unsigned HOST_WIDE_INT mask = GET_MODE_MASK (SImode);
111
kono
parents:
diff changeset
397
kono
parents:
diff changeset
398 /* Caculate the number of 1-bit of ival, if there is only one 1-bit,
kono
parents:
diff changeset
399 it is ok to perform 'btgl' operation. */
kono
parents:
diff changeset
400
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
401 one_bit_count = popcount_hwi ((unsigned HOST_WIDE_INT) (ival) & mask);
111
kono
parents:
diff changeset
402
kono
parents:
diff changeset
403 /* 'btgl' is a performance extension instruction. */
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
404 return (TARGET_EXT_PERF && (one_bit_count == 1));
111
kono
parents:
diff changeset
405 }
kono
parents:
diff changeset
406
kono
parents:
diff changeset
407 /* Function to check if 'bitci' instruction can be used with IVAL. */
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
408 bool
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
409 nds32_can_use_bitci_p (HOST_WIDE_INT ival)
111
kono
parents:
diff changeset
410 {
kono
parents:
diff changeset
411 /* If we are using V3 ISA, we have 'bitci' instruction.
kono
parents:
diff changeset
412 Try to see if we can present 'andi' semantic with
kono
parents:
diff changeset
413 such 'bit-clear-immediate' operation.
kono
parents:
diff changeset
414 For example, 'andi $r0,$r0,0xfffffffc' can be
kono
parents:
diff changeset
415 presented with 'bitci $r0,$r0,3'. */
kono
parents:
diff changeset
416 return (TARGET_ISA_V3
kono
parents:
diff changeset
417 && (ival < 0)
kono
parents:
diff changeset
418 && satisfies_constraint_Iu15 (gen_int_mode (~ival, SImode)));
kono
parents:
diff changeset
419 }
kono
parents:
diff changeset
420
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
421 /* Return true if is load/store with SYMBOL_REF addressing mode
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
422 and memory mode is SImode. */
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
423 bool
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
424 nds32_symbol_load_store_p (rtx_insn *insn)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
425 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
426 rtx mem_src = NULL_RTX;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
427
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
428 switch (get_attr_type (insn))
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
429 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
430 case TYPE_LOAD:
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
431 mem_src = SET_SRC (PATTERN (insn));
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
432 break;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
433 case TYPE_STORE:
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
434 mem_src = SET_DEST (PATTERN (insn));
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
435 break;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
436 default:
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
437 break;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
438 }
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
439
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
440 /* Find load/store insn with addressing mode is SYMBOL_REF. */
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
441 if (mem_src != NULL_RTX)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
442 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
443 if ((GET_CODE (mem_src) == ZERO_EXTEND)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
444 || (GET_CODE (mem_src) == SIGN_EXTEND))
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
445 mem_src = XEXP (mem_src, 0);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
446
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
447 if ((GET_CODE (XEXP (mem_src, 0)) == SYMBOL_REF)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
448 || (GET_CODE (XEXP (mem_src, 0)) == LO_SUM))
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
449 return true;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
450 }
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
451
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
452 return false;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
453 }
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
454
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
455 /* Vaild memory operand for floating-point loads and stores */
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
456 bool
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
457 nds32_float_mem_operand_p (rtx op)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
458 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
459 machine_mode mode = GET_MODE (op);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
460 rtx addr = XEXP (op, 0);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
461
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
462 /* Not support [symbol] [const] memory */
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
463 if (GET_CODE (addr) == SYMBOL_REF
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
464 || GET_CODE (addr) == CONST
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
465 || GET_CODE (addr) == LO_SUM)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
466 return false;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
467
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
468 if (GET_CODE (addr) == PLUS)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
469 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
470 if (GET_CODE (XEXP (addr, 0)) == SYMBOL_REF)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
471 return false;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
472
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
473 /* Restrict const range: (imm12s << 2) */
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
474 if (GET_CODE (XEXP (addr, 1)) == CONST_INT)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
475 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
476 if ((mode == SImode || mode == SFmode)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
477 && NDS32_SINGLE_WORD_ALIGN_P (INTVAL (XEXP (addr, 1)))
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
478 && !satisfies_constraint_Is14 ( XEXP(addr, 1)))
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
479 return false;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
480
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
481 if ((mode == DImode || mode == DFmode)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
482 && NDS32_DOUBLE_WORD_ALIGN_P (INTVAL (XEXP (addr, 1)))
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
483 && !satisfies_constraint_Is14 (XEXP (addr, 1)))
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
484 return false;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
485 }
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
486 }
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
487
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
488 return true;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
489 }
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
490
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
491 int
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
492 nds32_cond_move_p (rtx cmp_rtx)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
493 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
494 machine_mode cmp0_mode = GET_MODE (XEXP (cmp_rtx, 0));
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
495 machine_mode cmp1_mode = GET_MODE (XEXP (cmp_rtx, 1));
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
496 enum rtx_code cond = GET_CODE (cmp_rtx);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
497
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
498 if ((cmp0_mode == DFmode || cmp0_mode == SFmode)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
499 && (cmp1_mode == DFmode || cmp1_mode == SFmode)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
500 && (cond == ORDERED || cond == UNORDERED))
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
501 return true;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
502 return false;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
503 }
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
504
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
505 bool
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
506 nds32_const_double_range_ok_p (rtx op, machine_mode mode,
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
507 HOST_WIDE_INT lower, HOST_WIDE_INT upper)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
508 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
509 if (GET_CODE (op) != CONST_DOUBLE
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
510 || GET_MODE (op) != mode)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
511 return false;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
512
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
513 const REAL_VALUE_TYPE *rv;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
514 long val;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
515
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
516 rv = CONST_DOUBLE_REAL_VALUE (op);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
517 REAL_VALUE_TO_TARGET_SINGLE (*rv, val);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
518
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
519 return val >= lower && val < upper;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
520 }
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
521
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
522 bool
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
523 nds32_const_unspec_p (rtx x)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
524 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
525 if (GET_CODE (x) == CONST)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
526 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
527 x = XEXP (x, 0);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
528
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
529 if (GET_CODE (x) == PLUS)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
530 x = XEXP (x, 0);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
531
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
532 if (GET_CODE (x) == UNSPEC)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
533 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
534 switch (XINT (x, 1))
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
535 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
536 case UNSPEC_GOTINIT:
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
537 case UNSPEC_GOT:
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
538 case UNSPEC_GOTOFF:
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
539 case UNSPEC_PLT:
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
540 case UNSPEC_TLSGD:
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
541 case UNSPEC_TLSLD:
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
542 case UNSPEC_TLSIE:
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
543 case UNSPEC_TLSLE:
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
544 return false;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
545 default:
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
546 return true;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
547 }
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
548 }
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
549 }
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
550
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
551 if (GET_CODE (x) == SYMBOL_REF
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
552 && SYMBOL_REF_TLS_MODEL (x))
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
553 return false;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
554
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
555 return true;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
556 }
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
557
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
558 HOST_WIDE_INT
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
559 const_vector_to_hwint (rtx op)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
560 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
561 HOST_WIDE_INT hwint = 0;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
562 HOST_WIDE_INT mask;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
563 int i;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
564 int shift_adv;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
565 int shift = 0;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
566 int nelem;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
567
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
568 switch (GET_MODE (op))
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
569 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
570 case E_V2HImode:
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
571 mask = 0xffff;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
572 shift_adv = 16;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
573 nelem = 2;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
574 break;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
575 case E_V4QImode:
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
576 mask = 0xff;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
577 shift_adv = 8;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
578 nelem = 4;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
579 break;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
580 default:
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
581 gcc_unreachable ();
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
582 }
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
583
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
584 if (TARGET_BIG_ENDIAN)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
585 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
586 for (i = 0; i < nelem; ++i)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
587 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
588 HOST_WIDE_INT val = XINT (XVECEXP (op, 0, nelem - i - 1), 0);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
589 hwint |= (val & mask) << shift;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
590 shift = shift + shift_adv;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
591 }
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
592 }
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
593 else
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
594 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
595 for (i = 0; i < nelem; ++i)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
596 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
597 HOST_WIDE_INT val = XINT (XVECEXP (op, 0, i), 0);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
598 hwint |= (val & mask) << shift;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
599 shift = shift + shift_adv;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
600 }
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
601 }
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
602
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
603 return hwint;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
604 }
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
605
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
606 bool
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
607 nds32_valid_CVp5_p (rtx op)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
608 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
609 HOST_WIDE_INT ival = const_vector_to_hwint (op);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
610 return (ival < ((1 << 5) + 16)) && (ival >= (0 + 16));
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
611 }
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
612
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
613 bool
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
614 nds32_valid_CVs5_p (rtx op)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
615 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
616 HOST_WIDE_INT ival = const_vector_to_hwint (op);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
617 return (ival < (1 << 4)) && (ival >= -(1 << 4));
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
618 }
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
619
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
620 bool
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
621 nds32_valid_CVs2_p (rtx op)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
622 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
623 HOST_WIDE_INT ival = const_vector_to_hwint (op);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
624 return (ival < (1 << 19)) && (ival >= -(1 << 19));
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
625 }
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
626
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
627 bool
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
628 nds32_valid_CVhi_p (rtx op)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
629 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
630 HOST_WIDE_INT ival = const_vector_to_hwint (op);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
631 return (ival != 0) && ((ival & 0xfff) == 0);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
632 }
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
633
111
kono
parents:
diff changeset
634 /* ------------------------------------------------------------------------ */