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