Branch data Line data Source code
1 : : /* Expands front end tree to back end RTL for GCC
2 : : Copyright (C) 1987-2025 Free Software Foundation, Inc.
3 : :
4 : : This file is part of GCC.
5 : :
6 : : GCC is free software; you can redistribute it and/or modify it under
7 : : the terms of the GNU General Public License as published by the Free
8 : : Software Foundation; either version 3, or (at your option) any later
9 : : version.
10 : :
11 : : GCC is distributed in the hope that it will be useful, but WITHOUT ANY
12 : : WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 : : FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 : : for more details.
15 : :
16 : : You should have received a copy of the GNU General Public License
17 : : along with GCC; see the file COPYING3. If not see
18 : : <http://www.gnu.org/licenses/>. */
19 : :
20 : : /* This file handles the generation of rtl code from tree structure
21 : : above the level of expressions, using subroutines in exp*.c and emit-rtl.cc.
22 : : The functions whose names start with `expand_' are called by the
23 : : expander to generate RTL instructions for various kinds of constructs. */
24 : :
25 : : #include "config.h"
26 : : #include "system.h"
27 : : #include "coretypes.h"
28 : : #include "backend.h"
29 : : #include "target.h"
30 : : #include "rtl.h"
31 : : #include "tree.h"
32 : : #include "gimple.h"
33 : : #include "cfghooks.h"
34 : : #include "predict.h"
35 : : #include "memmodel.h"
36 : : #include "tm_p.h"
37 : : #include "optabs.h"
38 : : #include "regs.h"
39 : : #include "emit-rtl.h"
40 : : #include "pretty-print.h"
41 : : #include "diagnostic-core.h"
42 : :
43 : : #include "fold-const.h"
44 : : #include "varasm.h"
45 : : #include "stor-layout.h"
46 : : #include "dojump.h"
47 : : #include "explow.h"
48 : : #include "stmt.h"
49 : : #include "expr.h"
50 : : #include "langhooks.h"
51 : : #include "cfganal.h"
52 : : #include "tree-cfg.h"
53 : : #include "dumpfile.h"
54 : : #include "builtins.h"
55 : : #include "cfgexpand.h"
56 : :
57 : :
58 : : /* Functions and data structures for expanding case statements. */
59 : :
60 : : /* Case label structure, used to hold info on labels within case
61 : : statements. We handle "range" labels; for a single-value label
62 : : as in C, the high and low limits are the same.
63 : :
64 : : We start with a vector of case nodes sorted in ascending order, and
65 : : the default label as the last element in the vector.
66 : :
67 : : Switch statements are expanded in jump table form.
68 : :
69 : : */
70 : :
71 : : class simple_case_node
72 : : {
73 : : public:
74 : 97787 : simple_case_node (tree low, tree high, tree code_label):
75 : 97787 : m_low (low), m_high (high), m_code_label (code_label)
76 : : {}
77 : :
78 : : /* Lowest index value for this label. */
79 : : tree m_low;
80 : : /* Highest index value for this label. */
81 : : tree m_high;
82 : : /* Label to jump to when node matches. */
83 : : tree m_code_label;
84 : : };
85 : :
86 : : static bool check_unique_operand_names (tree, tree, tree);
87 : : static char *resolve_operand_name_1 (char *, tree, tree, tree);
88 : :
89 : : /* Return the rtx-label that corresponds to a LABEL_DECL,
90 : : creating it if necessary. */
91 : :
92 : : rtx_insn *
93 : 2671973 : label_rtx (tree label)
94 : : {
95 : 2671973 : gcc_assert (TREE_CODE (label) == LABEL_DECL);
96 : :
97 : 2671973 : if (!DECL_RTL_SET_P (label))
98 : : {
99 : 630866 : rtx_code_label *r = gen_label_rtx ();
100 : 630866 : SET_DECL_RTL (label, r);
101 : 630866 : if (FORCED_LABEL (label) || DECL_NONLOCAL (label))
102 : 26174 : LABEL_PRESERVE_P (r) = 1;
103 : : }
104 : :
105 : 2671973 : return as_a <rtx_insn *> (DECL_RTL (label));
106 : : }
107 : :
108 : : /* As above, but also put it on the forced-reference list of the
109 : : function that contains it. */
110 : : rtx_insn *
111 : 0 : force_label_rtx (tree label)
112 : : {
113 : 0 : rtx_insn *ref = label_rtx (label);
114 : 0 : tree function = decl_function_context (label);
115 : :
116 : 0 : gcc_assert (function);
117 : :
118 : 0 : vec_safe_push (forced_labels, ref);
119 : 0 : return ref;
120 : : }
121 : :
122 : : /* As label_rtx, but ensures (in check build), that returned value is
123 : : an existing label (i.e. rtx with code CODE_LABEL). */
124 : : rtx_code_label *
125 : 851603 : jump_target_rtx (tree label)
126 : : {
127 : 851603 : return as_a <rtx_code_label *> (label_rtx (label));
128 : : }
129 : :
130 : : /* Add an unconditional jump to LABEL as the next sequential instruction. */
131 : :
132 : : void
133 : 3234960 : emit_jump (rtx label)
134 : : {
135 : 3234960 : do_pending_stack_adjust ();
136 : 3234960 : emit_jump_insn (targetm.gen_jump (label));
137 : 3234960 : emit_barrier ();
138 : 3234960 : }
139 : :
140 : : /* Handle goto statements and the labels that they can go to. */
141 : :
142 : : /* Specify the location in the RTL code of a label LABEL,
143 : : which is a LABEL_DECL tree node.
144 : :
145 : : This is used for the kind of label that the user can jump to with a
146 : : goto statement, and for alternatives of a switch or case statement.
147 : : RTL labels generated for loops and conditionals don't go through here;
148 : : they are generated directly at the RTL level, by other functions below.
149 : :
150 : : Note that this has nothing to do with defining label *names*.
151 : : Languages vary in how they do that and what that even means. */
152 : :
153 : : void
154 : 630866 : expand_label (tree label)
155 : : {
156 : 630866 : rtx_code_label *label_r = jump_target_rtx (label);
157 : :
158 : 630866 : do_pending_stack_adjust ();
159 : 630866 : emit_label (label_r);
160 : 630866 : if (DECL_NAME (label))
161 : 98111 : LABEL_NAME (DECL_RTL (label)) = IDENTIFIER_POINTER (DECL_NAME (label));
162 : :
163 : 630866 : if (DECL_NONLOCAL (label))
164 : : {
165 : 502 : expand_builtin_setjmp_receiver (NULL);
166 : 502 : nonlocal_goto_handler_labels
167 : 502 : = gen_rtx_INSN_LIST (VOIDmode, label_r,
168 : 502 : nonlocal_goto_handler_labels);
169 : : }
170 : :
171 : 630866 : if (FORCED_LABEL (label))
172 : 25672 : vec_safe_push<rtx_insn *> (forced_labels, label_r);
173 : :
174 : 1261230 : if (DECL_NONLOCAL (label) || FORCED_LABEL (label))
175 : 26174 : maybe_set_first_label_num (label_r);
176 : 630866 : }
177 : :
178 : : /* Parse the output constraint pointed to by *CONSTRAINT_P. It is the
179 : : OPERAND_NUMth output operand, indexed from zero. There are NINPUTS
180 : : inputs and NOUTPUTS outputs to this extended-asm. Upon return,
181 : : *ALLOWS_MEM will be TRUE iff the constraint allows the use of a
182 : : memory operand. Similarly, *ALLOWS_REG will be TRUE iff the
183 : : constraint allows the use of a register operand. And, *IS_INOUT
184 : : will be true if the operand is read-write, i.e., if it is used as
185 : : an input as well as an output. If *CONSTRAINT_P is not in
186 : : canonical form, it will be made canonical. (Note that `+' will be
187 : : replaced with `=' as part of this process.)
188 : :
189 : : Returns TRUE if all went well; FALSE if an error occurred. */
190 : :
191 : : bool
192 : 31570628 : parse_output_constraint (const char **constraint_p, int operand_num,
193 : : int ninputs, int noutputs, bool *allows_mem,
194 : : bool *allows_reg, bool *is_inout)
195 : : {
196 : 31570628 : const char *constraint = *constraint_p;
197 : 31570628 : const char *p;
198 : :
199 : : /* Assume the constraint doesn't allow the use of either a register
200 : : or memory. */
201 : 31570628 : *allows_mem = false;
202 : 31570628 : *allows_reg = false;
203 : :
204 : : /* Allow the `=' or `+' to not be at the beginning of the string,
205 : : since it wasn't explicitly documented that way, and there is a
206 : : large body of code that puts it last. Swap the character to
207 : : the front, so as not to uglify any place else. */
208 : 31570628 : p = strchr (constraint, '=');
209 : 31570628 : if (!p)
210 : 17305 : p = strchr (constraint, '+');
211 : :
212 : : /* If the string doesn't contain an `=', issue an error
213 : : message. */
214 : 17305 : if (!p)
215 : : {
216 : 12 : error ("output operand constraint lacks %<=%>");
217 : 12 : return false;
218 : : }
219 : :
220 : : /* If the constraint begins with `+', then the operand is both read
221 : : from and written to. */
222 : 31570616 : *is_inout = (*p == '+');
223 : :
224 : : /* Canonicalize the output constraint so that it begins with `='. */
225 : 31570616 : if (p != constraint || *is_inout)
226 : : {
227 : 17293 : char *buf;
228 : 17293 : size_t c_len = strlen (constraint);
229 : :
230 : 17293 : if (p != constraint)
231 : 0 : warning (0, "output constraint %qc for operand %d "
232 : : "is not at the beginning",
233 : 0 : *p, operand_num);
234 : :
235 : : /* Make a copy of the constraint. */
236 : 17293 : buf = XALLOCAVEC (char, c_len + 1);
237 : 17293 : strcpy (buf, constraint);
238 : : /* Swap the first character and the `=' or `+'. */
239 : 17293 : buf[p - constraint] = buf[0];
240 : : /* Make sure the first character is an `='. (Until we do this,
241 : : it might be a `+'.) */
242 : 17293 : buf[0] = '=';
243 : : /* Replace the constraint with the canonicalized string. */
244 : 17293 : *constraint_p = ggc_alloc_string (buf, c_len);
245 : 17293 : constraint = *constraint_p;
246 : : }
247 : :
248 : : /* Loop through the constraint string. */
249 : 63958198 : for (p = constraint + 1; *p; )
250 : : {
251 : 32387590 : switch (*p)
252 : : {
253 : 0 : case '+':
254 : 0 : case '=':
255 : 0 : error ("operand constraint contains incorrectly positioned "
256 : : "%<+%> or %<=%>");
257 : 0 : return false;
258 : :
259 : 8 : case '%':
260 : 8 : if (operand_num + 1 == ninputs + noutputs)
261 : : {
262 : 0 : error ("%<%%%> constraint used with last operand");
263 : 0 : return false;
264 : : }
265 : : break;
266 : :
267 : : case '?': case '!': case '*': case '&': case '#':
268 : : case '$': case '^':
269 : : case 'E': case 'F': case 'G': case 'H':
270 : : case 's': case 'i': case 'n':
271 : : case 'I': case 'J': case 'K': case 'L': case 'M':
272 : : case 'N': case 'O': case 'P': case ',': case '-':
273 : : break;
274 : :
275 : 0 : case '0': case '1': case '2': case '3': case '4':
276 : 0 : case '5': case '6': case '7': case '8': case '9':
277 : 0 : case '[':
278 : 0 : error ("matching constraint not valid in output operand");
279 : 0 : return false;
280 : :
281 : 8 : case ':':
282 : 8 : error ("%<:%> constraint used for output operand");
283 : 8 : return false;
284 : :
285 : 0 : case '<': case '>':
286 : : /* ??? Before flow, auto inc/dec insns are not supposed to exist,
287 : : excepting those that expand_call created. So match memory
288 : : and hope. */
289 : 0 : *allows_mem = true;
290 : 0 : break;
291 : :
292 : 1887775 : case 'g': case 'X':
293 : 1887775 : *allows_reg = true;
294 : 1887775 : *allows_mem = true;
295 : 1887775 : break;
296 : :
297 : 29874396 : default:
298 : 29874396 : if (!ISALPHA (*p))
299 : : break;
300 : 29855361 : enum constraint_num cn = lookup_constraint (p);
301 : 29855361 : if (reg_class_for_constraint (cn) != NO_REGS
302 : 29855361 : || insn_extra_address_constraint (cn))
303 : 28063156 : *allows_reg = true;
304 : : else if (insn_extra_memory_constraint (cn))
305 : 1784443 : *allows_mem = true;
306 : : else
307 : : insn_extra_constraint_allows_reg_mem (cn, allows_reg, allows_mem);
308 : : break;
309 : : }
310 : :
311 : 64789572 : for (size_t len = CONSTRAINT_LEN (*p, p); len; len--, p++)
312 : 32402437 : if (*p == '\0')
313 : : break;
314 : : }
315 : :
316 : : return true;
317 : : }
318 : :
319 : : /* Similar, but for input constraints. */
320 : :
321 : : bool
322 : 20650793 : parse_input_constraint (const char **constraint_p, int input_num,
323 : : int ninputs, int noutputs, int ninout,
324 : : const char * const * constraints,
325 : : bool *allows_mem, bool *allows_reg)
326 : : {
327 : 20650793 : const char *constraint = *constraint_p;
328 : 20650793 : const char *orig_constraint = constraint;
329 : 20650793 : size_t c_len = strlen (constraint);
330 : 20650793 : size_t j;
331 : 20650793 : bool saw_match = false;
332 : 20650793 : bool at_checked = false;
333 : :
334 : : /* Assume the constraint doesn't allow the use of either
335 : : a register or memory. */
336 : 20650793 : *allows_mem = false;
337 : 20650793 : *allows_reg = false;
338 : :
339 : : /* Make sure constraint has neither `=', `+', nor '&'. */
340 : :
341 : 54988527 : for (j = 0; j < c_len; j += CONSTRAINT_LEN (constraint[j], constraint+j))
342 : 34337760 : switch (constraint[j])
343 : : {
344 : 476284 : case '+': case '=': case '&':
345 : 476284 : if (constraint == orig_constraint)
346 : : {
347 : 0 : error ("input operand constraint contains %qc", constraint[j]);
348 : 0 : return false;
349 : : }
350 : : break;
351 : :
352 : 378995 : case '%':
353 : 378995 : if (constraint == orig_constraint
354 : 378995 : && input_num + 1 == ninputs - ninout)
355 : : {
356 : 0 : error ("%<%%%> constraint used with last operand");
357 : 0 : return false;
358 : : }
359 : : break;
360 : :
361 : : case '<': case '>':
362 : : case '?': case '!': case '*': case '#':
363 : : case '$': case '^':
364 : : case 'E': case 'F': case 'G': case 'H':
365 : : case 's': case 'i': case 'n':
366 : : case 'I': case 'J': case 'K': case 'L': case 'M':
367 : : case 'N': case 'O': case 'P': case ',': case '-':
368 : : break;
369 : :
370 : 112 : case ':':
371 : : /* Verify that if : is used, it is just ":" or say ":,:" but not
372 : : mixed with other constraints or say ",:,," etc. */
373 : 112 : if (!at_checked)
374 : : {
375 : 204 : for (size_t k = 0; k < c_len; ++k)
376 : 228 : if (constraint[k] != ((k & 1) ? ',' : ':') || (c_len & 1) == 0)
377 : : {
378 : 20 : error ("%<:%> constraint mixed with other constraints");
379 : 20 : return false;
380 : : }
381 : : at_checked = true;
382 : : }
383 : : break;
384 : :
385 : : /* Whether or not a numeric constraint allows a register is
386 : : decided by the matching constraint, and so there is no need
387 : : to do anything special with them. We must handle them in
388 : : the default case, so that we don't unnecessarily force
389 : : operands to memory. */
390 : 12046597 : case '0': case '1': case '2': case '3': case '4':
391 : 12046597 : case '5': case '6': case '7': case '8': case '9':
392 : 12046597 : {
393 : 12046597 : char *end;
394 : 12046597 : unsigned long match;
395 : :
396 : 12046597 : saw_match = true;
397 : :
398 : 12046597 : match = strtoul (constraint + j, &end, 10);
399 : 12046597 : if (match >= (unsigned long) noutputs)
400 : : {
401 : 4 : error ("matching constraint references invalid operand number");
402 : 4 : return false;
403 : : }
404 : :
405 : : /* Try and find the real constraint for this dup. Only do this
406 : : if the matching constraint is the only alternative. */
407 : 12046593 : if (*end == '\0'
408 : 11982537 : && (j == 0 || (j == 1 && constraint[0] == '%')))
409 : : {
410 : 11971248 : constraint = constraints[match];
411 : 11971248 : *constraint_p = constraint;
412 : 11971248 : c_len = strlen (constraint);
413 : 11971248 : j = 0;
414 : : /* ??? At the end of the loop, we will skip the first part of
415 : : the matched constraint. This assumes not only that the
416 : : other constraint is an output constraint, but also that
417 : : the '=' or '+' come first. */
418 : 11971248 : break;
419 : : }
420 : : else
421 : 75345 : j = end - constraint;
422 : : /* Anticipate increment at end of loop. */
423 : 75345 : j--;
424 : : }
425 : : /* Fall through. */
426 : :
427 : 2866049 : case 'g': case 'X':
428 : 2866049 : *allows_reg = true;
429 : 2866049 : *allows_mem = true;
430 : 2866049 : break;
431 : :
432 : 18054465 : default:
433 : 18054465 : if (! ISALPHA (constraint[j]))
434 : : {
435 : 2 : error ("invalid punctuation %qc in constraint", constraint[j]);
436 : 2 : return false;
437 : : }
438 : 18054463 : enum constraint_num cn = lookup_constraint (constraint + j);
439 : 18054463 : if (reg_class_for_constraint (cn) != NO_REGS
440 : 18054463 : || insn_extra_address_constraint (cn))
441 : 15413894 : *allows_reg = true;
442 : : else if (insn_extra_memory_constraint (cn)
443 : : || insn_extra_special_memory_constraint (cn)
444 : : || insn_extra_relaxed_memory_constraint (cn))
445 : 2404699 : *allows_mem = true;
446 : : else
447 : : insn_extra_constraint_allows_reg_mem (cn, allows_reg, allows_mem);
448 : : break;
449 : : }
450 : :
451 : 20650767 : if (saw_match && !*allows_reg)
452 : 4 : warning (0, "matching constraint does not allow a register");
453 : :
454 : : return true;
455 : : }
456 : :
457 : : /* Return DECL iff there's an overlap between *REGS and DECL, where DECL
458 : : can be an asm-declared register. Called via walk_tree. */
459 : :
460 : : static tree
461 : 139490 : decl_overlaps_hard_reg_set_p (tree *declp, int *walk_subtrees ATTRIBUTE_UNUSED,
462 : : void *data)
463 : : {
464 : 139490 : tree decl = *declp;
465 : 139490 : const HARD_REG_SET *const regs = (const HARD_REG_SET *) data;
466 : :
467 : 139490 : if (VAR_P (decl))
468 : : {
469 : 20429 : if (DECL_HARD_REGISTER (decl)
470 : 1837 : && REG_P (DECL_RTL (decl))
471 : 22266 : && REGNO (DECL_RTL (decl)) < FIRST_PSEUDO_REGISTER)
472 : : {
473 : 1837 : rtx reg = DECL_RTL (decl);
474 : :
475 : 1837 : if (overlaps_hard_reg_set_p (*regs, GET_MODE (reg), REGNO (reg)))
476 : : return decl;
477 : : }
478 : : walk_subtrees = 0;
479 : : }
480 : : else if (TYPE_P (decl) || TREE_CODE (decl) == PARM_DECL)
481 : 139490 : walk_subtrees = 0;
482 : : return NULL_TREE;
483 : : }
484 : :
485 : : /* If there is an overlap between *REGS and DECL, return the first overlap
486 : : found. */
487 : : tree
488 : 123453 : tree_overlaps_hard_reg_set (tree decl, HARD_REG_SET *regs)
489 : : {
490 : 123453 : return walk_tree (&decl, decl_overlaps_hard_reg_set_p, regs, NULL);
491 : : }
492 : :
493 : :
494 : : /* A subroutine of expand_asm_operands. Check that all operand names
495 : : are unique. Return true if so. We rely on the fact that these names
496 : : are identifiers, and so have been canonicalized by get_identifier,
497 : : so all we need are pointer comparisons. */
498 : :
499 : : static bool
500 : 211606 : check_unique_operand_names (tree outputs, tree inputs, tree labels)
501 : : {
502 : 211606 : tree i, j, i_name = NULL_TREE;
503 : :
504 : 566116 : for (i = outputs; i ; i = TREE_CHAIN (i))
505 : : {
506 : 354510 : i_name = TREE_PURPOSE (TREE_PURPOSE (i));
507 : 354510 : if (! i_name)
508 : 354101 : continue;
509 : :
510 : 2328 : for (j = TREE_CHAIN (i); j ; j = TREE_CHAIN (j))
511 : 1919 : if (simple_cst_equal (i_name, TREE_PURPOSE (TREE_PURPOSE (j))))
512 : 0 : goto failure;
513 : : }
514 : :
515 : 580117 : for (i = inputs; i ; i = TREE_CHAIN (i))
516 : : {
517 : 368516 : i_name = TREE_PURPOSE (TREE_PURPOSE (i));
518 : 368516 : if (! i_name)
519 : 368378 : continue;
520 : :
521 : 359 : for (j = TREE_CHAIN (i); j ; j = TREE_CHAIN (j))
522 : 221 : if (simple_cst_equal (i_name, TREE_PURPOSE (TREE_PURPOSE (j))))
523 : 0 : goto failure;
524 : 443 : for (j = outputs; j ; j = TREE_CHAIN (j))
525 : 310 : if (simple_cst_equal (i_name, TREE_PURPOSE (TREE_PURPOSE (j))))
526 : 5 : goto failure;
527 : : }
528 : :
529 : 212356 : for (i = labels; i ; i = TREE_CHAIN (i))
530 : : {
531 : 763 : i_name = TREE_PURPOSE (i);
532 : 763 : if (! i_name)
533 : 0 : continue;
534 : :
535 : 2101 : for (j = TREE_CHAIN (i); j ; j = TREE_CHAIN (j))
536 : 1342 : if (simple_cst_equal (i_name, TREE_PURPOSE (j)))
537 : 4 : goto failure;
538 : 1069 : for (j = inputs; j ; j = TREE_CHAIN (j))
539 : 314 : if (simple_cst_equal (i_name, TREE_PURPOSE (TREE_PURPOSE (j))))
540 : 4 : goto failure;
541 : : }
542 : :
543 : : return true;
544 : :
545 : 13 : failure:
546 : 13 : error ("duplicate %<asm%> operand name %qs", TREE_STRING_POINTER (i_name));
547 : 13 : return false;
548 : : }
549 : :
550 : : /* Resolve the names of the operands in *POUTPUTS and *PINPUTS to numbers,
551 : : and replace the name expansions in STRING and in the constraints to
552 : : those numbers. This is generally done in the front end while creating
553 : : the ASM_EXPR generic tree that eventually becomes the GIMPLE_ASM. */
554 : :
555 : : tree
556 : 211606 : resolve_asm_operand_names (tree string, tree outputs, tree inputs, tree labels)
557 : : {
558 : 211606 : char *buffer;
559 : 211606 : char *p;
560 : 211606 : const char *c;
561 : 211606 : tree t;
562 : :
563 : 211606 : check_unique_operand_names (outputs, inputs, labels);
564 : :
565 : : /* Substitute [<name>] in input constraint strings. There should be no
566 : : named operands in output constraints. */
567 : 791728 : for (t = inputs; t ; t = TREE_CHAIN (t))
568 : : {
569 : 368516 : c = TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (t)));
570 : 368516 : if (strchr (c, '[') != NULL)
571 : : {
572 : 179 : p = buffer = xstrdup (c);
573 : 537 : while ((p = strchr (p, '[')) != NULL)
574 : 179 : p = resolve_operand_name_1 (p, outputs, inputs, NULL);
575 : 179 : TREE_VALUE (TREE_PURPOSE (t))
576 : 179 : = build_string (strlen (buffer), buffer);
577 : 179 : free (buffer);
578 : : }
579 : : }
580 : :
581 : : /* Now check for any needed substitutions in the template. */
582 : 211606 : c = TREE_STRING_POINTER (string);
583 : 251605 : while ((c = strchr (c, '%')) != NULL)
584 : : {
585 : 40149 : if (c[1] == '[')
586 : : break;
587 : 40089 : else if (ISALPHA (c[1]) && c[2] == '[')
588 : : break;
589 : : else
590 : : {
591 : 39999 : c += 1 + (c[1] == '%');
592 : 39999 : continue;
593 : : }
594 : : }
595 : :
596 : 211606 : if (c)
597 : : {
598 : : /* OK, we need to make a copy so we can perform the substitutions.
599 : : Assume that we will not need extra space--we get to remove '['
600 : : and ']', which means we cannot have a problem until we have more
601 : : than 999 operands. */
602 : 150 : buffer = xstrdup (TREE_STRING_POINTER (string));
603 : 150 : p = buffer + (c - TREE_STRING_POINTER (string));
604 : :
605 : 459 : while ((p = strchr (p, '%')) != NULL)
606 : : {
607 : 309 : if (p[1] == '[')
608 : 125 : p += 1;
609 : 184 : else if (ISALPHA (p[1]) && p[2] == '[')
610 : 142 : p += 2;
611 : : else
612 : : {
613 : 42 : p += 1 + (p[1] == '%');
614 : 42 : continue;
615 : : }
616 : :
617 : 267 : p = resolve_operand_name_1 (p, outputs, inputs, labels);
618 : : }
619 : :
620 : 150 : string = build_string (strlen (buffer), buffer);
621 : 150 : free (buffer);
622 : : }
623 : :
624 : 211606 : return string;
625 : : }
626 : :
627 : : /* A subroutine of resolve_operand_names. P points to the '[' for a
628 : : potential named operand of the form [<name>]. In place, replace
629 : : the name and brackets with a number. Return a pointer to the
630 : : balance of the string after substitution. */
631 : :
632 : : static char *
633 : 446 : resolve_operand_name_1 (char *p, tree outputs, tree inputs, tree labels)
634 : : {
635 : 446 : char *q;
636 : 446 : int op, op_inout;
637 : 446 : tree t;
638 : :
639 : : /* Collect the operand name. */
640 : 446 : q = strchr (++p, ']');
641 : 446 : if (!q)
642 : : {
643 : 0 : error ("missing close brace for named operand");
644 : 0 : return strchr (p, '\0');
645 : : }
646 : 446 : *q = '\0';
647 : :
648 : : /* Resolve the name to a number. */
649 : 1720 : for (op_inout = op = 0, t = outputs; t ; t = TREE_CHAIN (t), op++)
650 : : {
651 : 1507 : tree name = TREE_PURPOSE (TREE_PURPOSE (t));
652 : 2759 : if (name && strcmp (TREE_STRING_POINTER (name), p) == 0)
653 : 233 : goto found;
654 : 1274 : tree constraint = TREE_VALUE (TREE_PURPOSE (t));
655 : 2548 : if (constraint && strchr (TREE_STRING_POINTER (constraint), '+') != NULL)
656 : 64 : op_inout++;
657 : : }
658 : 379 : for (t = inputs; t ; t = TREE_CHAIN (t), op++)
659 : : {
660 : 280 : tree name = TREE_PURPOSE (TREE_PURPOSE (t));
661 : 459 : if (name && strcmp (TREE_STRING_POINTER (name), p) == 0)
662 : 114 : goto found;
663 : : }
664 : 99 : op += op_inout;
665 : 108 : for (t = labels; t ; t = TREE_CHAIN (t), op++)
666 : : {
667 : 105 : tree name = TREE_PURPOSE (t);
668 : 210 : if (name && strcmp (TREE_STRING_POINTER (name), p) == 0)
669 : 96 : goto found;
670 : : }
671 : :
672 : 3 : error ("undefined named operand %qs", identifier_to_locale (p));
673 : 3 : op = 0;
674 : :
675 : 446 : found:
676 : : /* Replace the name with the number. Unfortunately, not all libraries
677 : : get the return value of sprintf correct, so search for the end of the
678 : : generated string by hand. */
679 : 446 : sprintf (--p, "%d", op);
680 : 446 : p = strchr (p, '\0');
681 : :
682 : : /* Verify the no extra buffer space assumption. */
683 : 446 : gcc_assert (p <= q);
684 : :
685 : : /* Shift the rest of the buffer down to fill the gap. */
686 : 446 : memmove (p, q + 1, strlen (q + 1) + 1);
687 : :
688 : 446 : return p;
689 : : }
690 : :
691 : :
692 : : /* Generate RTL to return directly from the current function.
693 : : (That is, we bypass any return value.) */
694 : :
695 : : void
696 : 379 : expand_naked_return (void)
697 : : {
698 : 379 : rtx_code_label *end_label;
699 : :
700 : 379 : clear_pending_stack_adjust ();
701 : 379 : do_pending_stack_adjust ();
702 : :
703 : 379 : end_label = naked_return_label;
704 : 379 : if (end_label == 0)
705 : 379 : end_label = naked_return_label = gen_label_rtx ();
706 : :
707 : 379 : emit_jump (end_label);
708 : 379 : }
709 : :
710 : : /* Generate code to jump to LABEL if OP0 and OP1 are equal in mode MODE. PROB
711 : : is the probability of jumping to LABEL. */
712 : : static void
713 : 0 : do_jump_if_equal (machine_mode mode, rtx op0, rtx op1, rtx_code_label *label,
714 : : int unsignedp, profile_probability prob)
715 : : {
716 : 0 : do_compare_rtx_and_jump (op0, op1, EQ, unsignedp, mode,
717 : : NULL_RTX, NULL, label, prob);
718 : 0 : }
719 : :
720 : : /* Return the sum of probabilities of outgoing edges of basic block BB. */
721 : :
722 : : static profile_probability
723 : 9843 : get_outgoing_edge_probs (basic_block bb)
724 : : {
725 : 9843 : edge e;
726 : 9843 : edge_iterator ei;
727 : 9843 : profile_probability prob_sum = profile_probability::never ();
728 : 9843 : if (!bb)
729 : 0 : return profile_probability::never ();
730 : 102318 : FOR_EACH_EDGE (e, ei, bb->succs)
731 : 92475 : prob_sum += e->probability;
732 : 9843 : return prob_sum;
733 : : }
734 : :
735 : : /* Computes the conditional probability of jumping to a target if the branch
736 : : instruction is executed.
737 : : TARGET_PROB is the estimated probability of jumping to a target relative
738 : : to some basic block BB.
739 : : BASE_PROB is the probability of reaching the branch instruction relative
740 : : to the same basic block BB. */
741 : :
742 : : static inline profile_probability
743 : 14421 : conditional_probability (profile_probability target_prob,
744 : : profile_probability base_prob)
745 : : {
746 : 14421 : return target_prob / base_prob;
747 : : }
748 : :
749 : : /* Generate a dispatch tabler, switching on INDEX_EXPR and jumping to
750 : : one of the labels in CASE_LIST or to the DEFAULT_LABEL.
751 : : MINVAL, MAXVAL, and RANGE are the extrema and range of the case
752 : : labels in CASE_LIST. STMT_BB is the basic block containing the statement.
753 : :
754 : : First, a jump insn is emitted. First we try "casesi". If that
755 : : fails, try "tablejump". A target *must* have one of them (or both).
756 : :
757 : : Then, a table with the target labels is emitted.
758 : :
759 : : The process is unaware of the CFG. The caller has to fix up
760 : : the CFG itself. This is done in cfgexpand.cc. */
761 : :
762 : : static void
763 : 9843 : emit_case_dispatch_table (tree index_expr, tree index_type,
764 : : auto_vec<simple_case_node> &case_list,
765 : : rtx default_label,
766 : : edge default_edge, tree minval, tree maxval,
767 : : tree range, basic_block stmt_bb)
768 : : {
769 : 9843 : int i, ncases;
770 : 9843 : auto_vec<rtx> labelvec;
771 : 9843 : rtx_insn *fallback_label = label_rtx (case_list[0].m_code_label);
772 : 9843 : rtx_code_label *table_label = gen_label_rtx ();
773 : 9843 : bool has_gaps = false;
774 : 9843 : profile_probability default_prob = default_edge ? default_edge->probability
775 : 9843 : : profile_probability::never ();
776 : 9843 : profile_probability base = get_outgoing_edge_probs (stmt_bb);
777 : 9843 : bool try_with_tablejump = false;
778 : :
779 : 9843 : profile_probability new_default_prob = conditional_probability (default_prob,
780 : : base);
781 : :
782 : 9843 : if (! try_casesi (index_type, index_expr, minval, range,
783 : : table_label, default_label, fallback_label,
784 : : new_default_prob))
785 : : {
786 : : /* Index jumptables from zero for suitable values of minval to avoid
787 : : a subtraction. For the rationale see:
788 : : "http://gcc.gnu.org/ml/gcc-patches/2001-10/msg01234.html". */
789 : 9843 : if (optimize_insn_for_speed_p ()
790 : 9580 : && compare_tree_int (minval, 0) > 0
791 : 13278 : && compare_tree_int (minval, 3) < 0)
792 : : {
793 : 1019 : minval = build_int_cst (index_type, 0);
794 : 1019 : range = maxval;
795 : 1019 : has_gaps = true;
796 : : }
797 : : try_with_tablejump = true;
798 : : }
799 : :
800 : : /* Get table of labels to jump to, in order of case index. */
801 : :
802 : 9843 : ncases = tree_to_shwi (range) + 1;
803 : 9843 : labelvec.safe_grow_cleared (ncases);
804 : :
805 : 107630 : for (unsigned j = 0; j < case_list.length (); j++)
806 : : {
807 : 97787 : simple_case_node *n = &case_list[j];
808 : : /* Compute the low and high bounds relative to the minimum
809 : : value since that should fit in a HOST_WIDE_INT while the
810 : : actual values may not. */
811 : 97787 : HOST_WIDE_INT i_low
812 : 97787 : = tree_to_uhwi (fold_build2 (MINUS_EXPR, index_type,
813 : 97787 : n->m_low, minval));
814 : 97787 : HOST_WIDE_INT i_high
815 : 97787 : = tree_to_uhwi (fold_build2 (MINUS_EXPR, index_type,
816 : 97787 : n->m_high, minval));
817 : 97787 : HOST_WIDE_INT i;
818 : :
819 : 212435 : for (i = i_low; i <= i_high; i ++)
820 : 343944 : labelvec[i]
821 : 125993 : = gen_rtx_LABEL_REF (Pmode, label_rtx (n->m_code_label));
822 : : }
823 : :
824 : : /* The dispatch table may contain gaps, including at the beginning of
825 : : the table if we tried to avoid the minval subtraction. We fill the
826 : : dispatch table slots associated with the gaps with the default case label.
827 : : However, in the event the default case is unreachable, we then use
828 : : any label from one of the case statements. */
829 : 9843 : rtx gap_label = (default_label) ? default_label : fallback_label;
830 : :
831 : 234497 : for (i = 0; i < ncases; i++)
832 : 224654 : if (labelvec[i] == 0)
833 : : {
834 : 110006 : has_gaps = true;
835 : 121773 : labelvec[i] = gen_rtx_LABEL_REF (Pmode, gap_label);
836 : : }
837 : :
838 : 9843 : if (has_gaps && default_label)
839 : : {
840 : : /* There is at least one entry in the jump table that jumps
841 : : to default label. The default label can either be reached
842 : : through the indirect jump or the direct conditional jump
843 : : before that. Split the probability of reaching the
844 : : default label among these two jumps. */
845 : 4578 : new_default_prob = conditional_probability (default_prob / 2, base);
846 : 4578 : default_prob /= 2;
847 : 4578 : base -= default_prob;
848 : : }
849 : : else
850 : : {
851 : 5265 : base -= default_prob;
852 : 5265 : default_prob = profile_probability::never ();
853 : : }
854 : :
855 : 9843 : if (default_edge)
856 : 5601 : default_edge->probability = default_prob;
857 : :
858 : : /* We have altered the probability of the default edge. So the probabilities
859 : : of all other edges need to be adjusted so that it sums up to
860 : : REG_BR_PROB_BASE. */
861 : 9843 : if (base > profile_probability::never ())
862 : : {
863 : 9843 : edge e;
864 : 9843 : edge_iterator ei;
865 : 102318 : FOR_EACH_EDGE (e, ei, stmt_bb->succs)
866 : 92475 : e->probability /= base;
867 : : }
868 : :
869 : 9843 : if (try_with_tablejump)
870 : : {
871 : 9843 : bool ok = try_tablejump (index_type, index_expr, minval, range,
872 : : table_label, default_label, new_default_prob);
873 : 9843 : gcc_assert (ok);
874 : : }
875 : : /* Output the table. */
876 : 9843 : emit_label (table_label);
877 : :
878 : 9843 : if (CASE_VECTOR_PC_RELATIVE
879 : 9843 : || (flag_pic && targetm.asm_out.generate_pic_addr_diff_vec ()))
880 : 3375 : emit_jump_table_data (gen_rtx_ADDR_DIFF_VEC (CASE_VECTOR_MODE,
881 : : gen_rtx_LABEL_REF (Pmode,
882 : : table_label),
883 : : gen_rtvec_v (ncases, labelvec.address ()),
884 : : const0_rtx, const0_rtx));
885 : : else
886 : 18247 : emit_jump_table_data (gen_rtx_ADDR_VEC (CASE_VECTOR_MODE,
887 : : gen_rtvec_v (ncases, labelvec.address ())));
888 : :
889 : : /* Record no drop-through after the table. */
890 : 9843 : emit_barrier ();
891 : 9843 : }
892 : :
893 : : /* Terminate a case Ada or switch (C) statement
894 : : in which ORIG_INDEX is the expression to be tested.
895 : : If ORIG_TYPE is not NULL, it is the original ORIG_INDEX
896 : : type as given in the source before any compiler conversions.
897 : : Generate the code to test it and jump to the right place. */
898 : :
899 : : void
900 : 9843 : expand_case (gswitch *stmt)
901 : : {
902 : 9843 : tree minval = NULL_TREE, maxval = NULL_TREE, range = NULL_TREE;
903 : 9843 : rtx_code_label *default_label;
904 : 9843 : unsigned int count;
905 : 9843 : int i;
906 : 9843 : int ncases = gimple_switch_num_labels (stmt);
907 : 9843 : tree index_expr = gimple_switch_index (stmt);
908 : 9843 : tree index_type = TREE_TYPE (index_expr);
909 : 9843 : tree elt;
910 : 9843 : basic_block bb = gimple_bb (stmt);
911 : 9843 : gimple *def_stmt;
912 : :
913 : 9843 : auto_vec<simple_case_node> case_list;
914 : :
915 : : /* An ERROR_MARK occurs for various reasons including invalid data type.
916 : : ??? Can this still happen, with GIMPLE and all? */
917 : 9843 : if (index_type == error_mark_node)
918 : 0 : return;
919 : :
920 : : /* cleanup_tree_cfg removes all SWITCH_EXPR with their index
921 : : expressions being INTEGER_CST. */
922 : 9843 : gcc_assert (TREE_CODE (index_expr) != INTEGER_CST);
923 : :
924 : : /* Optimization of switch statements with only one label has already
925 : : occurred, so we should never see them at this point. */
926 : 9843 : gcc_assert (ncases > 1);
927 : :
928 : 9843 : do_pending_stack_adjust ();
929 : :
930 : : /* Find the default case target label. */
931 : 9843 : tree default_lab = CASE_LABEL (gimple_switch_default_label (stmt));
932 : 9843 : default_label = jump_target_rtx (default_lab);
933 : 9843 : basic_block default_bb = label_to_block (cfun, default_lab);
934 : 9843 : edge default_edge = find_edge (bb, default_bb);
935 : :
936 : : /* Get upper and lower bounds of case values. */
937 : 9843 : elt = gimple_switch_label (stmt, 1);
938 : 9843 : minval = fold_convert (index_type, CASE_LOW (elt));
939 : 9843 : elt = gimple_switch_label (stmt, ncases - 1);
940 : 9843 : if (CASE_HIGH (elt))
941 : 2583 : maxval = fold_convert (index_type, CASE_HIGH (elt));
942 : : else
943 : 7260 : maxval = fold_convert (index_type, CASE_LOW (elt));
944 : :
945 : : /* Try to narrow the index type if it's larger than a word.
946 : : That is mainly for -O0 where an equivalent optimization
947 : : done by forward propagation is not run and is aimed at
948 : : avoiding a call to a comparison routine of libgcc. */
949 : 9843 : if (TYPE_PRECISION (index_type) > BITS_PER_WORD
950 : 6 : && TREE_CODE (index_expr) == SSA_NAME
951 : 6 : && (def_stmt = SSA_NAME_DEF_STMT (index_expr))
952 : 6 : && is_gimple_assign (def_stmt)
953 : 9846 : && gimple_assign_rhs_code (def_stmt) == NOP_EXPR)
954 : : {
955 : 0 : tree inner_index_expr = gimple_assign_rhs1 (def_stmt);
956 : 0 : tree inner_index_type = TREE_TYPE (inner_index_expr);
957 : :
958 : 0 : if (INTEGRAL_TYPE_P (inner_index_type)
959 : 0 : && TYPE_PRECISION (inner_index_type) <= BITS_PER_WORD
960 : 0 : && int_fits_type_p (minval, inner_index_type)
961 : 0 : && int_fits_type_p (maxval, inner_index_type))
962 : : {
963 : 0 : index_expr = inner_index_expr;
964 : 0 : index_type = inner_index_type;
965 : 0 : minval = fold_convert (index_type, minval);
966 : 0 : maxval = fold_convert (index_type, maxval);
967 : : }
968 : : }
969 : :
970 : : /* Compute span of values. */
971 : 9843 : range = fold_build2 (MINUS_EXPR, index_type, maxval, minval);
972 : :
973 : : /* Listify the labels queue and gather some numbers to decide
974 : : how to expand this switch(). */
975 : 9843 : count = 0;
976 : :
977 : 107630 : for (i = ncases - 1; i >= 1; --i)
978 : : {
979 : 97787 : elt = gimple_switch_label (stmt, i);
980 : 97787 : tree low = CASE_LOW (elt);
981 : 97787 : gcc_assert (low);
982 : 97787 : tree high = CASE_HIGH (elt);
983 : 97787 : gcc_assert (! high || tree_int_cst_lt (low, high));
984 : 97787 : tree lab = CASE_LABEL (elt);
985 : :
986 : : /* Count the elements.
987 : : A range counts double, since it requires two compares. */
988 : 97787 : count++;
989 : 97787 : if (high)
990 : 8782 : count++;
991 : :
992 : : /* The bounds on the case range, LOW and HIGH, have to be converted
993 : : to case's index type TYPE. Note that the original type of the
994 : : case index in the source code is usually "lost" during
995 : : gimplification due to type promotion, but the case labels retain the
996 : : original type. Make sure to drop overflow flags. */
997 : 97787 : low = fold_convert (index_type, low);
998 : 97787 : if (TREE_OVERFLOW (low))
999 : 0 : low = wide_int_to_tree (index_type, wi::to_wide (low));
1000 : :
1001 : : /* The canonical from of a case label in GIMPLE is that a simple case
1002 : : has an empty CASE_HIGH. For the casesi and tablejump expanders,
1003 : : the back ends want simple cases to have high == low. */
1004 : 97787 : if (! high)
1005 : 89005 : high = low;
1006 : 97787 : high = fold_convert (index_type, high);
1007 : 97787 : if (TREE_OVERFLOW (high))
1008 : 0 : high = wide_int_to_tree (index_type, wi::to_wide (high));
1009 : :
1010 : 97787 : case_list.safe_push (simple_case_node (low, high, lab));
1011 : : }
1012 : :
1013 : : /* cleanup_tree_cfg removes all SWITCH_EXPR with a single
1014 : : destination, such as one with a default case only.
1015 : : It also removes cases that are out of range for the switch
1016 : : type, so we should never get a zero here. */
1017 : 9843 : gcc_assert (count > 0);
1018 : :
1019 : 9843 : rtx_insn *before_case = get_last_insn ();
1020 : :
1021 : : /* If the default case is unreachable, then set default_label to NULL
1022 : : so that we omit the range check when generating the dispatch table.
1023 : : We also remove the edge to the unreachable default case. The block
1024 : : itself will be automatically removed later. */
1025 : 9843 : if (EDGE_COUNT (default_edge->dest->succs) == 0
1026 : 14937 : && gimple_seq_unreachable_p (bb_seq (default_edge->dest)))
1027 : : {
1028 : 4242 : default_label = NULL;
1029 : 4242 : expand_remove_edge (default_edge);
1030 : 4242 : default_edge = NULL;
1031 : : }
1032 : :
1033 : 9843 : emit_case_dispatch_table (index_expr, index_type,
1034 : : case_list, default_label, default_edge,
1035 : : minval, maxval, range, bb);
1036 : :
1037 : 9843 : reorder_insns (NEXT_INSN (before_case), get_last_insn (), before_case);
1038 : :
1039 : 9843 : free_temp_slots ();
1040 : 9843 : }
1041 : :
1042 : : /* Expand the dispatch to a short decrement chain if there are few cases
1043 : : to dispatch to. Likewise if neither casesi nor tablejump is available,
1044 : : or if flag_jump_tables is set. Otherwise, expand as a casesi or a
1045 : : tablejump. The index mode is always the mode of integer_type_node.
1046 : : Trap if no case matches the index.
1047 : :
1048 : : DISPATCH_INDEX is the index expression to switch on. It should be a
1049 : : memory or register operand.
1050 : :
1051 : : DISPATCH_TABLE is a set of case labels. The set should be sorted in
1052 : : ascending order, be contiguous, starting with value 0, and contain only
1053 : : single-valued case labels. */
1054 : :
1055 : : void
1056 : 0 : expand_sjlj_dispatch_table (rtx dispatch_index,
1057 : : vec<tree> dispatch_table)
1058 : : {
1059 : 0 : tree index_type = integer_type_node;
1060 : 0 : machine_mode index_mode = TYPE_MODE (index_type);
1061 : :
1062 : 0 : int ncases = dispatch_table.length ();
1063 : :
1064 : 0 : do_pending_stack_adjust ();
1065 : 0 : rtx_insn *before_case = get_last_insn ();
1066 : :
1067 : : /* Expand as a decrement-chain if there are 5 or fewer dispatch
1068 : : labels. This covers more than 98% of the cases in libjava,
1069 : : and seems to be a reasonable compromise between the "old way"
1070 : : of expanding as a decision tree or dispatch table vs. the "new
1071 : : way" with decrement chain or dispatch table. */
1072 : 0 : if (dispatch_table.length () <= 5
1073 : 0 : || (!targetm.have_casesi () && !targetm.have_tablejump ())
1074 : 0 : || !flag_jump_tables)
1075 : : {
1076 : : /* Expand the dispatch as a decrement chain:
1077 : :
1078 : : "switch(index) {case 0: do_0; case 1: do_1; ...; case N: do_N;}"
1079 : :
1080 : : ==>
1081 : :
1082 : : if (index == 0) do_0; else index--;
1083 : : if (index == 0) do_1; else index--;
1084 : : ...
1085 : : if (index == 0) do_N; else index--;
1086 : :
1087 : : This is more efficient than a dispatch table on most machines.
1088 : : The last "index--" is redundant but the code is trivially dead
1089 : : and will be cleaned up by later passes. */
1090 : 0 : rtx index = copy_to_mode_reg (index_mode, dispatch_index);
1091 : 0 : rtx zero = CONST0_RTX (index_mode);
1092 : 0 : for (int i = 0; i < ncases; i++)
1093 : : {
1094 : 0 : tree elt = dispatch_table[i];
1095 : 0 : rtx_code_label *lab = jump_target_rtx (CASE_LABEL (elt));
1096 : 0 : do_jump_if_equal (index_mode, index, zero, lab, 0,
1097 : : profile_probability::uninitialized ());
1098 : 0 : force_expand_binop (index_mode, sub_optab,
1099 : : index, CONST1_RTX (index_mode),
1100 : : index, 0, OPTAB_DIRECT);
1101 : : }
1102 : : }
1103 : : else
1104 : : {
1105 : : /* Similar to expand_case, but much simpler. */
1106 : 0 : auto_vec<simple_case_node> case_list;
1107 : 0 : tree index_expr = make_tree (index_type, dispatch_index);
1108 : 0 : tree minval = build_int_cst (index_type, 0);
1109 : 0 : tree maxval = CASE_LOW (dispatch_table.last ());
1110 : 0 : tree range = maxval;
1111 : 0 : rtx_code_label *default_label = gen_label_rtx ();
1112 : :
1113 : 0 : for (int i = ncases - 1; i >= 0; --i)
1114 : : {
1115 : 0 : tree elt = dispatch_table[i];
1116 : 0 : tree high = CASE_HIGH (elt);
1117 : 0 : if (high == NULL_TREE)
1118 : 0 : high = CASE_LOW (elt);
1119 : 0 : case_list.safe_push (simple_case_node (CASE_LOW (elt), high,
1120 : 0 : CASE_LABEL (elt)));
1121 : : }
1122 : :
1123 : 0 : emit_case_dispatch_table (index_expr, index_type,
1124 : : case_list, default_label, NULL,
1125 : : minval, maxval, range,
1126 : 0 : BLOCK_FOR_INSN (before_case));
1127 : 0 : emit_label (default_label);
1128 : 0 : }
1129 : :
1130 : : /* Dispatching something not handled? Trap! */
1131 : 0 : expand_builtin_trap ();
1132 : :
1133 : 0 : reorder_insns (NEXT_INSN (before_case), get_last_insn (), before_case);
1134 : :
1135 : 0 : free_temp_slots ();
1136 : 0 : }
1137 : :
1138 : :
|