1 /* Subroutines used by or related to instruction recognition.
2    Copyright (C) 1987-2022 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 
21 #include "config.h"
22 #include "system.h"
23 #include "coretypes.h"
24 #include "backend.h"
25 #include "target.h"
26 #include "rtl.h"
27 #include "tree.h"
28 #include "cfghooks.h"
29 #include "df.h"
30 #include "memmodel.h"
31 #include "tm_p.h"
32 #include "insn-config.h"
33 #include "regs.h"
34 #include "emit-rtl.h"
35 #include "recog.h"
36 #include "insn-attr.h"
37 #include "addresses.h"
38 #include "cfgrtl.h"
39 #include "cfgbuild.h"
40 #include "cfgcleanup.h"
41 #include "reload.h"
42 #include "tree-pass.h"
43 #include "function-abi.h"
44 
45 #ifndef STACK_POP_CODE
46 #if STACK_GROWS_DOWNWARD
47 #define STACK_POP_CODE POST_INC
48 #else
49 #define STACK_POP_CODE POST_DEC
50 #endif
51 #endif
52 
53 static void validate_replace_rtx_1 (rtx *, rtx, rtx, rtx_insn *, bool);
54 static void validate_replace_src_1 (rtx *, void *);
55 static rtx_insn *split_insn (rtx_insn *);
56 
57 struct target_recog default_target_recog;
58 #if SWITCHABLE_TARGET
59 struct target_recog *this_target_recog = &default_target_recog;
60 #endif
61 
62 /* Nonzero means allow operands to be volatile.
63    This should be 0 if you are generating rtl, such as if you are calling
64    the functions in optabs.cc and expmed.cc (most of the time).
65    This should be 1 if all valid insns need to be recognized,
66    such as in reginfo.cc and final.cc and reload.cc.
67 
68    init_recog and init_recog_no_volatile are responsible for setting this.  */
69 
70 int volatile_ok;
71 
72 struct recog_data_d recog_data;
73 
74 /* Contains a vector of operand_alternative structures, such that
75    operand OP of alternative A is at index A * n_operands + OP.
76    Set up by preprocess_constraints.  */
77 const operand_alternative *recog_op_alt;
78 
79 /* Used to provide recog_op_alt for asms.  */
80 static operand_alternative asm_op_alt[MAX_RECOG_OPERANDS
81                                               * MAX_RECOG_ALTERNATIVES];
82 
83 /* On return from `constrain_operands', indicate which alternative
84    was satisfied.  */
85 
86 int which_alternative;
87 
88 /* Nonzero after end of reload pass.
89    Set to 1 or 0 by toplev.cc.
90    Controls the significance of (SUBREG (MEM)).  */
91 
92 int reload_completed;
93 
94 /* Nonzero after thread_prologue_and_epilogue_insns has run.  */
95 int epilogue_completed;
96 
97 /* Initialize data used by the function `recog'.
98    This must be called once in the compilation of a function
99    before any insn recognition may be done in the function.  */
100 
101 void
init_recog_no_volatile(void)102 init_recog_no_volatile (void)
103 {
104   volatile_ok = 0;
105 }
106 
107 void
init_recog(void)108 init_recog (void)
109 {
110   volatile_ok = 1;
111 }
112 
113 
114 /* Return true if labels in asm operands BODY are LABEL_REFs.  */
115 
116 static bool
asm_labels_ok(rtx body)117 asm_labels_ok (rtx body)
118 {
119   rtx asmop;
120   int i;
121 
122   asmop = extract_asm_operands (body);
123   if (asmop == NULL_RTX)
124     return true;
125 
126   for (i = 0; i < ASM_OPERANDS_LABEL_LENGTH (asmop); i++)
127     if (GET_CODE (ASM_OPERANDS_LABEL (asmop, i)) != LABEL_REF)
128       return false;
129 
130   return true;
131 }
132 
133 /* Check that X is an insn-body for an `asm' with operands
134    and that the operands mentioned in it are legitimate.  */
135 
136 int
check_asm_operands(rtx x)137 check_asm_operands (rtx x)
138 {
139   int noperands;
140   rtx *operands;
141   const char **constraints;
142   int i;
143 
144   if (!asm_labels_ok (x))
145     return 0;
146 
147   /* Post-reload, be more strict with things.  */
148   if (reload_completed)
149     {
150       /* ??? Doh!  We've not got the wrapping insn.  Cook one up.  */
151       rtx_insn *insn = make_insn_raw (x);
152       extract_insn (insn);
153       constrain_operands (1, get_enabled_alternatives (insn));
154       return which_alternative >= 0;
155     }
156 
157   noperands = asm_noperands (x);
158   if (noperands < 0)
159     return 0;
160   if (noperands == 0)
161     return 1;
162 
163   operands = XALLOCAVEC (rtx, noperands);
164   constraints = XALLOCAVEC (const char *, noperands);
165 
166   decode_asm_operands (x, operands, NULL, constraints, NULL, NULL);
167 
168   for (i = 0; i < noperands; i++)
169     {
170       const char *c = constraints[i];
171       if (c[0] == '%')
172           c++;
173       if (! asm_operand_ok (operands[i], c, constraints))
174           return 0;
175     }
176 
177   return 1;
178 }
179 
180 /* Static data for the next two routines.  */
181 
182 struct change_t
183 {
184   rtx object;
185   int old_code;
186   int old_len;
187   bool unshare;
188   rtx *loc;
189   rtx old;
190 };
191 
192 static change_t *changes;
193 static int changes_allocated;
194 
195 static int num_changes = 0;
196 static int temporarily_undone_changes = 0;
197 
198 /* Validate a proposed change to OBJECT.  LOC is the location in the rtl
199    at which NEW_RTX will be placed.  If NEW_LEN is >= 0, XVECLEN (NEW_RTX, 0)
200    will also be changed to NEW_LEN, which is no greater than the current
201    XVECLEN.  If OBJECT is zero, no validation is done, the change is
202    simply made.
203 
204    Two types of objects are supported:  If OBJECT is a MEM, memory_address_p
205    will be called with the address and mode as parameters.  If OBJECT is
206    an INSN, CALL_INSN, or JUMP_INSN, the insn will be re-recognized with
207    the change in place.
208 
209    IN_GROUP is nonzero if this is part of a group of changes that must be
210    performed as a group.  In that case, the changes will be stored.  The
211    function `apply_change_group' will validate and apply the changes.
212 
213    If IN_GROUP is zero, this is a single change.  Try to recognize the insn
214    or validate the memory reference with the change applied.  If the result
215    is not valid for the machine, suppress the change and return zero.
216    Otherwise, perform the change and return 1.  */
217 
218 static bool
validate_change_1(rtx object,rtx * loc,rtx new_rtx,bool in_group,bool unshare,int new_len=-1)219 validate_change_1 (rtx object, rtx *loc, rtx new_rtx, bool in_group,
220                        bool unshare, int new_len = -1)
221 {
222   gcc_assert (temporarily_undone_changes == 0);
223   rtx old = *loc;
224 
225   /* Single-element parallels aren't valid and won't match anything.
226      Replace them with the single element.  */
227   if (new_len == 1 && GET_CODE (new_rtx) == PARALLEL)
228     {
229       new_rtx = XVECEXP (new_rtx, 0, 0);
230       new_len = -1;
231     }
232 
233   if ((old == new_rtx || rtx_equal_p (old, new_rtx))
234       && (new_len < 0 || XVECLEN (new_rtx, 0) == new_len))
235     return 1;
236 
237   gcc_assert ((in_group != 0 || num_changes == 0)
238                 && (new_len < 0 || new_rtx == *loc));
239 
240   *loc = new_rtx;
241 
242   /* Save the information describing this change.  */
243   if (num_changes >= changes_allocated)
244     {
245       if (changes_allocated == 0)
246           /* This value allows for repeated substitutions inside complex
247              indexed addresses, or changes in up to 5 insns.  */
248           changes_allocated = MAX_RECOG_OPERANDS * 5;
249       else
250           changes_allocated *= 2;
251 
252       changes = XRESIZEVEC (change_t, changes, changes_allocated);
253     }
254 
255   changes[num_changes].object = object;
256   changes[num_changes].loc = loc;
257   changes[num_changes].old = old;
258   changes[num_changes].old_len = (new_len >= 0 ? XVECLEN (new_rtx, 0) : -1);
259   changes[num_changes].unshare = unshare;
260 
261   if (new_len >= 0)
262     XVECLEN (new_rtx, 0) = new_len;
263 
264   if (object && !MEM_P (object))
265     {
266       /* Set INSN_CODE to force rerecognition of insn.  Save old code in
267            case invalid.  */
268       changes[num_changes].old_code = INSN_CODE (object);
269       INSN_CODE (object) = -1;
270     }
271 
272   num_changes++;
273 
274   /* If we are making a group of changes, return 1.  Otherwise, validate the
275      change group we made.  */
276 
277   if (in_group)
278     return 1;
279   else
280     return apply_change_group ();
281 }
282 
283 /* Wrapper for validate_change_1 without the UNSHARE argument defaulting
284    UNSHARE to false.  */
285 
286 bool
validate_change(rtx object,rtx * loc,rtx new_rtx,bool in_group)287 validate_change (rtx object, rtx *loc, rtx new_rtx, bool in_group)
288 {
289   return validate_change_1 (object, loc, new_rtx, in_group, false);
290 }
291 
292 /* Wrapper for validate_change_1 without the UNSHARE argument defaulting
293    UNSHARE to true.  */
294 
295 bool
validate_unshare_change(rtx object,rtx * loc,rtx new_rtx,bool in_group)296 validate_unshare_change (rtx object, rtx *loc, rtx new_rtx, bool in_group)
297 {
298   return validate_change_1 (object, loc, new_rtx, in_group, true);
299 }
300 
301 /* Change XVECLEN (*LOC, 0) to NEW_LEN.  OBJECT, IN_GROUP and the return
302    value are as for validate_change_1.  */
303 
304 bool
validate_change_xveclen(rtx object,rtx * loc,int new_len,bool in_group)305 validate_change_xveclen (rtx object, rtx *loc, int new_len, bool in_group)
306 {
307   return validate_change_1 (object, loc, *loc, in_group, false, new_len);
308 }
309 
310 /* Keep X canonicalized if some changes have made it non-canonical; only
311    modifies the operands of X, not (for example) its code.  Simplifications
312    are not the job of this routine.
313 
314    Return true if anything was changed.  */
315 bool
canonicalize_change_group(rtx_insn * insn,rtx x)316 canonicalize_change_group (rtx_insn *insn, rtx x)
317 {
318   if (COMMUTATIVE_P (x)
319       && swap_commutative_operands_p (XEXP (x, 0), XEXP (x, 1)))
320     {
321       /* Oops, the caller has made X no longer canonical.
322            Let's redo the changes in the correct order.  */
323       rtx tem = XEXP (x, 0);
324       validate_unshare_change (insn, &XEXP (x, 0), XEXP (x, 1), 1);
325       validate_unshare_change (insn, &XEXP (x, 1), tem, 1);
326       return true;
327     }
328   else
329     return false;
330 }
331 
332 /* Check if REG_INC argument in *data overlaps a stored REG.  */
333 
334 static void
check_invalid_inc_dec(rtx reg,const_rtx,void * data)335 check_invalid_inc_dec (rtx reg, const_rtx, void *data)
336 {
337   rtx *pinc = (rtx *) data;
338   if (*pinc == NULL_RTX || MEM_P (reg))
339     return;
340   if (reg_overlap_mentioned_p (reg, *pinc))
341     *pinc = NULL_RTX;
342 }
343 
344 /* This subroutine of apply_change_group verifies whether the changes to INSN
345    were valid; i.e. whether INSN can still be recognized.
346 
347    If IN_GROUP is true clobbers which have to be added in order to
348    match the instructions will be added to the current change group.
349    Otherwise the changes will take effect immediately.  */
350 
351 int
insn_invalid_p(rtx_insn * insn,bool in_group)352 insn_invalid_p (rtx_insn *insn, bool in_group)
353 {
354   rtx pat = PATTERN (insn);
355   int num_clobbers = 0;
356   /* If we are before reload and the pattern is a SET, see if we can add
357      clobbers.  */
358   int icode = recog (pat, insn,
359                          (GET_CODE (pat) == SET
360                           && ! reload_completed
361                       && ! reload_in_progress)
362                          ? &num_clobbers : 0);
363   int is_asm = icode < 0 && asm_noperands (PATTERN (insn)) >= 0;
364 
365 
366   /* If this is an asm and the operand aren't legal, then fail.  Likewise if
367      this is not an asm and the insn wasn't recognized.  */
368   if ((is_asm && ! check_asm_operands (PATTERN (insn)))
369       || (!is_asm && icode < 0))
370     return 1;
371 
372   /* If we have to add CLOBBERs, fail if we have to add ones that reference
373      hard registers since our callers can't know if they are live or not.
374      Otherwise, add them.  */
375   if (num_clobbers > 0)
376     {
377       rtx newpat;
378 
379       if (added_clobbers_hard_reg_p (icode))
380           return 1;
381 
382       newpat = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (num_clobbers + 1));
383       XVECEXP (newpat, 0, 0) = pat;
384       add_clobbers (newpat, icode);
385       if (in_group)
386           validate_change (insn, &PATTERN (insn), newpat, 1);
387       else
388           PATTERN (insn) = pat = newpat;
389     }
390 
391   /* After reload, verify that all constraints are satisfied.  */
392   if (reload_completed)
393     {
394       extract_insn (insn);
395 
396       if (! constrain_operands (1, get_preferred_alternatives (insn)))
397           return 1;
398     }
399 
400   /* Punt if REG_INC argument overlaps some stored REG.  */
401   for (rtx link = FIND_REG_INC_NOTE (insn, NULL_RTX);
402        link; link = XEXP (link, 1))
403     if (REG_NOTE_KIND (link) == REG_INC)
404       {
405           rtx reg = XEXP (link, 0);
406           note_stores (insn, check_invalid_inc_dec, &reg);
407           if (reg == NULL_RTX)
408             return 1;
409       }
410 
411   INSN_CODE (insn) = icode;
412   return 0;
413 }
414 
415 /* Return number of changes made and not validated yet.  */
416 int
num_changes_pending(void)417 num_changes_pending (void)
418 {
419   return num_changes;
420 }
421 
422 /* Tentatively apply the changes numbered NUM and up.
423    Return 1 if all changes are valid, zero otherwise.  */
424 
425 int
verify_changes(int num)426 verify_changes (int num)
427 {
428   int i;
429   rtx last_validated = NULL_RTX;
430 
431   /* The changes have been applied and all INSN_CODEs have been reset to force
432      rerecognition.
433 
434      The changes are valid if we aren't given an object, or if we are
435      given a MEM and it still is a valid address, or if this is in insn
436      and it is recognized.  In the latter case, if reload has completed,
437      we also require that the operands meet the constraints for
438      the insn.  */
439 
440   for (i = num; i < num_changes; i++)
441     {
442       rtx object = changes[i].object;
443 
444       /* If there is no object to test or if it is the same as the one we
445          already tested, ignore it.  */
446       if (object == 0 || object == last_validated)
447           continue;
448 
449       if (MEM_P (object))
450           {
451             if (! memory_address_addr_space_p (GET_MODE (object),
452                                                        XEXP (object, 0),
453                                                        MEM_ADDR_SPACE (object)))
454               break;
455           }
456       else if (/* changes[i].old might be zero, e.g. when putting a
457                  REG_FRAME_RELATED_EXPR into a previously empty list.  */
458                  changes[i].old
459                  && REG_P (changes[i].old)
460                  && asm_noperands (PATTERN (object)) > 0
461                  && register_asm_p (changes[i].old))
462           {
463             /* Don't allow changes of hard register operands to inline
464                assemblies if they have been defined as register asm ("x").  */
465             break;
466           }
467       else if (DEBUG_INSN_P (object))
468           continue;
469       else if (insn_invalid_p (as_a <rtx_insn *> (object), true))
470           {
471             rtx pat = PATTERN (object);
472 
473             /* Perhaps we couldn't recognize the insn because there were
474                extra CLOBBERs at the end.  If so, try to re-recognize
475                without the last CLOBBER (later iterations will cause each of
476                them to be eliminated, in turn).  But don't do this if we
477                have an ASM_OPERAND.  */
478             if (GET_CODE (pat) == PARALLEL
479                 && GET_CODE (XVECEXP (pat, 0, XVECLEN (pat, 0) - 1)) == CLOBBER
480                 && asm_noperands (PATTERN (object)) < 0)
481               {
482                 rtx newpat;
483 
484                 if (XVECLEN (pat, 0) == 2)
485                     newpat = XVECEXP (pat, 0, 0);
486                 else
487                     {
488                       int j;
489 
490                       newpat
491                         = gen_rtx_PARALLEL (VOIDmode,
492                                                   rtvec_alloc (XVECLEN (pat, 0) - 1));
493                       for (j = 0; j < XVECLEN (newpat, 0); j++)
494                         XVECEXP (newpat, 0, j) = XVECEXP (pat, 0, j);
495                     }
496 
497                 /* Add a new change to this group to replace the pattern
498                      with this new pattern.  Then consider this change
499                      as having succeeded.  The change we added will
500                      cause the entire call to fail if things remain invalid.
501 
502                      Note that this can lose if a later change than the one
503                      we are processing specified &XVECEXP (PATTERN (object), 0, X)
504                      but this shouldn't occur.  */
505 
506                 validate_change (object, &PATTERN (object), newpat, 1);
507                 continue;
508               }
509             else if (GET_CODE (pat) == USE || GET_CODE (pat) == CLOBBER
510                        || GET_CODE (pat) == VAR_LOCATION)
511               /* If this insn is a CLOBBER or USE, it is always valid, but is
512                  never recognized.  */
513               continue;
514             else
515               break;
516           }
517       last_validated = object;
518     }
519 
520   return (i == num_changes);
521 }
522 
523 /* A group of changes has previously been issued with validate_change
524    and verified with verify_changes.  Call df_insn_rescan for each of
525    the insn changed and clear num_changes.  */
526 
527 void
confirm_change_group(void)528 confirm_change_group (void)
529 {
530   int i;
531   rtx last_object = NULL;
532 
533   gcc_assert (temporarily_undone_changes == 0);
534   for (i = 0; i < num_changes; i++)
535     {
536       rtx object = changes[i].object;
537 
538       if (changes[i].unshare)
539           *changes[i].loc = copy_rtx (*changes[i].loc);
540 
541       /* Avoid unnecessary rescanning when multiple changes to same instruction
542          are made.  */
543       if (object)
544           {
545             if (object != last_object && last_object && INSN_P (last_object))
546               df_insn_rescan (as_a <rtx_insn *> (last_object));
547             last_object = object;
548           }
549     }
550 
551   if (last_object && INSN_P (last_object))
552     df_insn_rescan (as_a <rtx_insn *> (last_object));
553   num_changes = 0;
554 }
555 
556 /* Apply a group of changes previously issued with `validate_change'.
557    If all changes are valid, call confirm_change_group and return 1,
558    otherwise, call cancel_changes and return 0.  */
559 
560 int
apply_change_group(void)561 apply_change_group (void)
562 {
563   if (verify_changes (0))
564     {
565       confirm_change_group ();
566       return 1;
567     }
568   else
569     {
570       cancel_changes (0);
571       return 0;
572     }
573 }
574 
575 
576 /* Return the number of changes so far in the current group.  */
577 
578 int
num_validated_changes(void)579 num_validated_changes (void)
580 {
581   return num_changes;
582 }
583 
584 /* Retract the changes numbered NUM and up.  */
585 
586 void
cancel_changes(int num)587 cancel_changes (int num)
588 {
589   gcc_assert (temporarily_undone_changes == 0);
590   int i;
591 
592   /* Back out all the changes.  Do this in the opposite order in which
593      they were made.  */
594   for (i = num_changes - 1; i >= num; i--)
595     {
596       if (changes[i].old_len >= 0)
597           XVECLEN (*changes[i].loc, 0) = changes[i].old_len;
598       else
599           *changes[i].loc = changes[i].old;
600       if (changes[i].object && !MEM_P (changes[i].object))
601           INSN_CODE (changes[i].object) = changes[i].old_code;
602     }
603   num_changes = num;
604 }
605 
606 /* Swap the status of change NUM from being applied to not being applied,
607    or vice versa.  */
608 
609 static void
swap_change(int num)610 swap_change (int num)
611 {
612   if (changes[num].old_len >= 0)
613     std::swap (XVECLEN (*changes[num].loc, 0), changes[num].old_len);
614   else
615     std::swap (*changes[num].loc, changes[num].old);
616   if (changes[num].object && !MEM_P (changes[num].object))
617     std::swap (INSN_CODE (changes[num].object), changes[num].old_code);
618 }
619 
620 /* Temporarily undo all the changes numbered NUM and up, with a view
621    to reapplying them later.  The next call to the changes machinery
622    must be:
623 
624       redo_changes (NUM)
625 
626    otherwise things will end up in an invalid state.  */
627 
628 void
temporarily_undo_changes(int num)629 temporarily_undo_changes (int num)
630 {
631   gcc_assert (temporarily_undone_changes == 0 && num <= num_changes);
632   for (int i = num_changes - 1; i >= num; i--)
633     swap_change (i);
634   temporarily_undone_changes = num_changes - num;
635 }
636 
637 /* Redo the changes that were temporarily undone by:
638 
639       temporarily_undo_changes (NUM).  */
640 
641 void
redo_changes(int num)642 redo_changes (int num)
643 {
644   gcc_assert (temporarily_undone_changes == num_changes - num);
645   for (int i = num; i < num_changes; ++i)
646     swap_change (i);
647   temporarily_undone_changes = 0;
648 }
649 
650 /* Reduce conditional compilation elsewhere.  */
651 /* A subroutine of validate_replace_rtx_1 that tries to simplify the resulting
652    rtx.  */
653 
654 static void
simplify_while_replacing(rtx * loc,rtx to,rtx_insn * object,machine_mode op0_mode)655 simplify_while_replacing (rtx *loc, rtx to, rtx_insn *object,
656                           machine_mode op0_mode)
657 {
658   rtx x = *loc;
659   enum rtx_code code = GET_CODE (x);
660   rtx new_rtx = NULL_RTX;
661   scalar_int_mode is_mode;
662 
663   if (SWAPPABLE_OPERANDS_P (x)
664       && swap_commutative_operands_p (XEXP (x, 0), XEXP (x, 1)))
665     {
666       validate_unshare_change (object, loc,
667                                      gen_rtx_fmt_ee (COMMUTATIVE_ARITH_P (x) ? code
668                                                          : swap_condition (code),
669                                                          GET_MODE (x), XEXP (x, 1),
670                                                          XEXP (x, 0)), 1);
671       x = *loc;
672       code = GET_CODE (x);
673     }
674 
675   /* Canonicalize arithmetics with all constant operands.  */
676   switch (GET_RTX_CLASS (code))
677     {
678     case RTX_UNARY:
679       if (CONSTANT_P (XEXP (x, 0)))
680           new_rtx = simplify_unary_operation (code, GET_MODE (x), XEXP (x, 0),
681                                                       op0_mode);
682       break;
683     case RTX_COMM_ARITH:
684     case RTX_BIN_ARITH:
685       if (CONSTANT_P (XEXP (x, 0)) && CONSTANT_P (XEXP (x, 1)))
686           new_rtx = simplify_binary_operation (code, GET_MODE (x), XEXP (x, 0),
687                                                        XEXP (x, 1));
688       break;
689     case RTX_COMPARE:
690     case RTX_COMM_COMPARE:
691       if (CONSTANT_P (XEXP (x, 0)) && CONSTANT_P (XEXP (x, 1)))
692           new_rtx = simplify_relational_operation (code, GET_MODE (x), op0_mode,
693                                                              XEXP (x, 0), XEXP (x, 1));
694       break;
695     default:
696       break;
697     }
698   if (new_rtx)
699     {
700       validate_change (object, loc, new_rtx, 1);
701       return;
702     }
703 
704   switch (code)
705     {
706     case PLUS:
707       /* If we have a PLUS whose second operand is now a CONST_INT, use
708          simplify_gen_binary to try to simplify it.
709          ??? We may want later to remove this, once simplification is
710          separated from this function.  */
711       if (CONST_INT_P (XEXP (x, 1)) && XEXP (x, 1) == to)
712           validate_change (object, loc,
713                                simplify_gen_binary
714                                (PLUS, GET_MODE (x), XEXP (x, 0), XEXP (x, 1)), 1);
715       break;
716     case MINUS:
717       if (CONST_SCALAR_INT_P (XEXP (x, 1)))
718           validate_change (object, loc,
719                                simplify_gen_binary
720                                (PLUS, GET_MODE (x), XEXP (x, 0),
721                                 simplify_gen_unary (NEG,
722                                                         GET_MODE (x), XEXP (x, 1),
723                                                         GET_MODE (x))), 1);
724       break;
725     case ZERO_EXTEND:
726     case SIGN_EXTEND:
727       if (GET_MODE (XEXP (x, 0)) == VOIDmode)
728           {
729             new_rtx = simplify_gen_unary (code, GET_MODE (x), XEXP (x, 0),
730                                             op0_mode);
731             /* If any of the above failed, substitute in something that
732                we know won't be recognized.  */
733             if (!new_rtx)
734               new_rtx = gen_rtx_CLOBBER (GET_MODE (x), const0_rtx);
735             validate_change (object, loc, new_rtx, 1);
736           }
737       break;
738     case SUBREG:
739       /* All subregs possible to simplify should be simplified.  */
740       new_rtx = simplify_subreg (GET_MODE (x), SUBREG_REG (x), op0_mode,
741                                    SUBREG_BYTE (x));
742 
743       /* Subregs of VOIDmode operands are incorrect.  */
744       if (!new_rtx && GET_MODE (SUBREG_REG (x)) == VOIDmode)
745           new_rtx = gen_rtx_CLOBBER (GET_MODE (x), const0_rtx);
746       if (new_rtx)
747           validate_change (object, loc, new_rtx, 1);
748       break;
749     case ZERO_EXTRACT:
750     case SIGN_EXTRACT:
751       /* If we are replacing a register with memory, try to change the memory
752          to be the mode required for memory in extract operations (this isn't
753          likely to be an insertion operation; if it was, nothing bad will
754          happen, we might just fail in some cases).  */
755 
756       if (MEM_P (XEXP (x, 0))
757             && is_a <scalar_int_mode> (GET_MODE (XEXP (x, 0)), &is_mode)
758             && CONST_INT_P (XEXP (x, 1))
759             && CONST_INT_P (XEXP (x, 2))
760             && !mode_dependent_address_p (XEXP (XEXP (x, 0), 0),
761                                                   MEM_ADDR_SPACE (XEXP (x, 0)))
762             && !MEM_VOLATILE_P (XEXP (x, 0)))
763           {
764             int pos = INTVAL (XEXP (x, 2));
765             machine_mode new_mode = is_mode;
766             if (GET_CODE (x) == ZERO_EXTRACT && targetm.have_extzv ())
767               new_mode = insn_data[targetm.code_for_extzv].operand[1].mode;
768             else if (GET_CODE (x) == SIGN_EXTRACT && targetm.have_extv ())
769               new_mode = insn_data[targetm.code_for_extv].operand[1].mode;
770             scalar_int_mode wanted_mode = (new_mode == VOIDmode
771                                                    ? word_mode
772                                                    : as_a <scalar_int_mode> (new_mode));
773 
774             /* If we have a narrower mode, we can do something.  */
775             if (GET_MODE_SIZE (wanted_mode) < GET_MODE_SIZE (is_mode))
776               {
777                 int offset = pos / BITS_PER_UNIT;
778                 rtx newmem;
779 
780                 /* If the bytes and bits are counted differently, we
781                    must adjust the offset.  */
782                 if (BYTES_BIG_ENDIAN != BITS_BIG_ENDIAN)
783                     offset =
784                       (GET_MODE_SIZE (is_mode) - GET_MODE_SIZE (wanted_mode) -
785                        offset);
786 
787                 gcc_assert (GET_MODE_PRECISION (wanted_mode)
788                                 == GET_MODE_BITSIZE (wanted_mode));
789                 pos %= GET_MODE_BITSIZE (wanted_mode);
790 
791                 newmem = adjust_address_nv (XEXP (x, 0), wanted_mode, offset);
792 
793                 validate_change (object, &XEXP (x, 2), GEN_INT (pos), 1);
794                 validate_change (object, &XEXP (x, 0), newmem, 1);
795               }
796           }
797 
798       break;
799 
800     default:
801       break;
802     }
803 }
804 
805 /* Replace every occurrence of FROM in X with TO.  Mark each change with
806    validate_change passing OBJECT.  */
807 
808 static void
validate_replace_rtx_1(rtx * loc,rtx from,rtx to,rtx_insn * object,bool simplify)809 validate_replace_rtx_1 (rtx *loc, rtx from, rtx to, rtx_insn *object,
810                         bool simplify)
811 {
812   int i, j;
813   const char *fmt;
814   rtx x = *loc;
815   enum rtx_code code;
816   machine_mode op0_mode = VOIDmode;
817   int prev_changes = num_changes;
818 
819   if (!x)
820     return;
821 
822   code = GET_CODE (x);
823   fmt = GET_RTX_FORMAT (code);
824   if (fmt[0] == 'e')
825     op0_mode = GET_MODE (XEXP (x, 0));
826 
827   /* X matches FROM if it is the same rtx or they are both referring to the
828      same register in the same mode.  Avoid calling rtx_equal_p unless the
829      operands look similar.  */
830 
831   if (x == from
832       || (REG_P (x) && REG_P (from)
833             && GET_MODE (x) == GET_MODE (from)
834             && REGNO (x) == REGNO (from))
835       || (GET_CODE (x) == GET_CODE (from) && GET_MODE (x) == GET_MODE (from)
836             && rtx_equal_p (x, from)))
837     {
838       validate_unshare_change (object, loc, to, 1);
839       return;
840     }
841 
842   /* Call ourself recursively to perform the replacements.
843      We must not replace inside already replaced expression, otherwise we
844      get infinite recursion for replacements like (reg X)->(subreg (reg X))
845      so we must special case shared ASM_OPERANDS.  */
846 
847   if (GET_CODE (x) == PARALLEL)
848     {
849       for (j = XVECLEN (x, 0) - 1; j >= 0; j--)
850           {
851             if (j && GET_CODE (XVECEXP (x, 0, j)) == SET
852                 && GET_CODE (SET_SRC (XVECEXP (x, 0, j))) == ASM_OPERANDS)
853               {
854                 /* Verify that operands are really shared.  */
855                 gcc_assert (ASM_OPERANDS_INPUT_VEC (SET_SRC (XVECEXP (x, 0, 0)))
856                                 == ASM_OPERANDS_INPUT_VEC (SET_SRC (XVECEXP
857                                                                             (x, 0, j))));
858                 validate_replace_rtx_1 (&SET_DEST (XVECEXP (x, 0, j)),
859                                               from, to, object, simplify);
860               }
861             else
862               validate_replace_rtx_1 (&XVECEXP (x, 0, j), from, to, object,
863                                     simplify);
864           }
865     }
866   else
867     for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
868       {
869           if (fmt[i] == 'e')
870             validate_replace_rtx_1 (&XEXP (x, i), from, to, object, simplify);
871           else if (fmt[i] == 'E')
872             for (j = XVECLEN (x, i) - 1; j >= 0; j--)
873               validate_replace_rtx_1 (&XVECEXP (x, i, j), from, to, object,
874                                     simplify);
875       }
876 
877   /* If we didn't substitute, there is nothing more to do.  */
878   if (num_changes == prev_changes)
879     return;
880 
881   /* ??? The regmove is no more, so is this aberration still necessary?  */
882   /* Allow substituted expression to have different mode.  This is used by
883      regmove to change mode of pseudo register.  */
884   if (fmt[0] == 'e' && GET_MODE (XEXP (x, 0)) != VOIDmode)
885     op0_mode = GET_MODE (XEXP (x, 0));
886 
887   /* Do changes needed to keep rtx consistent.  Don't do any other
888      simplifications, as it is not our job.  */
889   if (simplify)
890     simplify_while_replacing (loc, to, object, op0_mode);
891 }
892 
893 /* Try replacing every occurrence of FROM in subexpression LOC of INSN
894    with TO.  After all changes have been made, validate by seeing
895    if INSN is still valid.  */
896 
897 int
validate_replace_rtx_subexp(rtx from,rtx to,rtx_insn * insn,rtx * loc)898 validate_replace_rtx_subexp (rtx from, rtx to, rtx_insn *insn, rtx *loc)
899 {
900   validate_replace_rtx_1 (loc, from, to, insn, true);
901   return apply_change_group ();
902 }
903 
904 /* Try replacing every occurrence of FROM in INSN with TO.  After all
905    changes have been made, validate by seeing if INSN is still valid.  */
906 
907 int
validate_replace_rtx(rtx from,rtx to,rtx_insn * insn)908 validate_replace_rtx (rtx from, rtx to, rtx_insn *insn)
909 {
910   validate_replace_rtx_1 (&PATTERN (insn), from, to, insn, true);
911   return apply_change_group ();
912 }
913 
914 /* Try replacing every occurrence of FROM in WHERE with TO.  Assume that WHERE
915    is a part of INSN.  After all changes have been made, validate by seeing if
916    INSN is still valid.
917    validate_replace_rtx (from, to, insn) is equivalent to
918    validate_replace_rtx_part (from, to, &PATTERN (insn), insn).  */
919 
920 int
validate_replace_rtx_part(rtx from,rtx to,rtx * where,rtx_insn * insn)921 validate_replace_rtx_part (rtx from, rtx to, rtx *where, rtx_insn *insn)
922 {
923   validate_replace_rtx_1 (where, from, to, insn, true);
924   return apply_change_group ();
925 }
926 
927 /* Same as above, but do not simplify rtx afterwards.  */
928 int
validate_replace_rtx_part_nosimplify(rtx from,rtx to,rtx * where,rtx_insn * insn)929 validate_replace_rtx_part_nosimplify (rtx from, rtx to, rtx *where,
930                                               rtx_insn *insn)
931 {
932   validate_replace_rtx_1 (where, from, to, insn, false);
933   return apply_change_group ();
934 
935 }
936 
937 /* Try replacing every occurrence of FROM in INSN with TO.  This also
938    will replace in REG_EQUAL and REG_EQUIV notes.  */
939 
940 void
validate_replace_rtx_group(rtx from,rtx to,rtx_insn * insn)941 validate_replace_rtx_group (rtx from, rtx to, rtx_insn *insn)
942 {
943   rtx note;
944   validate_replace_rtx_1 (&PATTERN (insn), from, to, insn, true);
945   for (note = REG_NOTES (insn); note; note = XEXP (note, 1))
946     if (REG_NOTE_KIND (note) == REG_EQUAL
947           || REG_NOTE_KIND (note) == REG_EQUIV)
948       validate_replace_rtx_1 (&XEXP (note, 0), from, to, insn, true);
949 }
950 
951 /* Function called by note_uses to replace used subexpressions.  */
952 struct validate_replace_src_data
953 {
954   rtx from;                             /* Old RTX */
955   rtx to;                     /* New RTX */
956   rtx_insn *insn;                       /* Insn in which substitution is occurring.  */
957 };
958 
959 static void
validate_replace_src_1(rtx * x,void * data)960 validate_replace_src_1 (rtx *x, void *data)
961 {
962   struct validate_replace_src_data *d
963     = (struct validate_replace_src_data *) data;
964 
965   validate_replace_rtx_1 (x, d->from, d->to, d->insn, true);
966 }
967 
968 /* Try replacing every occurrence of FROM in INSN with TO, avoiding
969    SET_DESTs.  */
970 
971 void
validate_replace_src_group(rtx from,rtx to,rtx_insn * insn)972 validate_replace_src_group (rtx from, rtx to, rtx_insn *insn)
973 {
974   struct validate_replace_src_data d;
975 
976   d.from = from;
977   d.to = to;
978   d.insn = insn;
979   note_uses (&PATTERN (insn), validate_replace_src_1, &d);
980 }
981 
982 /* Try simplify INSN.
983    Invoke simplify_rtx () on every SET_SRC and SET_DEST inside the INSN's
984    pattern and return true if something was simplified.  */
985 
986 bool
validate_simplify_insn(rtx_insn * insn)987 validate_simplify_insn (rtx_insn *insn)
988 {
989   int i;
990   rtx pat = NULL;
991   rtx newpat = NULL;
992 
993   pat = PATTERN (insn);
994 
995   if (GET_CODE (pat) == SET)
996     {
997       newpat = simplify_rtx (SET_SRC (pat));
998       if (newpat && !rtx_equal_p (SET_SRC (pat), newpat))
999           validate_change (insn, &SET_SRC (pat), newpat, 1);
1000       newpat = simplify_rtx (SET_DEST (pat));
1001       if (newpat && !rtx_equal_p (SET_DEST (pat), newpat))
1002           validate_change (insn, &SET_DEST (pat), newpat, 1);
1003     }
1004   else if (GET_CODE (pat) == PARALLEL)
1005     for (i = 0; i < XVECLEN (pat, 0); i++)
1006       {
1007           rtx s = XVECEXP (pat, 0, i);
1008 
1009           if (GET_CODE (XVECEXP (pat, 0, i)) == SET)
1010             {
1011               newpat = simplify_rtx (SET_SRC (s));
1012               if (newpat && !rtx_equal_p (SET_SRC (s), newpat))
1013                 validate_change (insn, &SET_SRC (s), newpat, 1);
1014               newpat = simplify_rtx (SET_DEST (s));
1015               if (newpat && !rtx_equal_p (SET_DEST (s), newpat))
1016                 validate_change (insn, &SET_DEST (s), newpat, 1);
1017             }
1018       }
1019   return ((num_changes_pending () > 0) && (apply_change_group () > 0));
1020 }
1021 
1022 /* Try to process the address of memory expression MEM.  Return true on
1023    success; leave the caller to clean up on failure.  */
1024 
1025 bool
apply_to_mem_1(rtx mem)1026 insn_propagation::apply_to_mem_1 (rtx mem)
1027 {
1028   auto old_num_changes = num_validated_changes ();
1029   mem_depth += 1;
1030   bool res = apply_to_rvalue_1 (&XEXP (mem, 0));
1031   mem_depth -= 1;
1032   if (!res)
1033     return false;
1034 
1035   if (old_num_changes != num_validated_changes ()
1036       && should_check_mems
1037       && !check_mem (old_num_changes, mem))
1038     return false;
1039 
1040   return true;
1041 }
1042 
1043 /* Try to process the rvalue expression at *LOC.  Return true on success;
1044    leave the caller to clean up on failure.  */
1045 
1046 bool
apply_to_rvalue_1(rtx * loc)1047 insn_propagation::apply_to_rvalue_1 (rtx *loc)
1048 {
1049   rtx x = *loc;
1050   enum rtx_code code = GET_CODE (x);
1051   machine_mode mode = GET_MODE (x);
1052 
1053   auto old_num_changes = num_validated_changes ();
1054   if (from && GET_CODE (x) == GET_CODE (from) && rtx_equal_p (x, from))
1055     {
1056       /* Don't replace register asms in asm statements; we mustn't
1057            change the user's register allocation.  */
1058       if (REG_P (x)
1059             && HARD_REGISTER_P (x)
1060             && register_asm_p (x)
1061             && asm_noperands (PATTERN (insn)) > 0)
1062           return false;
1063 
1064       if (should_unshare)
1065           validate_unshare_change (insn, loc, to, 1);
1066       else
1067           validate_change (insn, loc, to, 1);
1068       if (mem_depth && !REG_P (to) && !CONSTANT_P (to))
1069           {
1070             /* We're substituting into an address, but TO will have the
1071                form expected outside an address.  Canonicalize it if
1072                necessary.  */
1073             insn_propagation subprop (insn);
1074             subprop.mem_depth += 1;
1075             if (!subprop.apply_to_rvalue (loc))
1076               gcc_unreachable ();
1077             if (should_unshare
1078                 && num_validated_changes () != old_num_changes + 1)
1079               {
1080                 /* TO is owned by someone else, so create a copy and
1081                      return TO to its original form.  */
1082                 rtx to = copy_rtx (*loc);
1083                 cancel_changes (old_num_changes);
1084                 validate_change (insn, loc, to, 1);
1085               }
1086           }
1087       num_replacements += 1;
1088       should_unshare = true;
1089       result_flags |= UNSIMPLIFIED;
1090       return true;
1091     }
1092 
1093   /* Recursively apply the substitution and see if we can simplify
1094      the result.  This specifically shouldn't use simplify_gen_* for
1095      speculative simplifications, since we want to avoid generating new
1096      expressions where possible.  */
1097   auto old_result_flags = result_flags;
1098   rtx newx = NULL_RTX;
1099   bool recurse_p = false;
1100   switch (GET_RTX_CLASS (code))
1101     {
1102     case RTX_UNARY:
1103       {
1104           machine_mode op0_mode = GET_MODE (XEXP (x, 0));
1105           if (!apply_to_rvalue_1 (&XEXP (x, 0)))
1106             return false;
1107           if (from && old_num_changes == num_validated_changes ())
1108             return true;
1109 
1110           newx = simplify_unary_operation (code, mode, XEXP (x, 0), op0_mode);
1111           break;
1112       }
1113 
1114     case RTX_BIN_ARITH:
1115     case RTX_COMM_ARITH:
1116       {
1117           if (!apply_to_rvalue_1 (&XEXP (x, 0))
1118               || !apply_to_rvalue_1 (&XEXP (x, 1)))
1119             return false;
1120           if (from && old_num_changes == num_validated_changes ())
1121             return true;
1122 
1123           if (GET_RTX_CLASS (code) == RTX_COMM_ARITH
1124               && swap_commutative_operands_p (XEXP (x, 0), XEXP (x, 1)))
1125             newx = simplify_gen_binary (code, mode, XEXP (x, 1), XEXP (x, 0));
1126           else
1127             newx = simplify_binary_operation (code, mode,
1128                                                       XEXP (x, 0), XEXP (x, 1));
1129           break;
1130       }
1131 
1132     case RTX_COMPARE:
1133     case RTX_COMM_COMPARE:
1134       {
1135           machine_mode op_mode = (GET_MODE (XEXP (x, 0)) != VOIDmode
1136                                         ? GET_MODE (XEXP (x, 0))
1137                                         : GET_MODE (XEXP (x, 1)));
1138           if (!apply_to_rvalue_1 (&XEXP (x, 0))
1139               || !apply_to_rvalue_1 (&XEXP (x, 1)))
1140             return false;
1141           if (from && old_num_changes == num_validated_changes ())
1142             return true;
1143 
1144           newx = simplify_relational_operation (code, mode, op_mode,
1145                                                         XEXP (x, 0), XEXP (x, 1));
1146           break;
1147       }
1148 
1149     case RTX_TERNARY:
1150     case RTX_BITFIELD_OPS:
1151       {
1152           machine_mode op0_mode = GET_MODE (XEXP (x, 0));
1153           if (!apply_to_rvalue_1 (&XEXP (x, 0))
1154               || !apply_to_rvalue_1 (&XEXP (x, 1))
1155               || !apply_to_rvalue_1 (&XEXP (x, 2)))
1156             return false;
1157           if (from && old_num_changes == num_validated_changes ())
1158             return true;
1159 
1160           newx = simplify_ternary_operation (code, mode, op0_mode,
1161                                                      XEXP (x, 0), XEXP (x, 1),
1162                                                      XEXP (x, 2));
1163           break;
1164       }
1165 
1166     case RTX_EXTRA:
1167       if (code == SUBREG)
1168           {
1169             machine_mode inner_mode = GET_MODE (SUBREG_REG (x));
1170             if (!apply_to_rvalue_1 (&SUBREG_REG (x)))
1171               return false;
1172             if (from && old_num_changes == num_validated_changes ())
1173               return true;
1174 
1175             rtx inner = SUBREG_REG (x);
1176             newx = simplify_subreg (mode, inner, inner_mode, SUBREG_BYTE (x));
1177             /* Reject the same cases that simplify_gen_subreg would.  */
1178             if (!newx
1179                 && (GET_CODE (inner) == SUBREG
1180                       || GET_CODE (inner) == CONCAT
1181                       || GET_MODE (inner) == VOIDmode
1182                       || !validate_subreg (mode, inner_mode,
1183                                                inner, SUBREG_BYTE (x))))
1184               {
1185                 failure_reason = "would create an invalid subreg";
1186                 return false;
1187               }
1188             break;
1189           }
1190       else
1191           recurse_p = true;
1192       break;
1193 
1194     case RTX_OBJ:
1195       if (code == LO_SUM)
1196           {
1197             if (!apply_to_rvalue_1 (&XEXP (x, 0))
1198                 || !apply_to_rvalue_1 (&XEXP (x, 1)))
1199               return false;
1200             if (from && old_num_changes == num_validated_changes ())
1201               return true;
1202 
1203             /* (lo_sum (high x) y) -> y where x and y have the same base.  */
1204             rtx op0 = XEXP (x, 0);
1205             rtx op1 = XEXP (x, 1);
1206             if (GET_CODE (op0) == HIGH)
1207               {
1208                 rtx base0, base1, offset0, offset1;
1209                 split_const (XEXP (op0, 0), &base0, &offset0);
1210                 split_const (op1, &base1, &offset1);
1211                 if (rtx_equal_p (base0, base1))
1212                     newx = op1;
1213               }
1214           }
1215       else if (code == REG)
1216           {
1217             if (from && REG_P (from) && reg_overlap_mentioned_p (x, from))
1218               {
1219                 failure_reason = "inexact register overlap";
1220                 return false;
1221               }
1222           }
1223       else if (code == MEM)
1224           return apply_to_mem_1 (x);
1225       else
1226           recurse_p = true;
1227       break;
1228 
1229     case RTX_CONST_OBJ:
1230       break;
1231 
1232     case RTX_AUTOINC:
1233       if (from && reg_overlap_mentioned_p (XEXP (x, 0), from))
1234           {
1235             failure_reason = "is subject to autoinc";
1236             return false;
1237           }
1238       recurse_p = true;
1239       break;
1240 
1241     case RTX_MATCH:
1242     case RTX_INSN:
1243       gcc_unreachable ();
1244     }
1245 
1246   if (recurse_p)
1247     {
1248       const char *fmt = GET_RTX_FORMAT (code);
1249       for (int i = 0; fmt[i]; i++)
1250           switch (fmt[i])
1251             {
1252             case 'E':
1253               for (int j = 0; j < XVECLEN (x, i); j++)
1254                 if (!apply_to_rvalue_1 (&XVECEXP (x, i, j)))
1255                     return false;
1256               break;
1257 
1258             case 'e':
1259               if (XEXP (x, i) && !apply_to_rvalue_1 (&XEXP (x, i)))
1260                 return false;
1261               break;
1262             }
1263     }
1264   else if (newx && !rtx_equal_p (x, newx))
1265     {
1266       /* All substitutions made by OLD_NUM_CHANGES onwards have been
1267            simplified.  */
1268       result_flags = ((result_flags & ~UNSIMPLIFIED)
1269                           | (old_result_flags & UNSIMPLIFIED));
1270 
1271       if (should_note_simplifications)
1272           note_simplification (old_num_changes, old_result_flags, x, newx);
1273 
1274       /* There's no longer any point unsharing the substitutions made
1275            for subexpressions, since we'll just copy this one instead.  */
1276       bool unshare = false;
1277       for (int i = old_num_changes; i < num_changes; ++i)
1278           {
1279             unshare |= changes[i].unshare;
1280             changes[i].unshare = false;
1281           }
1282       if (unshare)
1283           validate_unshare_change (insn, loc, newx, 1);
1284       else
1285           validate_change (insn, loc, newx, 1);
1286     }
1287 
1288   return true;
1289 }
1290 
1291 /* Try to process the lvalue expression at *LOC.  Return true on success;
1292    leave the caller to clean up on failure.  */
1293 
1294 bool
apply_to_lvalue_1(rtx dest)1295 insn_propagation::apply_to_lvalue_1 (rtx dest)
1296 {
1297   rtx old_dest = dest;
1298   while (GET_CODE (dest) == SUBREG
1299            || GET_CODE (dest) == ZERO_EXTRACT
1300            || GET_CODE (dest) == STRICT_LOW_PART)
1301     {
1302       if (GET_CODE (dest) == ZERO_EXTRACT
1303             && (!apply_to_rvalue_1 (&XEXP (dest, 1))
1304                 || !apply_to_rvalue_1 (&XEXP (dest, 2))))
1305           return false;
1306       dest = XEXP (dest, 0);
1307     }
1308 
1309   if (MEM_P (dest))
1310     return apply_to_mem_1 (dest);
1311 
1312   /* Check whether the substitution is safe in the presence of this lvalue.  */
1313   if (!from
1314       || dest == old_dest
1315       || !REG_P (dest)
1316       || !reg_overlap_mentioned_p (dest, from))
1317     return true;
1318 
1319   if (SUBREG_P (old_dest)
1320       && SUBREG_REG (old_dest) == dest
1321       && !read_modify_subreg_p (old_dest))
1322     return true;
1323 
1324   failure_reason = "is part of a read-write destination";
1325   return false;
1326 }
1327 
1328 /* Try to process the instruction pattern at *LOC.  Return true on success;
1329    leave the caller to clean up on failure.  */
1330 
1331 bool
apply_to_pattern_1(rtx * loc)1332 insn_propagation::apply_to_pattern_1 (rtx *loc)
1333 {
1334   rtx body = *loc;
1335   switch (GET_CODE (body))
1336     {
1337     case COND_EXEC:
1338       return (apply_to_rvalue_1 (&COND_EXEC_TEST (body))
1339                 && apply_to_pattern_1 (&COND_EXEC_CODE (body)));
1340 
1341     case PARALLEL:
1342       {
1343           int last = XVECLEN (body, 0) - 1;
1344           for (int i = 0; i < last; ++i)
1345             if (!apply_to_pattern_1 (&XVECEXP (body, 0, i)))
1346               return false;
1347           return apply_to_pattern_1 (&XVECEXP (body, 0, last));
1348       }
1349 
1350     case ASM_OPERANDS:
1351       for (int i = 0, len = ASM_OPERANDS_INPUT_LENGTH (body); i < len; ++i)
1352           if (!apply_to_rvalue_1 (&ASM_OPERANDS_INPUT (body, i)))
1353             return false;
1354       return true;
1355 
1356     case CLOBBER:
1357       return apply_to_lvalue_1 (XEXP (body, 0));
1358 
1359     case SET:
1360       return (apply_to_lvalue_1 (SET_DEST (body))
1361                 && apply_to_rvalue_1 (&SET_SRC (body)));
1362 
1363     default:
1364       /* All the other possibilities never store and can use a normal
1365            rtx walk.  This includes:
1366 
1367            - USE
1368            - TRAP_IF
1369            - PREFETCH
1370            - UNSPEC
1371            - UNSPEC_VOLATILE.  */
1372       return apply_to_rvalue_1 (loc);
1373     }
1374 }
1375 
1376 /* Apply this insn_propagation object's simplification or substitution
1377    to the instruction pattern at LOC.  */
1378 
1379 bool
apply_to_pattern(rtx * loc)1380 insn_propagation::apply_to_pattern (rtx *loc)
1381 {
1382   unsigned int num_changes = num_validated_changes ();
1383   bool res = apply_to_pattern_1 (loc);
1384   if (!res)
1385     cancel_changes (num_changes);
1386   return res;
1387 }
1388 
1389 /* Apply this insn_propagation object's simplification or substitution
1390    to the rvalue expression at LOC.  */
1391 
1392 bool
apply_to_rvalue(rtx * loc)1393 insn_propagation::apply_to_rvalue (rtx *loc)
1394 {
1395   unsigned int num_changes = num_validated_changes ();
1396   bool res = apply_to_rvalue_1 (loc);
1397   if (!res)
1398     cancel_changes (num_changes);
1399   return res;
1400 }
1401 
1402 /* Check whether INSN matches a specific alternative of an .md pattern.  */
1403 
1404 bool
valid_insn_p(rtx_insn * insn)1405 valid_insn_p (rtx_insn *insn)
1406 {
1407   recog_memoized (insn);
1408   if (INSN_CODE (insn) < 0)
1409     return false;
1410   extract_insn (insn);
1411   /* We don't know whether the insn will be in code that is optimized
1412      for size or speed, so consider all enabled alternatives.  */
1413   if (!constrain_operands (1, get_enabled_alternatives (insn)))
1414     return false;
1415   return true;
1416 }
1417 
1418 /* Return true if OP is a valid general operand for machine mode MODE.
1419    This is either a register reference, a memory reference,
1420    or a constant.  In the case of a memory reference, the address
1421    is checked for general validity for the target machine.
1422 
1423    Register and memory references must have mode MODE in order to be valid,
1424    but some constants have no machine mode and are valid for any mode.
1425 
1426    If MODE is VOIDmode, OP is checked for validity for whatever mode
1427    it has.
1428 
1429    The main use of this function is as a predicate in match_operand
1430    expressions in the machine description.  */
1431 
1432 bool
general_operand(rtx op,machine_mode mode)1433 general_operand (rtx op, machine_mode mode)
1434 {
1435   enum rtx_code code = GET_CODE (op);
1436 
1437   if (mode == VOIDmode)
1438     mode = GET_MODE (op);
1439 
1440   /* Don't accept CONST_INT or anything similar
1441      if the caller wants something floating.  */
1442   if (GET_MODE (op) == VOIDmode && mode != VOIDmode
1443       && GET_MODE_CLASS (mode) != MODE_INT
1444       && GET_MODE_CLASS (mode) != MODE_PARTIAL_INT)
1445     return false;
1446 
1447   if (CONST_INT_P (op)
1448       && mode != VOIDmode
1449       && trunc_int_for_mode (INTVAL (op), mode) != INTVAL (op))
1450     return false;
1451 
1452   if (CONSTANT_P (op))
1453     return ((GET_MODE (op) == VOIDmode || GET_MODE (op) == mode
1454                || mode == VOIDmode)
1455               && (! flag_pic || LEGITIMATE_PIC_OPERAND_P (op))
1456               && targetm.legitimate_constant_p (mode == VOIDmode
1457                                                         ? GET_MODE (op)
1458                                                         : mode, op));
1459 
1460   /* Except for certain constants with VOIDmode, already checked for,
1461      OP's mode must match MODE if MODE specifies a mode.  */
1462 
1463   if (GET_MODE (op) != mode)
1464     return false;
1465 
1466   if (code == SUBREG)
1467     {
1468       rtx sub = SUBREG_REG (op);
1469 
1470 #ifdef INSN_SCHEDULING
1471       /* On machines that have insn scheduling, we want all memory
1472            reference to be explicit, so outlaw paradoxical SUBREGs.
1473            However, we must allow them after reload so that they can
1474            get cleaned up by cleanup_subreg_operands.  */
1475       if (!reload_completed && MEM_P (sub)
1476             && paradoxical_subreg_p (op))
1477           return false;
1478 #endif
1479       /* Avoid memories with nonzero SUBREG_BYTE, as offsetting the memory
1480          may result in incorrect reference.  We should simplify all valid
1481          subregs of MEM anyway.  But allow this after reload because we
1482            might be called from cleanup_subreg_operands.
1483 
1484            ??? This is a kludge.  */
1485       if (!reload_completed
1486             && maybe_ne (SUBREG_BYTE (op), 0)
1487             && MEM_P (sub)
1488 #ifdef NB_FIX_VAX_BACKEND
1489             && (maybe_gt (SUBREG_BYTE (op), GET_MODE_SIZE (GET_MODE (sub)))
1490                 || !multiple_p (SUBREG_BYTE (op), GET_MODE_SIZE (mode))
1491                 )
1492 #endif /* NB_FIX_VAX_BACKEND */
1493             )
1494           return false;
1495 
1496       if (REG_P (sub)
1497             && REGNO (sub) < FIRST_PSEUDO_REGISTER
1498             && !REG_CAN_CHANGE_MODE_P (REGNO (sub), GET_MODE (sub), mode)
1499             && GET_MODE_CLASS (GET_MODE (sub)) != MODE_COMPLEX_INT
1500             && GET_MODE_CLASS (GET_MODE (sub)) != MODE_COMPLEX_FLOAT
1501             /* LRA can generate some invalid SUBREGS just for matched
1502                operand reload presentation.  LRA needs to treat them as
1503                valid.  */
1504             && ! LRA_SUBREG_P (op))
1505           return false;
1506 
1507       /* FLOAT_MODE subregs can't be paradoxical.  Combine will occasionally
1508            create such rtl, and we must reject it.  */
1509       if (SCALAR_FLOAT_MODE_P (GET_MODE (op))
1510             /* LRA can use subreg to store a floating point value in an
1511                integer mode.  Although the floating point and the
1512                integer modes need the same number of hard registers, the
1513                size of floating point mode can be less than the integer
1514                mode.  */
1515             && ! lra_in_progress
1516             && paradoxical_subreg_p (op))
1517           return false;
1518 
1519       op = sub;
1520       code = GET_CODE (op);
1521     }
1522 
1523   if (code == REG)
1524     return (REGNO (op) >= FIRST_PSEUDO_REGISTER
1525               || in_hard_reg_set_p (operand_reg_set, GET_MODE (op), REGNO (op)));
1526 
1527   if (code == MEM)
1528     {
1529       rtx y = XEXP (op, 0);
1530 
1531       if (! volatile_ok && MEM_VOLATILE_P (op))
1532           return false;
1533 
1534       /* Use the mem's mode, since it will be reloaded thus.  LRA can
1535            generate move insn with invalid addresses which is made valid
1536            and efficiently calculated by LRA through further numerous
1537            transformations.  */
1538       if (lra_in_progress
1539             || memory_address_addr_space_p (GET_MODE (op), y, MEM_ADDR_SPACE (op)))
1540           return true;
1541     }
1542 
1543   return false;
1544 }
1545 
1546 /* Return true if OP is a valid memory address for a memory reference
1547    of mode MODE.
1548 
1549    The main use of this function is as a predicate in match_operand
1550    expressions in the machine description.  */
1551 
1552 bool
address_operand(rtx op,machine_mode mode)1553 address_operand (rtx op, machine_mode mode)
1554 {
1555   /* Wrong mode for an address expr.  */
1556   if (GET_MODE (op) != VOIDmode
1557       && ! SCALAR_INT_MODE_P (GET_MODE (op)))
1558     return false;
1559 
1560   return memory_address_p (mode, op);
1561 }
1562 
1563 /* Return true if OP is a register reference of mode MODE.
1564    If MODE is VOIDmode, accept a register in any mode.
1565 
1566    The main use of this function is as a predicate in match_operand
1567    expressions in the machine description.  */
1568 
1569 bool
register_operand(rtx op,machine_mode mode)1570 register_operand (rtx op, machine_mode mode)
1571 {
1572   if (GET_CODE (op) == SUBREG)
1573     {
1574       rtx sub = SUBREG_REG (op);
1575 
1576       /* Before reload, we can allow (SUBREG (MEM...)) as a register operand
1577            because it is guaranteed to be reloaded into one.
1578            Just make sure the MEM is valid in itself.
1579            (Ideally, (SUBREG (MEM)...) should not exist after reload,
1580            but currently it does result from (SUBREG (REG)...) where the
1581            reg went on the stack.)  */
1582       if (!REG_P (sub) && (reload_completed || !MEM_P (sub)))
1583           return false;
1584     }
1585   else if (!REG_P (op))
1586     return false;
1587   return general_operand (op, mode);
1588 }
1589 
1590 /* Return true for a register in Pmode; ignore the tested mode.  */
1591 
1592 bool
pmode_register_operand(rtx op,machine_mode mode ATTRIBUTE_UNUSED)1593 pmode_register_operand (rtx op, machine_mode mode ATTRIBUTE_UNUSED)
1594 {
1595   return register_operand (op, Pmode);
1596 }
1597 
1598 /* Return true if OP should match a MATCH_SCRATCH, i.e., if it is a SCRATCH
1599    or a hard register.  */
1600 
1601 bool
scratch_operand(rtx op,machine_mode mode)1602 scratch_operand (rtx op, machine_mode mode)
1603 {
1604   if (GET_MODE (op) != mode && mode != VOIDmode)
1605     return false;
1606 
1607   return (GET_CODE (op) == SCRATCH
1608             || (REG_P (op)
1609                 && (lra_in_progress
1610                       || (REGNO (op) < FIRST_PSEUDO_REGISTER
1611                           && REGNO_REG_CLASS (REGNO (op)) != NO_REGS))));
1612 }
1613 
1614 /* Return true if OP is a valid immediate operand for mode MODE.
1615 
1616    The main use of this function is as a predicate in match_operand
1617    expressions in the machine description.  */
1618 
1619 bool
immediate_operand(rtx op,machine_mode mode)1620 immediate_operand (rtx op, machine_mode mode)
1621 {
1622   /* Don't accept CONST_INT or anything similar
1623      if the caller wants something floating.  */
1624   if (GET_MODE (op) == VOIDmode && mode != VOIDmode
1625       && GET_MODE_CLASS (mode) != MODE_INT
1626       && GET_MODE_CLASS (mode) != MODE_PARTIAL_INT)
1627     return false;
1628 
1629   if (CONST_INT_P (op)
1630       && mode != VOIDmode
1631       && trunc_int_for_mode (INTVAL (op), mode) != INTVAL (op))
1632     return false;
1633 
1634   return (CONSTANT_P (op)
1635             && (GET_MODE (op) == mode || mode == VOIDmode
1636                 || GET_MODE (op) == VOIDmode)
1637             && (! flag_pic || LEGITIMATE_PIC_OPERAND_P (op))
1638             && targetm.legitimate_constant_p (mode == VOIDmode
1639                                                       ? GET_MODE (op)
1640                                                       : mode, op));
1641 }
1642 
1643 /* Return true if OP is an operand that is a CONST_INT of mode MODE.  */
1644 
1645 bool
const_int_operand(rtx op,machine_mode mode)1646 const_int_operand (rtx op, machine_mode mode)
1647 {
1648   if (!CONST_INT_P (op))
1649     return false;
1650 
1651   if (mode != VOIDmode
1652       && trunc_int_for_mode (INTVAL (op), mode) != INTVAL (op))
1653     return false;
1654 
1655   return true;
1656 }
1657 
1658 #if TARGET_SUPPORTS_WIDE_INT
1659 /* Return true if OP is an operand that is a CONST_INT or CONST_WIDE_INT
1660    of mode MODE.  */
1661 bool
const_scalar_int_operand(rtx op,machine_mode mode)1662 const_scalar_int_operand (rtx op, machine_mode mode)
1663 {
1664   if (!CONST_SCALAR_INT_P (op))
1665     return false;
1666 
1667   if (CONST_INT_P (op))
1668     return const_int_operand (op, mode);
1669 
1670   if (mode != VOIDmode)
1671     {
1672       scalar_int_mode int_mode = as_a <scalar_int_mode> (mode);
1673       int prec = GET_MODE_PRECISION (int_mode);
1674       int bitsize = GET_MODE_BITSIZE (int_mode);
1675 
1676       if (CONST_WIDE_INT_NUNITS (op) * HOST_BITS_PER_WIDE_INT > bitsize)
1677           return false;
1678 
1679       if (prec == bitsize)
1680           return true;
1681       else
1682           {
1683             /* Multiword partial int.  */
1684             HOST_WIDE_INT x
1685               = CONST_WIDE_INT_ELT (op, CONST_WIDE_INT_NUNITS (op) - 1);
1686             return (sext_hwi (x, prec & (HOST_BITS_PER_WIDE_INT - 1)) == x);
1687           }
1688     }
1689   return true;
1690 }
1691 
1692 /* Return true if OP is an operand that is a constant integer or constant
1693    floating-point number of MODE.  */
1694 
1695 bool
const_double_operand(rtx op,machine_mode mode)1696 const_double_operand (rtx op, machine_mode mode)
1697 {
1698   return (GET_CODE (op) == CONST_DOUBLE)
1699             && (GET_MODE (op) == mode || mode == VOIDmode);
1700 }
1701 #else
1702 /* Return true if OP is an operand that is a constant integer or constant
1703    floating-point number of MODE.  */
1704 
1705 bool
const_double_operand(rtx op,machine_mode mode)1706 const_double_operand (rtx op, machine_mode mode)
1707 {
1708   /* Don't accept CONST_INT or anything similar
1709      if the caller wants something floating.  */
1710   if (GET_MODE (op) == VOIDmode && mode != VOIDmode
1711       && GET_MODE_CLASS (mode) != MODE_INT
1712       && GET_MODE_CLASS (mode) != MODE_PARTIAL_INT)
1713     return false;
1714 
1715   return ((CONST_DOUBLE_P (op) || CONST_INT_P (op))
1716             && (mode == VOIDmode || GET_MODE (op) == mode
1717                 || GET_MODE (op) == VOIDmode));
1718 }
1719 #endif
1720 /* Return true if OP is a general operand that is not an immediate
1721    operand of mode MODE.  */
1722 
1723 bool
nonimmediate_operand(rtx op,machine_mode mode)1724 nonimmediate_operand (rtx op, machine_mode mode)
1725 {
1726   return (general_operand (op, mode) && ! CONSTANT_P (op));
1727 }
1728 
1729 /* Return true if OP is a register reference or
1730    immediate value of mode MODE.  */
1731 
1732 bool
nonmemory_operand(rtx op,machine_mode mode)1733 nonmemory_operand (rtx op, machine_mode mode)
1734 {
1735   if (CONSTANT_P (op))
1736     return immediate_operand (op, mode);
1737   return register_operand (op, mode);
1738 }
1739 
1740 /* Return true if OP is a valid operand that stands for pushing a
1741    value of mode MODE onto the stack.
1742 
1743    The main use of this function is as a predicate in match_operand
1744    expressions in the machine description.  */
1745 
1746 bool
push_operand(rtx op,machine_mode mode)1747 push_operand (rtx op, machine_mode mode)
1748 {
1749   if (!MEM_P (op))
1750     return false;
1751 
1752   if (mode != VOIDmode && GET_MODE (op) != mode)
1753     return false;
1754 
1755   poly_int64 rounded_size = GET_MODE_SIZE (mode);
1756 
1757 #ifdef PUSH_ROUNDING
1758   rounded_size = PUSH_ROUNDING (MACRO_INT (rounded_size));
1759 #endif
1760 
1761   op = XEXP (op, 0);
1762 
1763   if (known_eq (rounded_size, GET_MODE_SIZE (mode)))
1764     {
1765       if (GET_CODE (op) != STACK_PUSH_CODE)
1766           return false;
1767     }
1768   else
1769     {
1770       poly_int64 offset;
1771       if (GET_CODE (op) != PRE_MODIFY
1772             || GET_CODE (XEXP (op, 1)) != PLUS
1773             || XEXP (XEXP (op, 1), 0) != XEXP (op, 0)
1774             || !poly_int_rtx_p (XEXP (XEXP (op, 1), 1), &offset)
1775             || (STACK_GROWS_DOWNWARD
1776                 ? maybe_ne (offset, -rounded_size)
1777                 : maybe_ne (offset, rounded_size)))
1778           return false;
1779     }
1780 
1781   return XEXP (op, 0) == stack_pointer_rtx;
1782 }
1783 
1784 /* Return true if OP is a valid operand that stands for popping a
1785    value of mode MODE off the stack.
1786 
1787    The main use of this function is as a predicate in match_operand
1788    expressions in the machine description.  */
1789 
1790 bool
pop_operand(rtx op,machine_mode mode)1791 pop_operand (rtx op, machine_mode mode)
1792 {
1793   if (!MEM_P (op))
1794     return false;
1795 
1796   if (mode != VOIDmode && GET_MODE (op) != mode)
1797     return false;
1798 
1799   op = XEXP (op, 0);
1800 
1801   if (GET_CODE (op) != STACK_POP_CODE)
1802     return false;
1803 
1804   return XEXP (op, 0) == stack_pointer_rtx;
1805 }
1806 
1807 /* Return true if ADDR is a valid memory address
1808    for mode MODE in address space AS.  */
1809 
1810 bool
memory_address_addr_space_p(machine_mode mode ATTRIBUTE_UNUSED,rtx addr,addr_space_t as)1811 memory_address_addr_space_p (machine_mode mode ATTRIBUTE_UNUSED,
1812                                    rtx addr, addr_space_t as)
1813 {
1814 #ifdef GO_IF_LEGITIMATE_ADDRESS
1815   gcc_assert (ADDR_SPACE_GENERIC_P (as));
1816   GO_IF_LEGITIMATE_ADDRESS (mode, addr, win);
1817   return false;
1818 
1819  win:
1820   return true;
1821 #else
1822   return targetm.addr_space.legitimate_address_p (mode, addr, 0, as);
1823 #endif
1824 }
1825 
1826 /* Return true if OP is a valid memory reference with mode MODE,
1827    including a valid address.
1828 
1829    The main use of this function is as a predicate in match_operand
1830    expressions in the machine description.  */
1831 
1832 bool
memory_operand(rtx op,machine_mode mode)1833 memory_operand (rtx op, machine_mode mode)
1834 {
1835   rtx inner;
1836 
1837   if (! reload_completed)
1838     /* Note that no SUBREG is a memory operand before end of reload pass,
1839        because (SUBREG (MEM...)) forces reloading into a register.  */
1840     return MEM_P (op) && general_operand (op, mode);
1841 
1842   if (mode != VOIDmode && GET_MODE (op) != mode)
1843     return false;
1844 
1845   inner = op;
1846   if (GET_CODE (inner) == SUBREG)
1847     inner = SUBREG_REG (inner);
1848 
1849   return (MEM_P (inner) && general_operand (op, mode));
1850 }
1851 
1852 /* Return true if OP is a valid indirect memory reference with mode MODE;
1853    that is, a memory reference whose address is a general_operand.  */
1854 
1855 bool
indirect_operand(rtx op,machine_mode mode)1856 indirect_operand (rtx op, machine_mode mode)
1857 {
1858   /* Before reload, a SUBREG isn't in memory (see memory_operand, above).  */
1859   if (! reload_completed
1860       && GET_CODE (op) == SUBREG && MEM_P (SUBREG_REG (op)))
1861     {
1862       if (mode != VOIDmode && GET_MODE (op) != mode)
1863           return false;
1864 
1865       /* The only way that we can have a general_operand as the resulting
1866            address is if OFFSET is zero and the address already is an operand
1867            or if the address is (plus Y (const_int -OFFSET)) and Y is an
1868            operand.  */
1869       poly_int64 offset;
1870       rtx addr = strip_offset (XEXP (SUBREG_REG (op), 0), &offset);
1871       return (known_eq (offset + SUBREG_BYTE (op), 0)
1872                 && general_operand (addr, Pmode));
1873     }
1874 
1875   return (MEM_P (op)
1876             && memory_operand (op, mode)
1877             && general_operand (XEXP (op, 0), Pmode));
1878 }
1879 
1880 /* Return true if this is an ordered comparison operator (not including
1881    ORDERED and UNORDERED).  */
1882 
1883 bool
ordered_comparison_operator(rtx op,machine_mode mode)1884 ordered_comparison_operator (rtx op, machine_mode mode)
1885 {
1886   if (mode != VOIDmode && GET_MODE (op) != mode)
1887     return false;
1888   switch (GET_CODE (op))
1889     {
1890     case EQ:
1891     case NE:
1892     case LT:
1893     case LTU:
1894     case LE:
1895     case LEU:
1896     case GT:
1897     case GTU:
1898     case GE:
1899     case GEU:
1900       return true;
1901     default:
1902       return false;
1903     }
1904 }
1905 
1906 /* Return true if this is a comparison operator.  This allows the use of
1907    MATCH_OPERATOR to recognize all the branch insns.  */
1908 
1909 bool
comparison_operator(rtx op,machine_mode mode)1910 comparison_operator (rtx op, machine_mode mode)
1911 {
1912   return ((mode == VOIDmode || GET_MODE (op) == mode)
1913             && COMPARISON_P (op));
1914 }
1915 
1916 /* If BODY is an insn body that uses ASM_OPERANDS, return it.  */
1917 
1918 rtx
extract_asm_operands(rtx body)1919 extract_asm_operands (rtx body)
1920 {
1921   rtx tmp;
1922   switch (GET_CODE (body))
1923     {
1924     case ASM_OPERANDS:
1925       return body;
1926 
1927     case SET:
1928       /* Single output operand: BODY is (set OUTPUT (asm_operands ...)).  */
1929       tmp = SET_SRC (body);
1930       if (GET_CODE (tmp) == ASM_OPERANDS)
1931           return tmp;
1932       break;
1933 
1934     case PARALLEL:
1935       tmp = XVECEXP (body, 0, 0);
1936       if (GET_CODE (tmp) == ASM_OPERANDS)
1937           return tmp;
1938       if (GET_CODE (tmp) == SET)
1939           {
1940             tmp = SET_SRC (tmp);
1941             if (GET_CODE (tmp) == ASM_OPERANDS)
1942               return tmp;
1943           }
1944       break;
1945 
1946     default:
1947       break;
1948     }
1949   return NULL;
1950 }
1951 
1952 /* If BODY is an insn body that uses ASM_OPERANDS,
1953    return the number of operands (both input and output) in the insn.
1954    If BODY is an insn body that uses ASM_INPUT with CLOBBERS in PARALLEL,
1955    return 0.
1956    Otherwise return -1.  */
1957 
1958 int
asm_noperands(const_rtx body)1959 asm_noperands (const_rtx body)
1960 {
1961   rtx asm_op = extract_asm_operands (CONST_CAST_RTX (body));
1962   int i, n_sets = 0;
1963 
1964   if (asm_op == NULL)
1965     {
1966       if (GET_CODE (body) == PARALLEL && XVECLEN (body, 0) >= 2
1967             && GET_CODE (XVECEXP (body, 0, 0)) == ASM_INPUT)
1968           {
1969             /* body is [(asm_input ...) (clobber (reg ...))...].  */
1970             for (i = XVECLEN (body, 0) - 1; i > 0; i--)
1971               if (GET_CODE (XVECEXP (body, 0, i)) != CLOBBER)
1972                 return -1;
1973             return 0;
1974           }
1975       return -1;
1976     }
1977 
1978   if (GET_CODE (body) == SET)
1979     n_sets = 1;
1980   else if (GET_CODE (body) == PARALLEL)
1981     {
1982       if (GET_CODE (XVECEXP (body, 0, 0)) == SET)
1983           {
1984             /* Multiple output operands, or 1 output plus some clobbers:
1985                body is
1986                [(set OUTPUT (asm_operands ...))... (clobber (reg ...))...].  */
1987             /* Count backwards through CLOBBERs to determine number of SETs.  */
1988             for (i = XVECLEN (body, 0); i > 0; i--)
1989               {
1990                 if (GET_CODE (XVECEXP (body, 0, i - 1)) == SET)
1991                     break;
1992                 if (GET_CODE (XVECEXP (body, 0, i - 1)) != CLOBBER)
1993                     return -1;
1994               }
1995 
1996             /* N_SETS is now number of output operands.  */
1997             n_sets = i;
1998 
1999             /* Verify that all the SETs we have
2000                came from a single original asm_operands insn
2001                (so that invalid combinations are blocked).  */
2002             for (i = 0; i < n_sets; i++)
2003               {
2004                 rtx elt = XVECEXP (body, 0, i);
2005                 if (GET_CODE (elt) != SET)
2006                     return -1;
2007                 if (GET_CODE (SET_SRC (elt)) != ASM_OPERANDS)
2008                     return -1;
2009                 /* If these ASM_OPERANDS rtx's came from different original insns
2010                    then they aren't allowed together.  */
2011                 if (ASM_OPERANDS_INPUT_VEC (SET_SRC (elt))
2012                       != ASM_OPERANDS_INPUT_VEC (asm_op))
2013                     return -1;
2014               }
2015           }
2016       else
2017           {
2018             /* 0 outputs, but some clobbers:
2019                body is [(asm_operands ...) (clobber (reg ...))...].  */
2020             /* Make sure all the other parallel things really are clobbers.  */
2021             for (i = XVECLEN (body, 0) - 1; i > 0; i--)
2022               if (GET_CODE (XVECEXP (body, 0, i)) != CLOBBER)
2023                 return -1;
2024           }
2025     }
2026 
2027   return (ASM_OPERANDS_INPUT_LENGTH (asm_op)
2028             + ASM_OPERANDS_LABEL_LENGTH (asm_op) + n_sets);
2029 }
2030 
2031 /* Assuming BODY is an insn body that uses ASM_OPERANDS,
2032    copy its operands (both input and output) into the vector OPERANDS,
2033    the locations of the operands within the insn into the vector OPERAND_LOCS,
2034    and the constraints for the operands into CONSTRAINTS.
2035    Write the modes of the operands into MODES.
2036    Write the location info into LOC.
2037    Return the assembler-template.
2038    If BODY is an insn body that uses ASM_INPUT with CLOBBERS in PARALLEL,
2039    return the basic assembly string.
2040 
2041    If LOC, MODES, OPERAND_LOCS, CONSTRAINTS or OPERANDS is 0,
2042    we don't store that info.  */
2043 
2044 const char *
decode_asm_operands(rtx body,rtx * operands,rtx ** operand_locs,const char ** constraints,machine_mode * modes,location_t * loc)2045 decode_asm_operands (rtx body, rtx *operands, rtx **operand_locs,
2046                          const char **constraints, machine_mode *modes,
2047                          location_t *loc)
2048 {
2049   int nbase = 0, n, i;
2050   rtx asmop;
2051 
2052   switch (GET_CODE (body))
2053     {
2054     case ASM_OPERANDS:
2055       /* Zero output asm: BODY is (asm_operands ...).  */
2056       asmop = body;
2057       break;
2058 
2059     case SET:
2060       /* Single output asm: BODY is (set OUTPUT (asm_operands ...)).  */
2061       asmop = SET_SRC (body);
2062 
2063       /* The output is in the SET.
2064            Its constraint is in the ASM_OPERANDS itself.  */
2065       if (operands)
2066           operands[0] = SET_DEST (body);
2067       if (operand_locs)
2068           operand_locs[0] = &SET_DEST (body);
2069       if (constraints)
2070           constraints[0] = ASM_OPERANDS_OUTPUT_CONSTRAINT (asmop);
2071       if (modes)
2072           modes[0] = GET_MODE (SET_DEST (body));
2073       nbase = 1;
2074       break;
2075 
2076     case PARALLEL:
2077       {
2078           int nparallel = XVECLEN (body, 0); /* Includes CLOBBERs.  */
2079 
2080           asmop = XVECEXP (body, 0, 0);
2081           if (GET_CODE (asmop) == SET)
2082             {
2083               asmop = SET_SRC (asmop);
2084 
2085               /* At least one output, plus some CLOBBERs.  The outputs are in
2086                  the SETs.  Their constraints are in the ASM_OPERANDS itself.  */
2087               for (i = 0; i < nparallel; i++)
2088                 {
2089                     if (GET_CODE (XVECEXP (body, 0, i)) == CLOBBER)
2090                       break;            /* Past last SET */
2091                     gcc_assert (GET_CODE (XVECEXP (body, 0, i)) == SET);
2092                     if (operands)
2093                       operands[i] = SET_DEST (XVECEXP (body, 0, i));
2094                     if (operand_locs)
2095                       operand_locs[i] = &SET_DEST (XVECEXP (body, 0, i));
2096                     if (constraints)
2097                       constraints[i] = XSTR (SET_SRC (XVECEXP (body, 0, i)), 1);
2098                     if (modes)
2099                       modes[i] = GET_MODE (SET_DEST (XVECEXP (body, 0, i)));
2100                 }
2101               nbase = i;
2102             }
2103           else if (GET_CODE (asmop) == ASM_INPUT)
2104             {
2105               if (loc)
2106                 *loc = ASM_INPUT_SOURCE_LOCATION (asmop);
2107               return XSTR (asmop, 0);
2108             }
2109           break;
2110       }
2111 
2112     default:
2113       gcc_unreachable ();
2114     }
2115 
2116   n = ASM_OPERANDS_INPUT_LENGTH (asmop);
2117   for (i = 0; i < n; i++)
2118     {
2119       if (operand_locs)
2120           operand_locs[nbase + i] = &ASM_OPERANDS_INPUT (asmop, i);
2121       if (operands)
2122           operands[nbase + i] = ASM_OPERANDS_INPUT (asmop, i);
2123       if (constraints)
2124           constraints[nbase + i] = ASM_OPERANDS_INPUT_CONSTRAINT (asmop, i);
2125       if (modes)
2126           modes[nbase + i] = ASM_OPERANDS_INPUT_MODE (asmop, i);
2127     }
2128   nbase += n;
2129 
2130   n = ASM_OPERANDS_LABEL_LENGTH (asmop);
2131   for (i = 0; i < n; i++)
2132     {
2133       if (operand_locs)
2134           operand_locs[nbase + i] = &ASM_OPERANDS_LABEL (asmop, i);
2135       if (operands)
2136           operands[nbase + i] = ASM_OPERANDS_LABEL (asmop, i);
2137       if (constraints)
2138           constraints[nbase + i] = "";
2139       if (modes)
2140           modes[nbase + i] = Pmode;
2141     }
2142 
2143   if (loc)
2144     *loc = ASM_OPERANDS_SOURCE_LOCATION (asmop);
2145 
2146   return ASM_OPERANDS_TEMPLATE (asmop);
2147 }
2148 
2149 /* Parse inline assembly string STRING and determine which operands are
2150    referenced by % markers.  For the first NOPERANDS operands, set USED[I]
2151    to true if operand I is referenced.
2152 
2153    This is intended to distinguish barrier-like asms such as:
2154 
2155       asm ("" : "=m" (...));
2156 
2157    from real references such as:
2158 
2159       asm ("sw\t$0, %0" : "=m" (...));  */
2160 
2161 void
get_referenced_operands(const char * string,bool * used,unsigned int noperands)2162 get_referenced_operands (const char *string, bool *used,
2163                                unsigned int noperands)
2164 {
2165   memset (used, 0, sizeof (bool) * noperands);
2166   const char *p = string;
2167   while (*p)
2168     switch (*p)
2169       {
2170       case '%':
2171           p += 1;
2172           /* A letter followed by a digit indicates an operand number.  */
2173           if (ISALPHA (p[0]) && ISDIGIT (p[1]))
2174             p += 1;
2175           if (ISDIGIT (*p))
2176             {
2177               char *endptr;
2178               unsigned long opnum = strtoul (p, &endptr, 10);
2179               if (endptr != p && opnum < noperands)
2180                 used[opnum] = true;
2181               p = endptr;
2182             }
2183           else
2184             p += 1;
2185           break;
2186 
2187       default:
2188           p++;
2189           break;
2190       }
2191 }
2192 
2193 /* Check if an asm_operand matches its constraints.
2194    Return > 0 if ok, = 0 if bad, < 0 if inconclusive.  */
2195 
2196 int
asm_operand_ok(rtx op,const char * constraint,const char ** constraints)2197 asm_operand_ok (rtx op, const char *constraint, const char **constraints)
2198 {
2199   int result = 0;
2200   bool incdec_ok = false;
2201 
2202   /* Use constrain_operands after reload.  */
2203   gcc_assert (!reload_completed);
2204 
2205   /* Empty constraint string is the same as "X,...,X", i.e. X for as
2206      many alternatives as required to match the other operands.  */
2207   if (*constraint == '\0')
2208     result = 1;
2209 
2210   while (*constraint)
2211     {
2212       enum constraint_num cn;
2213       char c = *constraint;
2214       int len;
2215       switch (c)
2216           {
2217           case ',':
2218             constraint++;
2219             continue;
2220 
2221           case '0': case '1': case '2': case '3': case '4':
2222           case '5': case '6': case '7': case '8': case '9':
2223             /* If caller provided constraints pointer, look up
2224                the matching constraint.  Otherwise, our caller should have
2225                given us the proper matching constraint, but we can't
2226                actually fail the check if they didn't.  Indicate that
2227                results are inconclusive.  */
2228             if (constraints)
2229               {
2230                 char *end;
2231                 unsigned long match;
2232 
2233                 match = strtoul (constraint, &end, 10);
2234                 if (!result)
2235                     result = asm_operand_ok (op, constraints[match], NULL);
2236                 constraint = (const char *) end;
2237               }
2238             else
2239               {
2240                 do
2241                     constraint++;
2242                 while (ISDIGIT (*constraint));
2243                 if (! result)
2244                     result = -1;
2245               }
2246             continue;
2247 
2248             /* The rest of the compiler assumes that reloading the address
2249                of a MEM into a register will make it fit an 'o' constraint.
2250                That is, if it sees a MEM operand for an 'o' constraint,
2251                it assumes that (mem (base-reg)) will fit.
2252 
2253                That assumption fails on targets that don't have offsettable
2254                addresses at all.  We therefore need to treat 'o' asm
2255                constraints as a special case and only accept operands that
2256                are already offsettable, thus proving that at least one
2257                offsettable address exists.  */
2258           case 'o': /* offsettable */
2259             if (offsettable_nonstrict_memref_p (op))
2260               result = 1;
2261             break;
2262 
2263           case 'g':
2264             if (general_operand (op, VOIDmode))
2265               result = 1;
2266             break;
2267 
2268           case '<':
2269           case '>':
2270             /* ??? Before auto-inc-dec, auto inc/dec insns are not supposed
2271                to exist, excepting those that expand_call created.  Further,
2272                on some machines which do not have generalized auto inc/dec,
2273                an inc/dec is not a memory_operand.
2274 
2275                Match any memory and hope things are resolved after reload.  */
2276             incdec_ok = true;
2277             /* FALLTHRU */
2278           default:
2279             cn = lookup_constraint (constraint);
2280             rtx mem = NULL;
2281             switch (get_constraint_type (cn))
2282               {
2283               case CT_REGISTER:
2284                 if (!result
2285                       && reg_class_for_constraint (cn) != NO_REGS
2286                       && GET_MODE (op) != BLKmode
2287                       && register_operand (op, VOIDmode))
2288                     result = 1;
2289                 break;
2290 
2291               case CT_CONST_INT:
2292                 if (!result
2293                       && CONST_INT_P (op)
2294                       && insn_const_int_ok_for_constraint (INTVAL (op), cn))
2295                     result = 1;
2296                 break;
2297 
2298               case CT_MEMORY:
2299               case CT_RELAXED_MEMORY:
2300                 mem = op;
2301                 /* Fall through.  */
2302               case CT_SPECIAL_MEMORY:
2303                 /* Every memory operand can be reloaded to fit.  */
2304                 if (!mem)
2305                     mem = extract_mem_from_operand (op);
2306                 result = result || memory_operand (mem, VOIDmode);
2307                 break;
2308 
2309               case CT_ADDRESS:
2310                 /* Every address operand can be reloaded to fit.  */
2311                 result = result || address_operand (op, VOIDmode);
2312                 break;
2313 
2314               case CT_FIXED_FORM:
2315                 result = result || constraint_satisfied_p (op, cn);
2316                 break;
2317               }
2318             break;
2319           }
2320       len = CONSTRAINT_LEN (c, constraint);
2321       do
2322           constraint++;
2323       while (--len && *constraint && *constraint != ',');
2324       if (len)
2325           return 0;
2326     }
2327 
2328   /* For operands without < or > constraints reject side-effects.  */
2329   if (AUTO_INC_DEC && !incdec_ok && result && MEM_P (op))
2330     switch (GET_CODE (XEXP (op, 0)))
2331       {
2332       case PRE_INC:
2333       case POST_INC:
2334       case PRE_DEC:
2335       case POST_DEC:
2336       case PRE_MODIFY:
2337       case POST_MODIFY:
2338           return 0;
2339       default:
2340           break;
2341       }
2342 
2343   return result;
2344 }
2345 
2346 /* Given an rtx *P, if it is a sum containing an integer constant term,
2347    return the location (type rtx *) of the pointer to that constant term.
2348    Otherwise, return a null pointer.  */
2349 
2350 rtx *
find_constant_term_loc(rtx * p)2351 find_constant_term_loc (rtx *p)
2352 {
2353   rtx *tem;
2354   enum rtx_code code = GET_CODE (*p);
2355 
2356   /* If *P IS such a constant term, P is its location.  */
2357 
2358   if (code == CONST_INT || code == SYMBOL_REF || code == LABEL_REF
2359       || code == CONST)
2360     return p;
2361 
2362   /* Otherwise, if not a sum, it has no constant term.  */
2363 
2364   if (GET_CODE (*p) != PLUS)
2365     return 0;
2366 
2367   /* If one of the summands is constant, return its location.  */
2368 
2369   if (XEXP (*p, 0) && CONSTANT_P (XEXP (*p, 0))
2370       && XEXP (*p, 1) && CONSTANT_P (XEXP (*p, 1)))
2371     return p;
2372 
2373   /* Otherwise, check each summand for containing a constant term.  */
2374 
2375   if (XEXP (*p, 0) != 0)
2376     {
2377       tem = find_constant_term_loc (&XEXP (*p, 0));
2378       if (tem != 0)
2379           return tem;
2380     }
2381 
2382   if (XEXP (*p, 1) != 0)
2383     {
2384       tem = find_constant_term_loc (&XEXP (*p, 1));
2385       if (tem != 0)
2386           return tem;
2387     }
2388 
2389   return 0;
2390 }
2391 
2392 /* Return true if OP is a memory reference whose address contains
2393    no side effects and remains valid after the addition of a positive
2394    integer less than the size of the object being referenced.
2395 
2396    We assume that the original address is valid and do not check it.
2397 
2398    This uses strict_memory_address_p as a subroutine, so
2399    don't use it before reload.  */
2400 
2401 bool
offsettable_memref_p(rtx op)2402 offsettable_memref_p (rtx op)
2403 {
2404   return ((MEM_P (op))
2405             && offsettable_address_addr_space_p (1, GET_MODE (op), XEXP (op, 0),
2406                                                          MEM_ADDR_SPACE (op)));
2407 }
2408 
2409 /* Similar, but don't require a strictly valid mem ref:
2410    consider pseudo-regs valid as index or base regs.  */
2411 
2412 bool
offsettable_nonstrict_memref_p(rtx op)2413 offsettable_nonstrict_memref_p (rtx op)
2414 {
2415   return ((MEM_P (op))
2416             && offsettable_address_addr_space_p (0, GET_MODE (op), XEXP (op, 0),
2417                                                          MEM_ADDR_SPACE (op)));
2418 }
2419 
2420 /* Return true if Y is a memory address which contains no side effects
2421    and would remain valid for address space AS after the addition of
2422    a positive integer less than the size of that mode.
2423 
2424    We assume that the original address is valid and do not check it.
2425    We do check that it is valid for narrower modes.
2426 
2427    If STRICTP is nonzero, we require a strictly valid address,
2428    for the sake of use in reload.cc.  */
2429 
2430 bool
offsettable_address_addr_space_p(int strictp,machine_mode mode,rtx y,addr_space_t as)2431 offsettable_address_addr_space_p (int strictp, machine_mode mode, rtx y,
2432                                           addr_space_t as)
2433 {
2434   enum rtx_code ycode = GET_CODE (y);
2435   rtx z;
2436   rtx y1 = y;
2437   rtx *y2;
2438   bool (*addressp) (machine_mode, rtx, addr_space_t) =
2439     (strictp ? strict_memory_address_addr_space_p
2440                : memory_address_addr_space_p);
2441   poly_int64 mode_sz = GET_MODE_SIZE (mode);
2442 
2443   if (CONSTANT_ADDRESS_P (y))
2444     return true;
2445 
2446   /* Adjusting an offsettable address involves changing to a narrower mode.
2447      Make sure that's OK.  */
2448 
2449   if (mode_dependent_address_p (y, as))
2450     return false;
2451 
2452   machine_mode address_mode = GET_MODE (y);
2453   if (address_mode == VOIDmode)
2454     address_mode = targetm.addr_space.address_mode (as);
2455 #ifdef POINTERS_EXTEND_UNSIGNED
2456   machine_mode pointer_mode = targetm.addr_space.pointer_mode (as);
2457 #endif
2458 
2459   /* ??? How much offset does an offsettable BLKmode reference need?
2460      Clearly that depends on the situation in which it's being used.
2461      However, the current situation in which we test 0xffffffff is
2462      less than ideal.  Caveat user.  */
2463   if (known_eq (mode_sz, 0))
2464     mode_sz = BIGGEST_ALIGNMENT / BITS_PER_UNIT;
2465 
2466   /* If the expression contains a constant term,
2467      see if it remains valid when max possible offset is added.  */
2468 
2469   if ((ycode == PLUS) && (y2 = find_constant_term_loc (&y1)))
2470     {
2471       bool good;
2472 
2473       y1 = *y2;
2474       *y2 = plus_constant (address_mode, *y2, mode_sz - 1);
2475       /* Use QImode because an odd displacement may be automatically invalid
2476            for any wider mode.  But it should be valid for a single byte.  */
2477       good = (*addressp) (QImode, y, as);
2478 
2479       /* In any case, restore old contents of memory.  */
2480       *y2 = y1;
2481       return good;
2482     }
2483 
2484   if (GET_RTX_CLASS (ycode) == RTX_AUTOINC)
2485     return false;
2486 
2487   /* The offset added here is chosen as the maximum offset that
2488      any instruction could need to add when operating on something
2489      of the specified mode.  We assume that if Y and Y+c are
2490      valid addresses then so is Y+d for all 0<d<c.  adjust_address will
2491      go inside a LO_SUM here, so we do so as well.  */
2492   if (GET_CODE (y) == LO_SUM
2493       && mode != BLKmode
2494       && known_le (mode_sz, GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT))
2495     z = gen_rtx_LO_SUM (address_mode, XEXP (y, 0),
2496                               plus_constant (address_mode, XEXP (y, 1),
2497                                                mode_sz - 1));
2498 #ifdef POINTERS_EXTEND_UNSIGNED
2499   /* Likewise for a ZERO_EXTEND from pointer_mode.  */
2500   else if (POINTERS_EXTEND_UNSIGNED > 0
2501              && GET_CODE (y) == ZERO_EXTEND
2502              && GET_MODE (XEXP (y, 0)) == pointer_mode)
2503     z = gen_rtx_ZERO_EXTEND (address_mode,
2504                                    plus_constant (pointer_mode, XEXP (y, 0),
2505                                                       mode_sz - 1));
2506 #endif
2507   else
2508     z = plus_constant (address_mode, y, mode_sz - 1);
2509 
2510   /* Use QImode because an odd displacement may be automatically invalid
2511      for any wider mode.  But it should be valid for a single byte.  */
2512   return (*addressp) (QImode, z, as);
2513 }
2514 
2515 /* Return true if ADDR is an address-expression whose effect depends
2516    on the mode of the memory reference it is used in.
2517 
2518    ADDRSPACE is the address space associated with the address.
2519 
2520    Autoincrement addressing is a typical example of mode-dependence
2521    because the amount of the increment depends on the mode.  */
2522 
2523 bool
mode_dependent_address_p(rtx addr,addr_space_t addrspace)2524 mode_dependent_address_p (rtx addr, addr_space_t addrspace)
2525 {
2526   /* Auto-increment addressing with anything other than post_modify
2527      or pre_modify always introduces a mode dependency.  Catch such
2528      cases now instead of deferring to the target.  */
2529   if (GET_CODE (addr) == PRE_INC
2530       || GET_CODE (addr) == POST_INC
2531       || GET_CODE (addr) == PRE_DEC
2532       || GET_CODE (addr) == POST_DEC)
2533     return true;
2534 
2535   return targetm.mode_dependent_address_p (addr, addrspace);
2536 }
2537 
2538 /* Return true if boolean attribute ATTR is supported.  */
2539 
2540 static bool
have_bool_attr(bool_attr attr)2541 have_bool_attr (bool_attr attr)
2542 {
2543   switch (attr)
2544     {
2545     case BA_ENABLED:
2546       return HAVE_ATTR_enabled;
2547     case BA_PREFERRED_FOR_SIZE:
2548       return HAVE_ATTR_enabled || HAVE_ATTR_preferred_for_size;
2549     case BA_PREFERRED_FOR_SPEED:
2550       return HAVE_ATTR_enabled || HAVE_ATTR_preferred_for_speed;
2551     }
2552   gcc_unreachable ();
2553 }
2554 
2555 /* Return the value of ATTR for instruction INSN.  */
2556 
2557 static bool
get_bool_attr(rtx_insn * insn,bool_attr attr)2558 get_bool_attr (rtx_insn *insn, bool_attr attr)
2559 {
2560   switch (attr)
2561     {
2562     case BA_ENABLED:
2563       return get_attr_enabled (insn);
2564     case BA_PREFERRED_FOR_SIZE:
2565       return get_attr_enabled (insn) && get_attr_preferred_for_size (insn);
2566     case BA_PREFERRED_FOR_SPEED:
2567       return get_attr_enabled (insn) && get_attr_preferred_for_speed (insn);
2568     }
2569   gcc_unreachable ();
2570 }
2571 
2572 /* Like get_bool_attr_mask, but don't use the cache.  */
2573 
2574 static alternative_mask
get_bool_attr_mask_uncached(rtx_insn * insn,bool_attr attr)2575 get_bool_attr_mask_uncached (rtx_insn *insn, bool_attr attr)
2576 {
2577   /* Temporarily install enough information for get_attr_<foo> to assume
2578      that the insn operands are already cached.  As above, the attribute
2579      mustn't depend on the values of operands, so we don't provide their
2580      real values here.  */
2581   rtx_insn *old_insn = recog_data.insn;
2582   int old_alternative = which_alternative;
2583 
2584   recog_data.insn = insn;
2585   alternative_mask mask = ALL_ALTERNATIVES;
2586   int n_alternatives = insn_data[INSN_CODE (insn)].n_alternatives;
2587   for (int i = 0; i < n_alternatives; i++)
2588     {
2589       which_alternative = i;
2590       if (!get_bool_attr (insn, attr))
2591           mask &= ~ALTERNATIVE_BIT (i);
2592     }
2593 
2594   recog_data.insn = old_insn;
2595   which_alternative = old_alternative;
2596   return mask;
2597 }
2598 
2599 /* Return the mask of operand alternatives that are allowed for INSN
2600    by boolean attribute ATTR.  This mask depends only on INSN and on
2601    the current target; it does not depend on things like the values of
2602    operands.  */
2603 
2604 static alternative_mask
get_bool_attr_mask(rtx_insn * insn,bool_attr attr)2605 get_bool_attr_mask (rtx_insn *insn, bool_attr attr)
2606 {
2607   /* Quick exit for asms and for targets that don't use these attributes.  */
2608   int code = INSN_CODE (insn);
2609   if (code < 0 || !have_bool_attr (attr))
2610     return ALL_ALTERNATIVES;
2611 
2612   /* Calling get_attr_<foo> can be expensive, so cache the mask
2613      for speed.  */
2614   if (!this_target_recog->x_bool_attr_masks[code][attr])
2615     this_target_recog->x_bool_attr_masks[code][attr]
2616       = get_bool_attr_mask_uncached (insn, attr);
2617   return this_target_recog->x_bool_attr_masks[code][attr];
2618 }
2619 
2620 /* Return the set of alternatives of INSN that are allowed by the current
2621    target.  */
2622 
2623 alternative_mask
get_enabled_alternatives(rtx_insn * insn)2624 get_enabled_alternatives (rtx_insn *insn)
2625 {
2626   return get_bool_attr_mask (insn, BA_ENABLED);
2627 }
2628 
2629 /* Return the set of alternatives of INSN that are allowed by the current
2630    target and are preferred for the current size/speed optimization
2631    choice.  */
2632 
2633 alternative_mask
get_preferred_alternatives(rtx_insn * insn)2634 get_preferred_alternatives (rtx_insn *insn)
2635 {
2636   if (optimize_bb_for_speed_p (BLOCK_FOR_INSN (insn)))
2637     return get_bool_attr_mask (insn, BA_PREFERRED_FOR_SPEED);
2638   else
2639     return get_bool_attr_mask (insn, BA_PREFERRED_FOR_SIZE);
2640 }
2641 
2642 /* Return the set of alternatives of INSN that are allowed by the current
2643    target and are preferred for the size/speed optimization choice
2644    associated with BB.  Passing a separate BB is useful if INSN has not
2645    been emitted yet or if we are considering moving it to a different
2646    block.  */
2647 
2648 alternative_mask
get_preferred_alternatives(rtx_insn * insn,basic_block bb)2649 get_preferred_alternatives (rtx_insn *insn, basic_block bb)
2650 {
2651   if (optimize_bb_for_speed_p (bb))
2652     return get_bool_attr_mask (insn, BA_PREFERRED_FOR_SPEED);
2653   else
2654     return get_bool_attr_mask (insn, BA_PREFERRED_FOR_SIZE);
2655 }
2656 
2657 /* Assert that the cached boolean attributes for INSN are still accurate.
2658    The backend is required to define these attributes in a way that only
2659    depends on the current target (rather than operands, compiler phase,
2660    etc.).  */
2661 
2662 bool
check_bool_attrs(rtx_insn * insn)2663 check_bool_attrs (rtx_insn *insn)
2664 {
2665   int code = INSN_CODE (insn);
2666   if (code >= 0)
2667     for (int i = 0; i <= BA_LAST; ++i)
2668       {
2669           enum bool_attr attr = (enum bool_attr) i;
2670           if (this_target_recog->x_bool_attr_masks[code][attr])
2671             gcc_assert (this_target_recog->x_bool_attr_masks[code][attr]
2672                           == get_bool_attr_mask_uncached (insn, attr));
2673       }
2674   return true;
2675 }
2676 
2677 /* Like extract_insn, but save insn extracted and don't extract again, when
2678    called again for the same insn expecting that recog_data still contain the
2679    valid information.  This is used primary by gen_attr infrastructure that
2680    often does extract insn again and again.  */
2681 void
extract_insn_cached(rtx_insn * insn)2682 extract_insn_cached (rtx_insn *insn)
2683 {
2684   if (recog_data.insn == insn && INSN_CODE (insn) >= 0)
2685     return;
2686   extract_insn (insn);
2687   recog_data.insn = insn;
2688 }
2689 
2690 /* Do uncached extract_insn, constrain_operands and complain about failures.
2691    This should be used when extracting a pre-existing constrained instruction
2692    if the caller wants to know which alternative was chosen.  */
2693 void
extract_constrain_insn(rtx_insn * insn)2694 extract_constrain_insn (rtx_insn *insn)
2695 {
2696   extract_insn (insn);
2697   if (!constrain_operands (reload_completed, get_enabled_alternatives (insn)))
2698     fatal_insn_not_found (insn);
2699 }
2700 
2701 /* Do cached extract_insn, constrain_operands and complain about failures.
2702    Used by insn_attrtab.  */
2703 void
extract_constrain_insn_cached(rtx_insn * insn)2704 extract_constrain_insn_cached (rtx_insn *insn)
2705 {
2706   extract_insn_cached (insn);
2707   if (which_alternative == -1
2708       && !constrain_operands (reload_completed,
2709                                     get_enabled_alternatives (insn)))
2710     fatal_insn_not_found (insn);
2711 }
2712 
2713 /* Do cached constrain_operands on INSN and complain about failures.  */
2714 int
constrain_operands_cached(rtx_insn * insn,int strict)2715 constrain_operands_cached (rtx_insn *insn, int strict)
2716 {
2717   if (which_alternative == -1)
2718     return constrain_operands (strict, get_enabled_alternatives (insn));
2719   else
2720     return 1;
2721 }
2722 
2723 /* Analyze INSN and fill in recog_data.  */
2724 
2725 void
extract_insn(rtx_insn * insn)2726 extract_insn (rtx_insn *insn)
2727 {
2728   int i;
2729   int icode;
2730   int noperands;
2731   rtx body = PATTERN (insn);
2732 
2733   recog_data.n_operands = 0;
2734   recog_data.n_alternatives = 0;
2735   recog_data.n_dups = 0;
2736   recog_data.is_asm = false;
2737 
2738   switch (GET_CODE (body))
2739     {
2740     case USE:
2741     case CLOBBER:
2742     case ASM_INPUT:
2743     case ADDR_VEC:
2744     case ADDR_DIFF_VEC:
2745     case VAR_LOCATION:
2746     case DEBUG_MARKER:
2747       return;
2748 
2749     case SET:
2750       if (GET_CODE (SET_SRC (body)) == ASM_OPERANDS)
2751           goto asm_insn;
2752       else
2753           goto normal_insn;
2754     case PARALLEL:
2755       if ((GET_CODE (XVECEXP (body, 0, 0)) == SET
2756              && GET_CODE (SET_SRC (XVECEXP (body, 0, 0))) == ASM_OPERANDS)
2757             || GET_CODE (XVECEXP (body, 0, 0)) == ASM_OPERANDS
2758             || GET_CODE (XVECEXP (body, 0, 0)) == ASM_INPUT)
2759           goto asm_insn;
2760       else
2761           goto normal_insn;
2762     case ASM_OPERANDS:
2763     asm_insn:
2764       recog_data.n_operands = noperands = asm_noperands (body);
2765       if (noperands >= 0)
2766           {
2767             /* This insn is an `asm' with operands.  */
2768 
2769             /* expand_asm_operands makes sure there aren't too many operands.  */
2770             gcc_assert (noperands <= MAX_RECOG_OPERANDS);
2771 
2772             /* Now get the operand values and constraints out of the insn.  */
2773             decode_asm_operands (body, recog_data.operand,
2774                                      recog_data.operand_loc,
2775                                      recog_data.constraints,
2776                                      recog_data.operand_mode, NULL);
2777             memset (recog_data.is_operator, 0, sizeof recog_data.is_operator);
2778             if (noperands > 0)
2779               {
2780                 const char *p =  recog_data.constraints[0];
2781                 recog_data.n_alternatives = 1;
2782                 while (*p)
2783                     recog_data.n_alternatives += (*p++ == ',');
2784               }
2785             recog_data.is_asm = true;
2786             break;
2787           }
2788       fatal_insn_not_found (insn);
2789 
2790     default:
2791     normal_insn:
2792       /* Ordinary insn: recognize it, get the operands via insn_extract
2793            and get the constraints.  */
2794 
2795       icode = recog_memoized (insn);
2796       if (icode < 0)
2797           fatal_insn_not_found (insn);
2798 
2799       recog_data.n_operands = noperands = insn_data[icode].n_operands;
2800       recog_data.n_alternatives = insn_data[icode].n_alternatives;
2801       recog_data.n_dups = insn_data[icode].n_dups;
2802 
2803       insn_extract (insn);
2804 
2805       for (i = 0; i < noperands; i++)
2806           {
2807             recog_data.constraints[i] = insn_data[icode].operand[i].constraint;
2808             recog_data.is_operator[i] = insn_data[icode].operand[i].is_operator;
2809             recog_data.operand_mode[i] = insn_data[icode].operand[i].mode;
2810             /* VOIDmode match_operands gets mode from their real operand.  */
2811             if (recog_data.operand_mode[i] == VOIDmode)
2812               recog_data.operand_mode[i] = GET_MODE (recog_data.operand[i]);
2813           }
2814     }
2815   for (i = 0; i < noperands; i++)
2816     recog_data.operand_type[i]
2817       = (recog_data.constraints[i][0] == '=' ? OP_OUT
2818            : recog_data.constraints[i][0] == '+' ? OP_INOUT
2819            : OP_IN);
2820 
2821   gcc_assert (recog_data.n_alternatives <= MAX_RECOG_ALTERNATIVES);
2822 
2823   recog_data.insn = NULL;
2824   which_alternative = -1;
2825 }
2826 
2827 /* Fill in OP_ALT_BASE for an instruction that has N_OPERANDS
2828    operands, N_ALTERNATIVES alternatives and constraint strings
2829    CONSTRAINTS.  OP_ALT_BASE has N_ALTERNATIVES * N_OPERANDS entries
2830    and CONSTRAINTS has N_OPERANDS entries.  OPLOC should be passed in
2831    if the insn is an asm statement and preprocessing should take the
2832    asm operands into account, e.g. to determine whether they could be
2833    addresses in constraints that require addresses; it should then
2834    point to an array of pointers to each operand.  */
2835 
2836 void
preprocess_constraints(int n_operands,int n_alternatives,const char ** constraints,operand_alternative * op_alt_base,rtx ** oploc)2837 preprocess_constraints (int n_operands, int n_alternatives,
2838                               const char **constraints,
2839                               operand_alternative *op_alt_base,
2840                               rtx **oploc)
2841 {
2842   for (int i = 0; i < n_operands; i++)
2843     {
2844       int j;
2845       struct operand_alternative *op_alt;
2846       const char *p = constraints[i];
2847 
2848       op_alt = op_alt_base;
2849 
2850       for (j = 0; j < n_alternatives; j++, op_alt += n_operands)
2851           {
2852             op_alt[i].cl = NO_REGS;
2853             op_alt[i].constraint = p;
2854             op_alt[i].matches = -1;
2855             op_alt[i].matched = -1;
2856 
2857             if (*p == '\0' || *p == ',')
2858               {
2859                 op_alt[i].anything_ok = 1;
2860                 continue;
2861               }
2862 
2863             for (;;)
2864               {
2865                 char c = *p;
2866                 if (c == '#')
2867                     do
2868                       c = *++p;
2869                     while (c != ',' && c != '\0');
2870                 if (c == ',' || c == '\0')
2871                     {
2872                       p++;
2873                       break;
2874                     }
2875 
2876                 switch (c)
2877                     {
2878                     case '?':
2879                       op_alt[i].reject += 6;
2880                       break;
2881                     case '!':
2882                       op_alt[i].reject += 600;
2883                       break;
2884                     case '&':
2885                       op_alt[i].earlyclobber = 1;
2886                       break;
2887 
2888                     case '0': case '1': case '2': case '3': case '4':
2889                     case '5': case '6': case '7': case '8': case '9':
2890                       {
2891                         char *end;
2892                         op_alt[i].matches = strtoul (p, &end, 10);
2893                         op_alt[op_alt[i].matches].matched = i;
2894                         p = end;
2895                       }
2896                       continue;
2897 
2898                     case 'X':
2899                       op_alt[i].anything_ok = 1;
2900                       break;
2901 
2902                     case 'g':
2903                       op_alt[i].cl =
2904                        reg_class_subunion[(int) op_alt[i].cl][(int) GENERAL_REGS];
2905                       break;
2906 
2907                     default:
2908                       enum constraint_num cn = lookup_constraint (p);
2909                       enum reg_class cl;
2910                       switch (get_constraint_type (cn))
2911                         {
2912                         case CT_REGISTER:
2913                           cl = reg_class_for_constraint (cn);
2914                           if (cl != NO_REGS)
2915                               op_alt[i].cl = reg_class_subunion[op_alt[i].cl][cl];
2916                           break;
2917 
2918                         case CT_CONST_INT:
2919                           break;
2920 
2921                         case CT_MEMORY:
2922                         case CT_SPECIAL_MEMORY:
2923                         case CT_RELAXED_MEMORY:
2924                           op_alt[i].memory_ok = 1;
2925                           break;
2926 
2927                         case CT_ADDRESS:
2928                           if (oploc && !address_operand (*oploc[i], VOIDmode))
2929                               break;
2930 
2931                           op_alt[i].is_address = 1;
2932                           op_alt[i].cl
2933                               = (reg_class_subunion
2934                                  [(int) op_alt[i].cl]
2935                                  [(int) base_reg_class (VOIDmode, ADDR_SPACE_GENERIC,
2936                                                               ADDRESS, SCRATCH)]);
2937                           break;
2938 
2939                         case CT_FIXED_FORM:
2940                           break;
2941                         }
2942                       break;
2943                     }
2944                 p += CONSTRAINT_LEN (c, p);
2945               }
2946           }
2947     }
2948 }
2949 
2950 /* Return an array of operand_alternative instructions for
2951    instruction ICODE.  */
2952 
2953 const operand_alternative *
preprocess_insn_constraints(unsigned int icode)2954 preprocess_insn_constraints (unsigned int icode)
2955 {
2956   gcc_checking_assert (IN_RANGE (icode, 0, NUM_INSN_CODES - 1));
2957   if (this_target_recog->x_op_alt[icode])
2958     return this_target_recog->x_op_alt[icode];
2959 
2960   int n_operands = insn_data[icode].n_operands;
2961   if (n_operands == 0)
2962     return 0;
2963   /* Always provide at least one alternative so that which_op_alt ()
2964      works correctly.  If the instruction has 0 alternatives (i.e. all
2965      constraint strings are empty) then each operand in this alternative
2966      will have anything_ok set.  */
2967   int n_alternatives = MAX (insn_data[icode].n_alternatives, 1);
2968   int n_entries = n_operands * n_alternatives;
2969 
2970   operand_alternative *op_alt = XCNEWVEC (operand_alternative, n_entries);
2971   const char **constraints = XALLOCAVEC (const char *, n_operands);
2972 
2973   for (int i = 0; i < n_operands; ++i)
2974     constraints[i] = insn_data[icode].operand[i].constraint;
2975   preprocess_constraints (n_operands, n_alternatives, constraints, op_alt,
2976                                 NULL);
2977 
2978   this_target_recog->x_op_alt[icode] = op_alt;
2979   return op_alt;
2980 }
2981 
2982 /* After calling extract_insn, you can use this function to extract some
2983    information from the constraint strings into a more usable form.
2984    The collected data is stored in recog_op_alt.  */
2985 
2986 void
preprocess_constraints(rtx_insn * insn)2987 preprocess_constraints (rtx_insn *insn)
2988 {
2989   int icode = INSN_CODE (insn);
2990   if (icode >= 0)
2991     recog_op_alt = preprocess_insn_constraints (icode);
2992   else
2993     {
2994       int n_operands = recog_data.n_operands;
2995       int n_alternatives = recog_data.n_alternatives;
2996       int n_entries = n_operands * n_alternatives;
2997       memset (asm_op_alt, 0, n_entries * sizeof (operand_alternative));
2998       preprocess_constraints (n_operands, n_alternatives,
2999                                     recog_data.constraints, asm_op_alt,
3000                                     NULL);
3001       recog_op_alt = asm_op_alt;
3002     }
3003 }
3004 
3005 /* Check the operands of an insn against the insn's operand constraints
3006    and return 1 if they match any of the alternatives in ALTERNATIVES.
3007 
3008    The information about the insn's operands, constraints, operand modes
3009    etc. is obtained from the global variables set up by extract_insn.
3010 
3011    WHICH_ALTERNATIVE is set to a number which indicates which
3012    alternative of constraints was matched: 0 for the first alternative,
3013    1 for the next, etc.
3014 
3015    In addition, when two operands are required to match
3016    and it happens that the output operand is (reg) while the
3017    input operand is --(reg) or ++(reg) (a pre-inc or pre-dec),
3018    make the output operand look like the input.
3019    This is because the output operand is the one the template will print.
3020 
3021    This is used in final, just before printing the assembler code and by
3022    the routines that determine an insn's attribute.
3023 
3024    If STRICT is a positive nonzero value, it means that we have been
3025    called after reload has been completed.  In that case, we must
3026    do all checks strictly.  If it is zero, it means that we have been called
3027    before reload has completed.  In that case, we first try to see if we can
3028    find an alternative that matches strictly.  If not, we try again, this
3029    time assuming that reload will fix up the insn.  This provides a "best
3030    guess" for the alternative and is used to compute attributes of insns prior
3031    to reload.  A negative value of STRICT is used for this internal call.  */
3032 
3033 struct funny_match
3034 {
3035   int this_op, other;
3036 };
3037 
3038 int
constrain_operands(int strict,alternative_mask alternatives)3039 constrain_operands (int strict, alternative_mask alternatives)
3040 {
3041   const char *constraints[MAX_RECOG_OPERANDS];
3042   int matching_operands[MAX_RECOG_OPERANDS];
3043   int earlyclobber[MAX_RECOG_OPERANDS];
3044   int c;
3045 
3046   struct funny_match funny_match[MAX_RECOG_OPERANDS];
3047   int funny_match_index;
3048 
3049   which_alternative = 0;
3050   if (recog_data.n_operands == 0 || recog_data.n_alternatives == 0)
3051     return 1;
3052 
3053   for (c = 0; c < recog_data.n_operands; c++)
3054     constraints[c] = recog_data.constraints[c];
3055 
3056   do
3057     {
3058       int seen_earlyclobber_at = -1;
3059       int opno;
3060       int lose = 0;
3061       funny_match_index = 0;
3062 
3063       if (!TEST_BIT (alternatives, which_alternative))
3064           {
3065             int i;
3066 
3067             for (i = 0; i < recog_data.n_operands; i++)
3068               constraints[i] = skip_alternative (constraints[i]);
3069 
3070             which_alternative++;
3071             continue;
3072           }
3073 
3074       for (opno = 0; opno < recog_data.n_operands; opno++)
3075           matching_operands[opno] = -1;
3076 
3077       for (opno = 0; opno < recog_data.n_operands; opno++)
3078           {
3079             rtx op = recog_data.operand[opno];
3080             machine_mode mode = GET_MODE (op);
3081             const char *p = constraints[opno];
3082             int offset = 0;
3083             int win = 0;
3084             int val;
3085             int len;
3086 
3087             earlyclobber[opno] = 0;
3088 
3089             /* A unary operator may be accepted by the predicate, but it
3090                is irrelevant for matching constraints.  */
3091             /* For special_memory_operand, there could be a memory operand inside,
3092                and it would cause a mismatch for constraint_satisfied_p.  */
3093             if (UNARY_P (op) && op == extract_mem_from_operand (op))
3094               op = XEXP (op, 0);
3095 
3096             if (GET_CODE (op) == SUBREG)
3097               {
3098                 if (REG_P (SUBREG_REG (op))
3099                       && REGNO (SUBREG_REG (op)) < FIRST_PSEUDO_REGISTER)
3100                     offset = subreg_regno_offset (REGNO (SUBREG_REG (op)),
3101                                                         GET_MODE (SUBREG_REG (op)),
3102                                                         SUBREG_BYTE (op),
3103                                                         GET_MODE (op));
3104                 op = SUBREG_REG (op);
3105               }
3106 
3107             /* An empty constraint or empty alternative
3108                allows anything which matched the pattern.  */
3109             if (*p == 0 || *p == ',')
3110               win = 1;
3111 
3112             do
3113               switch (c = *p, len = CONSTRAINT_LEN (c, p), c)
3114                 {
3115                 case '\0':
3116                     len = 0;
3117                     break;
3118                 case ',':
3119                     c = '\0';
3120                     break;
3121 
3122                 case '#':
3123                     /* Ignore rest of this alternative as far as
3124                        constraint checking is concerned.  */
3125                     do
3126                       p++;
3127                     while (*p && *p != ',');
3128                     len = 0;
3129                     break;
3130 
3131                 case '&':
3132                     earlyclobber[opno] = 1;
3133                     if (seen_earlyclobber_at < 0)
3134                       seen_earlyclobber_at = opno;
3135                     break;
3136 
3137                 case '0':  case '1':  case '2':  case '3':  case '4':
3138                 case '5':  case '6':  case '7':  case '8':  case '9':
3139                     {
3140                       /* This operand must be the same as a previous one.
3141                          This kind of constraint is used for instructions such
3142                          as add when they take only two operands.
3143 
3144                          Note that the lower-numbered operand is passed first.
3145 
3146                          If we are not testing strictly, assume that this
3147                          constraint will be satisfied.  */
3148 
3149                       char *end;
3150                       int match;
3151 
3152                       match = strtoul (p, &end, 10);
3153                       p = end;
3154 
3155                       if (strict < 0)
3156                         val = 1;
3157                       else
3158                         {
3159                           rtx op1 = recog_data.operand[match];
3160                           rtx op2 = recog_data.operand[opno];
3161 
3162                           /* A unary operator may be accepted by the predicate,
3163                                but it is irrelevant for matching constraints.  */
3164                           if (UNARY_P (op1))
3165                               op1 = XEXP (op1, 0);
3166                           if (UNARY_P (op2))
3167                               op2 = XEXP (op2, 0);
3168 
3169                           val = operands_match_p (op1, op2);
3170                         }
3171 
3172                       matching_operands[opno] = match;
3173                       matching_operands[match] = opno;
3174 
3175                       if (val != 0)
3176                         win = 1;
3177 
3178                       /* If output is *x and input is *--x, arrange later
3179                          to change the output to *--x as well, since the
3180                          output op is the one that will be printed.  */
3181                       if (val == 2 && strict > 0)
3182                         {
3183                           funny_match[funny_match_index].this_op = opno;
3184                           funny_match[funny_match_index++].other = match;
3185                         }
3186                     }
3187                     len = 0;
3188                     break;
3189 
3190                 case 'p':
3191                     /* p is used for address_operands.  When we are called by
3192                        gen_reload, no one will have checked that the address is
3193                        strictly valid, i.e., that all pseudos requiring hard regs
3194                        have gotten them.  We also want to make sure we have a
3195                        valid mode.  */
3196                     if ((GET_MODE (op) == VOIDmode
3197                          || SCALAR_INT_MODE_P (GET_MODE (op)))
3198                         && (strict <= 0
3199                               || (strict_memory_address_p
3200                                    (recog_data.operand_mode[opno], op))))
3201                       win = 1;
3202                     break;
3203 
3204                     /* No need to check general_operand again;
3205                        it was done in insn-recog.cc.  Well, except that reload
3206                        doesn't check the validity of its replacements, but
3207                        that should only matter when there's a bug.  */
3208                 case 'g':
3209                     /* Anything goes unless it is a REG and really has a hard reg
3210                        but the hard reg is not in the class GENERAL_REGS.  */
3211                     if (REG_P (op))
3212                       {
3213                         if (strict < 0
3214                               || GENERAL_REGS == ALL_REGS
3215                               || (reload_in_progress
3216                                   && REGNO (op) >= FIRST_PSEUDO_REGISTER)
3217                               || reg_fits_class_p (op, GENERAL_REGS, offset, mode))
3218                           win = 1;
3219                       }
3220                     else if (strict < 0 || general_operand (op, mode))
3221                       win = 1;
3222                     break;
3223 
3224                 default:
3225                     {
3226                       enum constraint_num cn = lookup_constraint (p);
3227                       enum reg_class cl = reg_class_for_constraint (cn);
3228                       if (cl != NO_REGS)
3229                         {
3230                           if (strict < 0
3231                                 || (strict == 0
3232                                     && REG_P (op)
3233                                     && REGNO (op) >= FIRST_PSEUDO_REGISTER)
3234                                 || (strict == 0 && GET_CODE (op) == SCRATCH)
3235                                 || (REG_P (op)
3236                                     && reg_fits_class_p (op, cl, offset, mode)))
3237                             win = 1;
3238                         }
3239 
3240                       else if (constraint_satisfied_p (op, cn))
3241                         win = 1;
3242 
3243                       else if (insn_extra_memory_constraint (cn)
3244                                  /* Every memory operand can be reloaded to fit.  */
3245                                  && ((strict < 0 && MEM_P (op))
3246                                      /* Before reload, accept what reload can turn
3247                                           into a mem.  */
3248                                      || (strict < 0 && CONSTANT_P (op))
3249                                      /* Before reload, accept a pseudo or hard register,
3250                                           since LRA can turn it into a mem.  */
3251                                      || (strict < 0 && targetm.lra_p () && REG_P (op))
3252                                      /* During reload, accept a pseudo  */
3253                                      || (reload_in_progress && REG_P (op)
3254                                            && REGNO (op) >= FIRST_PSEUDO_REGISTER)))
3255                         win = 1;
3256                       else if (insn_extra_address_constraint (cn)
3257                                  /* Every address operand can be reloaded to fit.  */
3258                                  && strict < 0)
3259                         win = 1;
3260                       /* Cater to architectures like IA-64 that define extra memory
3261                          constraints without using define_memory_constraint.  */
3262                       else if (reload_in_progress
3263                                  && REG_P (op)
3264                                  && REGNO (op) >= FIRST_PSEUDO_REGISTER
3265                                  && reg_renumber[REGNO (op)] < 0
3266                                  && reg_equiv_mem (REGNO (op)) != 0
3267                                  && constraint_satisfied_p
3268                                     (reg_equiv_mem (REGNO (op)), cn))
3269                         win = 1;
3270                       break;
3271                     }
3272                 }
3273             while (p += len, c);
3274 
3275             constraints[opno] = p;
3276             /* If this operand did not win somehow,
3277                this alternative loses.  */
3278             if (! win)
3279               lose = 1;
3280           }
3281       /* This alternative won; the operands are ok.
3282            Change whichever operands this alternative says to change.  */
3283       if (! lose)
3284           {
3285             int opno, eopno;
3286 
3287             /* See if any earlyclobber operand conflicts with some other
3288                operand.  */
3289 
3290             if (strict > 0  && seen_earlyclobber_at >= 0)
3291               for (eopno = seen_earlyclobber_at;
3292                      eopno < recog_data.n_operands;
3293                      eopno++)
3294                 /* Ignore earlyclobber operands now in memory,
3295                      because we would often report failure when we have
3296                      two memory operands, one of which was formerly a REG.  */
3297                 if (earlyclobber[eopno]
3298                       && REG_P (recog_data.operand[eopno]))
3299                     for (opno = 0; opno < recog_data.n_operands; opno++)
3300                       if ((MEM_P (recog_data.operand[opno])
3301                            || recog_data.operand_type[opno] != OP_OUT)
3302                           && opno != eopno
3303                           /* Ignore things like match_operator operands.  */
3304                           && *recog_data.constraints[opno] != 0
3305                           && ! (matching_operands[opno] == eopno
3306                                   && operands_match_p (recog_data.operand[opno],
3307                                                              recog_data.operand[eopno]))
3308                           && ! safe_from_earlyclobber (recog_data.operand[opno],
3309                                                                recog_data.operand[eopno]))
3310                         lose = 1;
3311 
3312             if (! lose)
3313               {
3314                 while (--funny_match_index >= 0)
3315                     {
3316                       recog_data.operand[funny_match[funny_match_index].other]
3317                         = recog_data.operand[funny_match[funny_match_index].this_op];
3318                     }
3319 
3320                 /* For operands without < or > constraints reject side-effects.  */
3321                 if (AUTO_INC_DEC && recog_data.is_asm)
3322                     {
3323                       for (opno = 0; opno < recog_data.n_operands; opno++)
3324                         if (MEM_P (recog_data.operand[opno]))
3325                           switch (GET_CODE (XEXP (recog_data.operand[opno], 0)))
3326                               {
3327                               case PRE_INC:
3328                               case POST_INC:
3329                               case PRE_DEC:
3330                               case POST_DEC:
3331                               case PRE_MODIFY:
3332                               case POST_MODIFY:
3333                                 if (strchr (recog_data.constraints[opno], '<') == NULL
3334                                     && strchr (recog_data.constraints[opno], '>')
3335                                          == NULL)
3336                                   return 0;
3337                                 break;
3338                               default:
3339                                 break;
3340                               }
3341                     }
3342 
3343                 return 1;
3344               }
3345           }
3346 
3347       which_alternative++;
3348     }
3349   while (which_alternative < recog_data.n_alternatives);
3350 
3351   which_alternative = -1;
3352   /* If we are about to reject this, but we are not to test strictly,
3353      try a very loose test.  Only return failure if it fails also.  */
3354   if (strict == 0)
3355     return constrain_operands (-1, alternatives);
3356   else
3357     return 0;
3358 }
3359 
3360 /* Return true iff OPERAND (assumed to be a REG rtx)
3361    is a hard reg in class CLASS when its regno is offset by OFFSET
3362    and changed to mode MODE.
3363    If REG occupies multiple hard regs, all of them must be in CLASS.  */
3364 
3365 bool
reg_fits_class_p(const_rtx operand,reg_class_t cl,int offset,machine_mode mode)3366 reg_fits_class_p (const_rtx operand, reg_class_t cl, int offset,
3367                       machine_mode mode)
3368 {
3369   unsigned int regno = REGNO (operand);
3370 
3371   if (cl == NO_REGS)
3372     return false;
3373 
3374   /* Regno must not be a pseudo register.  Offset may be negative.  */
3375   return (HARD_REGISTER_NUM_P (regno)
3376             && HARD_REGISTER_NUM_P (regno + offset)
3377             && in_hard_reg_set_p (reg_class_contents[(int) cl], mode,
3378                                         regno + offset));
3379 }
3380 
3381 /* Split single instruction.  Helper function for split_all_insns and
3382    split_all_insns_noflow.  Return last insn in the sequence if successful,
3383    or NULL if unsuccessful.  */
3384 
3385 static rtx_insn *
split_insn(rtx_insn * insn)3386 split_insn (rtx_insn *insn)
3387 {
3388   /* Split insns here to get max fine-grain parallelism.  */
3389   rtx_insn *first = PREV_INSN (insn);
3390   rtx_insn *last = try_split (PATTERN (insn), insn, 1);
3391   rtx insn_set, last_set, note;
3392 
3393   if (last == insn)
3394     return NULL;
3395 
3396   /* If the original instruction was a single set that was known to be
3397      equivalent to a constant, see if we can say the same about the last
3398      instruction in the split sequence.  The two instructions must set
3399      the same destination.  */
3400   insn_set = single_set (insn);
3401   if (insn_set)
3402     {
3403       last_set = single_set (last);
3404       if (last_set && rtx_equal_p (SET_DEST (last_set), SET_DEST (insn_set)))
3405           {
3406             note = find_reg_equal_equiv_note (insn);
3407             if (note && CONSTANT_P (XEXP (note, 0)))
3408               set_unique_reg_note (last, REG_EQUAL, XEXP (note, 0));
3409             else if (CONSTANT_P (SET_SRC (insn_set)))
3410               set_unique_reg_note (last, REG_EQUAL,
3411                                          copy_rtx (SET_SRC (insn_set)));
3412           }
3413     }
3414 
3415   /* try_split returns the NOTE that INSN became.  */
3416   SET_INSN_DELETED (insn);
3417 
3418   /* ??? Coddle to md files that generate subregs in post-reload
3419      splitters instead of computing the proper hard register.  */
3420   if (reload_completed && first != last)
3421     {
3422       first = NEXT_INSN (first);
3423       for (;;)
3424           {
3425             if (INSN_P (first))
3426               cleanup_subreg_operands (first);
3427             if (first == last)
3428               break;
3429             first = NEXT_INSN (first);
3430           }
3431     }
3432 
3433   return last;
3434 }
3435 
3436 /* Split all insns in the function.  If UPD_LIFE, update life info after.  */
3437 
3438 void
split_all_insns(void)3439 split_all_insns (void)
3440 {
3441   bool changed;
3442   bool need_cfg_cleanup = false;
3443   basic_block bb;
3444 
3445   auto_sbitmap blocks (last_basic_block_for_fn (cfun));
3446   bitmap_clear (blocks);
3447   changed = false;
3448 
3449   FOR_EACH_BB_REVERSE_FN (bb, cfun)
3450     {
3451       rtx_insn *insn, *next;
3452       bool finish = false;
3453 
3454       rtl_profile_for_bb (bb);
3455       for (insn = BB_HEAD (bb); !finish ; insn = next)
3456           {
3457             /* Can't use `next_real_insn' because that might go across
3458                CODE_LABELS and short-out basic blocks.  */
3459             next = NEXT_INSN (insn);
3460             finish = (insn == BB_END (bb));
3461 
3462             /* If INSN has a REG_EH_REGION note and we split INSN, the
3463                resulting split may not have/need REG_EH_REGION notes.
3464 
3465                If that happens and INSN was the last reference to the
3466                given EH region, then the EH region will become unreachable.
3467                We cannot leave the unreachable blocks in the CFG as that
3468                will trigger a checking failure.
3469 
3470                So track if INSN has a REG_EH_REGION note.  If so and we
3471                split INSN, then trigger a CFG cleanup.  */
3472             rtx note = find_reg_note (insn, REG_EH_REGION, NULL_RTX);
3473             if (INSN_P (insn))
3474               {
3475                 rtx set = single_set (insn);
3476 
3477                 /* Don't split no-op move insns.  These should silently
3478                      disappear later in final.  Splitting such insns would
3479                      break the code that handles LIBCALL blocks.  */
3480                 if (set && set_noop_p (set))
3481                     {
3482                       /* Nops get in the way while scheduling, so delete them
3483                          now if register allocation has already been done.  It
3484                          is too risky to try to do this before register
3485                          allocation, and there are unlikely to be very many
3486                          nops then anyways.  */
3487                       if (reload_completed)
3488                           delete_insn_and_edges (insn);
3489                       if (note)
3490                         need_cfg_cleanup = true;
3491                     }
3492                 else
3493                     {
3494                       if (split_insn (insn))
3495                         {
3496                           bitmap_set_bit (blocks, bb->index);
3497                           changed = true;
3498                           if (note)
3499                               need_cfg_cleanup = true;
3500                         }
3501                     }
3502               }
3503           }
3504     }
3505 
3506   default_rtl_profile ();
3507   if (changed)
3508     {
3509       find_many_sub_basic_blocks (blocks);
3510 
3511       /* Splitting could drop an REG_EH_REGION if it potentially
3512            trapped in its original form, but does not in its split
3513            form.  Consider a FLOAT_TRUNCATE which splits into a memory
3514            store/load pair and -fnon-call-exceptions.  */
3515       if (need_cfg_cleanup)
3516           cleanup_cfg (0);
3517     }
3518 
3519   checking_verify_flow_info ();
3520 }
3521 
3522 /* Same as split_all_insns, but do not expect CFG to be available.
3523    Used by machine dependent reorg passes.  */
3524 
3525 unsigned int
split_all_insns_noflow(void)3526 split_all_insns_noflow (void)
3527 {
3528   rtx_insn *next, *insn;
3529 
3530   for (insn = get_insns (); insn; insn = next)
3531     {
3532       next = NEXT_INSN (insn);
3533       if (INSN_P (insn))
3534           {
3535             /* Don't split no-op move insns.  These should silently
3536                disappear later in final.  Splitting such insns would
3537                break the code that handles LIBCALL blocks.  */
3538             rtx set = single_set (insn);
3539             if (set && set_noop_p (set))
3540               {
3541                 /* Nops get in the way while scheduling, so delete them
3542                      now if register allocation has already been done.  It
3543                      is too risky to try to do this before register
3544                      allocation, and there are unlikely to be very many
3545                      nops then anyways.
3546 
3547                      ??? Should we use delete_insn when the CFG isn't valid?  */
3548                 if (reload_completed)
3549                     delete_insn_and_edges (insn);
3550               }
3551             else
3552               split_insn (insn);
3553           }
3554     }
3555   return 0;
3556 }
3557 
3558 struct peep2_insn_data
3559 {
3560   rtx_insn *insn;
3561   regset live_before;
3562 };
3563 
3564 static struct peep2_insn_data peep2_insn_data[MAX_INSNS_PER_PEEP2 + 1];
3565 static int peep2_current;
3566 
3567 static bool peep2_do_rebuild_jump_labels;
3568 static bool peep2_do_cleanup_cfg;
3569 
3570 /* The number of instructions available to match a peep2.  */
3571 int peep2_current_count;
3572 
3573 /* A marker indicating the last insn of the block.  The live_before regset
3574    for this element is correct, indicating DF_LIVE_OUT for the block.  */
3575 #define PEEP2_EOB invalid_insn_rtx
3576 
3577 /* Wrap N to fit into the peep2_insn_data buffer.  */
3578 
3579 static int
peep2_buf_position(int n)3580 peep2_buf_position (int n)
3581 {
3582   if (n >= MAX_INSNS_PER_PEEP2 + 1)
3583     n -= MAX_INSNS_PER_PEEP2 + 1;
3584   return n;
3585 }
3586 
3587 /* Return the Nth non-note insn after `current', or return NULL_RTX if it
3588    does not exist.  Used by the recognizer to find the next insn to match
3589    in a multi-insn pattern.  */
3590 
3591 rtx_insn *
peep2_next_insn(int n)3592 peep2_next_insn (int n)
3593 {
3594   gcc_assert (n <= peep2_current_count);
3595 
3596   n = peep2_buf_position (peep2_current + n);
3597 
3598   return peep2_insn_data[n].insn;
3599 }
3600 
3601 /* Return true if REGNO is dead before the Nth non-note insn
3602    after `current'.  */
3603 
3604 int
peep2_regno_dead_p(int ofs,int regno)3605 peep2_regno_dead_p (int ofs, int regno)
3606 {
3607   gcc_assert (ofs < MAX_INSNS_PER_PEEP2 + 1);
3608 
3609   ofs = peep2_buf_position (peep2_current + ofs);
3610 
3611   gcc_assert (peep2_insn_data[ofs].insn != NULL_RTX);
3612 
3613   return ! REGNO_REG_SET_P (peep2_insn_data[ofs].live_before, regno);
3614 }
3615 
3616 /* Similarly for a REG.  */
3617 
3618 int
peep2_reg_dead_p(int ofs,rtx reg)3619 peep2_reg_dead_p (int ofs, rtx reg)
3620 {
3621   gcc_assert (ofs < MAX_INSNS_PER_PEEP2 + 1);
3622 
3623   ofs = peep2_buf_position (peep2_current + ofs);
3624 
3625   gcc_assert (peep2_insn_data[ofs].insn != NULL_RTX);
3626 
3627   unsigned int end_regno = END_REGNO (reg);
3628   for (unsigned int regno = REGNO (reg); regno < end_regno; ++regno)
3629     if (REGNO_REG_SET_P (peep2_insn_data[ofs].live_before, regno))
3630       return 0;
3631   return 1;
3632 }
3633 
3634 /* Regno offset to be used in the register search.  */
3635 static int search_ofs;
3636 
3637 /* Try to find a hard register of mode MODE, matching the register class in
3638    CLASS_STR, which is available at the beginning of insn CURRENT_INSN and
3639    remains available until the end of LAST_INSN.  LAST_INSN may be NULL_RTX,
3640    in which case the only condition is that the register must be available
3641    before CURRENT_INSN.
3642    Registers that already have bits set in REG_SET will not be considered.
3643 
3644    If an appropriate register is available, it will be returned and the
3645    corresponding bit(s) in REG_SET will be set; otherwise, NULL_RTX is
3646    returned.  */
3647 
3648 rtx
peep2_find_free_register(int from,int to,const char * class_str,machine_mode mode,HARD_REG_SET * reg_set)3649 peep2_find_free_register (int from, int to, const char *class_str,
3650                                 machine_mode mode, HARD_REG_SET *reg_set)
3651 {
3652   enum reg_class cl;
3653   HARD_REG_SET live;
3654   df_ref def;
3655   int i;
3656 
3657   gcc_assert (from < MAX_INSNS_PER_PEEP2 + 1);
3658   gcc_assert (to < MAX_INSNS_PER_PEEP2 + 1);
3659 
3660   from = peep2_buf_position (peep2_current + from);
3661   to = peep2_buf_position (peep2_current + to);
3662 
3663   gcc_assert (peep2_insn_data[from].insn != NULL_RTX);
3664   REG_SET_TO_HARD_REG_SET (live, peep2_insn_data[from].live_before);
3665 
3666   while (from != to)
3667     {
3668       gcc_assert (peep2_insn_data[from].insn != NULL_RTX);
3669 
3670       /* Don't use registers set or clobbered by the insn.  */
3671       FOR_EACH_INSN_DEF (def, peep2_insn_data[from].insn)
3672           SET_HARD_REG_BIT (live, DF_REF_REGNO (def));
3673 
3674       from = peep2_buf_position (from + 1);
3675     }
3676 
3677   cl = reg_class_for_constraint (lookup_constraint (class_str));
3678 
3679   for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
3680     {
3681       int raw_regno, regno, success, j;
3682 
3683       /* Distribute the free registers as much as possible.  */
3684       raw_regno = search_ofs + i;
3685       if (raw_regno >= FIRST_PSEUDO_REGISTER)
3686           raw_regno -= FIRST_PSEUDO_REGISTER;
3687 #ifdef REG_ALLOC_ORDER
3688       regno = reg_alloc_order[raw_regno];
3689 #else
3690       regno = raw_regno;
3691 #endif
3692 
3693       /* Can it support the mode we need?  */
3694       if (!targetm.hard_regno_mode_ok (regno, mode))
3695           continue;
3696 
3697       success = 1;
3698       for (j = 0; success && j < hard_regno_nregs (regno, mode); j++)
3699           {
3700             /* Don't allocate fixed registers.  */
3701             if (fixed_regs[regno + j])
3702               {
3703                 success = 0;
3704                 break;
3705               }
3706             /* Don't allocate global registers.  */
3707             if (global_regs[regno + j])
3708               {
3709                 success = 0;
3710                 break;
3711               }
3712             /* Make sure the register is of the right class.  */
3713             if (! TEST_HARD_REG_BIT (reg_class_contents[cl], regno + j))
3714               {
3715                 success = 0;
3716                 break;
3717               }
3718             /* And that we don't create an extra save/restore.  */
3719             if (! crtl->abi->clobbers_full_reg_p (regno + j)
3720                 && ! df_regs_ever_live_p (regno + j))
3721               {
3722                 success = 0;
3723                 break;
3724               }
3725 
3726             if (! targetm.hard_regno_scratch_ok (regno + j))
3727               {
3728                 success = 0;
3729                 break;
3730               }
3731 
3732             /* And we don't clobber traceback for noreturn functions.  */
3733             if ((regno + j == FRAME_POINTER_REGNUM
3734                  || regno + j == HARD_FRAME_POINTER_REGNUM)
3735                 && (! reload_completed || frame_pointer_needed))
3736               {
3737                 success = 0;
3738                 break;
3739               }
3740 
3741             if (TEST_HARD_REG_BIT (*reg_set, regno + j)
3742                 || TEST_HARD_REG_BIT (live, regno + j))
3743               {
3744                 success = 0;
3745                 break;
3746               }
3747           }
3748 
3749       if (success)
3750           {
3751             add_to_hard_reg_set (reg_set, mode, regno);
3752 
3753             /* Start the next search with the next register.  */
3754             if (++raw_regno >= FIRST_PSEUDO_REGISTER)
3755               raw_regno = 0;
3756             search_ofs = raw_regno;
3757 
3758             return gen_rtx_REG (mode, regno);
3759           }
3760     }
3761 
3762   search_ofs = 0;
3763   return NULL_RTX;
3764 }
3765 
3766 /* Forget all currently tracked instructions, only remember current
3767    LIVE regset.  */
3768 
3769 static void
peep2_reinit_state(regset live)3770 peep2_reinit_state (regset live)
3771 {
3772   int i;
3773 
3774   /* Indicate that all slots except the last holds invalid data.  */
3775   for (i = 0; i < MAX_INSNS_PER_PEEP2; ++i)
3776     peep2_insn_data[i].insn = NULL;
3777   peep2_current_count = 0;
3778 
3779   /* Indicate that the last slot contains live_after data.  */
3780   peep2_insn_data[MAX_INSNS_PER_PEEP2].insn = PEEP2_EOB;
3781   peep2_current = MAX_INSNS_PER_PEEP2;
3782 
3783   COPY_REG_SET (peep2_insn_data[MAX_INSNS_PER_PEEP2].live_before, live);
3784 }
3785 
3786 /* Copies frame related info of an insn (OLD_INSN) to the single
3787    insn (NEW_INSN) that was obtained by splitting OLD_INSN.  */
3788 
3789 void
copy_frame_info_to_split_insn(rtx_insn * old_insn,rtx_insn * new_insn)3790 copy_frame_info_to_split_insn (rtx_insn *old_insn, rtx_insn *new_insn)
3791 {
3792   bool any_note = false;
3793   rtx note;
3794 
3795   if (!RTX_FRAME_RELATED_P (old_insn))
3796     return;
3797 
3798   RTX_FRAME_RELATED_P (new_insn) = 1;
3799 
3800   /* Allow the backend to fill in a note during the split.  */
3801   for (note = REG_NOTES (new_insn); note ; note = XEXP (note, 1))
3802     switch (REG_NOTE_KIND (note))
3803       {
3804       case REG_FRAME_RELATED_EXPR:
3805       case REG_CFA_DEF_CFA:
3806       case REG_CFA_ADJUST_CFA:
3807       case REG_CFA_OFFSET:
3808       case REG_CFA_REGISTER:
3809       case REG_CFA_EXPRESSION:
3810       case REG_CFA_RESTORE:
3811       case REG_CFA_SET_VDRAP:
3812         any_note = true;
3813         break;
3814       default:
3815         break;
3816       }
3817 
3818   /* If the backend didn't supply a note, copy one over.  */
3819   if (!any_note)
3820     for (note = REG_NOTES (old_insn); note ; note = XEXP (note, 1))
3821       switch (REG_NOTE_KIND (note))
3822         {
3823         case REG_FRAME_RELATED_EXPR:
3824         case REG_CFA_DEF_CFA:
3825         case REG_CFA_ADJUST_CFA:
3826         case REG_CFA_OFFSET:
3827         case REG_CFA_REGISTER:
3828         case REG_CFA_EXPRESSION:
3829         case REG_CFA_RESTORE:
3830         case REG_CFA_SET_VDRAP:
3831           add_reg_note (new_insn, REG_NOTE_KIND (note), XEXP (note, 0));
3832           any_note = true;
3833           break;
3834         default:
3835           break;
3836         }
3837 
3838   /* If there still isn't a note, make sure the unwind info sees the
3839      same expression as before the split.  */
3840   if (!any_note)
3841     {
3842       rtx old_set, new_set;
3843 
3844       /* The old insn had better have been simple, or annotated.  */
3845       old_set = single_set (old_insn);
3846       gcc_assert (old_set != NULL);
3847 
3848       new_set = single_set (new_insn);
3849       if (!new_set || !rtx_equal_p (new_set, old_set))
3850         add_reg_note (new_insn, REG_FRAME_RELATED_EXPR, old_set);
3851     }
3852 
3853   /* Copy prologue/epilogue status.  This is required in order to keep
3854      proper placement of EPILOGUE_BEG and the DW_CFA_remember_state.  */
3855   maybe_copy_prologue_epilogue_insn (old_insn, new_insn);
3856 }
3857 
3858 /* While scanning basic block BB, we found a match of length MATCH_LEN,
3859    starting at INSN.  Perform the replacement, removing the old insns and
3860    replacing them with ATTEMPT.  Returns the last insn emitted, or NULL
3861    if the replacement is rejected.  */
3862 
3863 static rtx_insn *
peep2_attempt(basic_block bb,rtx_insn * insn,int match_len,rtx_insn * attempt)3864 peep2_attempt (basic_block bb, rtx_insn *insn, int match_len, rtx_insn *attempt)
3865 {
3866   int i;
3867   rtx_insn *last, *before_try, *x;
3868   rtx eh_note, as_note;
3869   rtx_insn *old_insn;
3870   rtx_insn *new_insn;
3871   bool was_call = false;
3872 
3873   /* If we are splitting an RTX_FRAME_RELATED_P insn, do not allow it to
3874      match more than one insn, or to be split into more than one insn.  */
3875   old_insn = peep2_insn_data[peep2_current].insn;
3876   if (RTX_FRAME_RELATED_P (old_insn))
3877     {
3878       if (match_len != 0)
3879           return NULL;
3880 
3881       /* Look for one "active" insn.  I.e. ignore any "clobber" insns that
3882            may be in the stream for the purpose of register allocation.  */
3883       if (active_insn_p (attempt))
3884           new_insn = attempt;
3885       else
3886           new_insn = next_active_insn (attempt);
3887       if (next_active_insn (new_insn))
3888           return NULL;
3889 
3890       /* We have a 1-1 replacement.  Copy over any frame-related info.  */
3891       copy_frame_info_to_split_insn (old_insn, new_insn);
3892     }
3893 
3894   /* If we are splitting a CALL_INSN, look for the CALL_INSN
3895      in SEQ and copy our CALL_INSN_FUNCTION_USAGE and other
3896      cfg-related call notes.  */
3897   for (i = 0; i <= match_len; ++i)
3898     {
3899       int j;
3900       rtx note;
3901 
3902       j = peep2_buf_position (peep2_current + i);
3903       old_insn = peep2_insn_data[j].insn;
3904       if (!CALL_P (old_insn))
3905           continue;
3906       was_call = true;
3907 
3908       new_insn = attempt;
3909       while (new_insn != NULL_RTX)
3910           {
3911             if (CALL_P (new_insn))
3912               break;
3913             new_insn = NEXT_INSN (new_insn);
3914           }
3915 
3916       gcc_assert (new_insn != NULL_RTX);
3917 
3918       CALL_INSN_FUNCTION_USAGE (new_insn)
3919           = CALL_INSN_FUNCTION_USAGE (old_insn);
3920       SIBLING_CALL_P (new_insn) = SIBLING_CALL_P (old_insn);
3921 
3922       for (note = REG_NOTES (old_insn);
3923              note;
3924              note = XEXP (note, 1))
3925           switch (REG_NOTE_KIND (note))
3926             {
3927             case REG_NORETURN:
3928             case REG_SETJMP:
3929             case REG_TM:
3930             case REG_CALL_NOCF_CHECK:
3931               add_reg_note (new_insn, REG_NOTE_KIND (note),
3932                                 XEXP (note, 0));
3933               break;
3934             default:
3935               /* Discard all other reg notes.  */
3936               break;
3937             }
3938 
3939       /* Croak if there is another call in the sequence.  */
3940       while (++i <= match_len)
3941           {
3942             j = peep2_buf_position (peep2_current + i);
3943             old_insn = peep2_insn_data[j].insn;
3944             gcc_assert (!CALL_P (old_insn));
3945           }
3946       break;
3947     }
3948 
3949   /* If we matched any instruction that had a REG_ARGS_SIZE, then
3950      move those notes over to the new sequence.  */
3951   as_note = NULL;
3952   for (i = match_len; i >= 0; --i)
3953     {
3954       int j = peep2_buf_position (peep2_current + i);
3955       old_insn = peep2_insn_data[j].insn;
3956 
3957       as_note = find_reg_note (old_insn, REG_ARGS_SIZE, NULL);
3958       if (as_note)
3959           break;
3960     }
3961 
3962   i = peep2_buf_position (peep2_current + match_len);
3963   eh_note = find_reg_note (peep2_insn_data[i].insn, REG_EH_REGION, NULL_RTX);
3964 
3965   /* Replace the old sequence with the new.  */
3966   rtx_insn *peepinsn = peep2_insn_data[i].insn;
3967   last = emit_insn_after_setloc (attempt,
3968                                          peep2_insn_data[i].insn,
3969                                          INSN_LOCATION (peepinsn));
3970   if (JUMP_P (peepinsn) && JUMP_P (last))
3971     CROSSING_JUMP_P (last) = CROSSING_JUMP_P (peepinsn);
3972   before_try = PREV_INSN (insn);
3973   delete_insn_chain (insn, peep2_insn_data[i].insn, false);
3974 
3975   /* Re-insert the EH_REGION notes.  */
3976   if (eh_note || (was_call && nonlocal_goto_handler_labels))
3977     {
3978       edge eh_edge;
3979       edge_iterator ei;
3980 
3981       FOR_EACH_EDGE (eh_edge, ei, bb->succs)
3982           if (eh_edge->flags & (EDGE_EH | EDGE_ABNORMAL_CALL))
3983             break;
3984 
3985       if (eh_note)
3986           copy_reg_eh_region_note_backward (eh_note, last, before_try);
3987 
3988       if (eh_edge)
3989           for (x = last; x != before_try; x = PREV_INSN (x))
3990             if (x != BB_END (bb)
3991                 && (can_throw_internal (x)
3992                       || can_nonlocal_goto (x)))
3993               {
3994                 edge nfte, nehe;
3995                 int flags;
3996 
3997                 nfte = split_block (bb, x);
3998                 flags = (eh_edge->flags
3999                            & (EDGE_EH | EDGE_ABNORMAL));
4000                 if (CALL_P (x))
4001                     flags |= EDGE_ABNORMAL_CALL;
4002                 nehe = make_edge (nfte->src, eh_edge->dest,
4003                                         flags);
4004 
4005                 nehe->probability = eh_edge->probability;
4006                 nfte->probability = nehe->probability.invert ();
4007 
4008                 peep2_do_cleanup_cfg |= purge_dead_edges (nfte->dest);
4009                 bb = nfte->src;
4010                 eh_edge = nehe;
4011               }
4012 
4013       /* Converting possibly trapping insn to non-trapping is
4014            possible.  Zap dummy outgoing edges.  */
4015       peep2_do_cleanup_cfg |= purge_dead_edges (bb);
4016     }
4017 
4018   /* Re-insert the ARGS_SIZE notes.  */
4019   if (as_note)
4020     fixup_args_size_notes (before_try, last, get_args_size (as_note));
4021 
4022   /* Scan the new insns for embedded side effects and add appropriate
4023      REG_INC notes.  */
4024   if (AUTO_INC_DEC)
4025     for (x = last; x != before_try; x = PREV_INSN (x))
4026       if (NONDEBUG_INSN_P (x))
4027           add_auto_inc_notes (x, PATTERN (x));
4028 
4029   /* If we generated a jump instruction, it won't have
4030      JUMP_LABEL set.  Recompute after we're done.  */
4031   for (x = last; x != before_try; x = PREV_INSN (x))
4032     if (JUMP_P (x))
4033       {
4034           peep2_do_rebuild_jump_labels = true;
4035           break;
4036       }
4037 
4038   return last;
4039 }
4040 
4041 /* After performing a replacement in basic block BB, fix up the life
4042    information in our buffer.  LAST is the last of the insns that we
4043    emitted as a replacement.  PREV is the insn before the start of
4044    the replacement.  MATCH_LEN is the number of instructions that were
4045    matched, and which now need to be replaced in the buffer.  */
4046 
4047 static void
peep2_update_life(basic_block bb,int match_len,rtx_insn * last,rtx_insn * prev)4048 peep2_update_life (basic_block bb, int match_len, rtx_insn *last,
4049                        rtx_insn *prev)
4050 {
4051   int i = peep2_buf_position (peep2_current + match_len + 1);
4052   rtx_insn *x;
4053   regset_head live;
4054 
4055   INIT_REG_SET (&live);
4056   COPY_REG_SET (&live, peep2_insn_data[i].live_before);
4057 
4058   gcc_assert (peep2_current_count >= match_len + 1);
4059   peep2_current_count -= match_len + 1;
4060 
4061   x = last;
4062   do
4063     {
4064       if (INSN_P (x))
4065           {
4066             df_insn_rescan (x);
4067             if (peep2_current_count < MAX_INSNS_PER_PEEP2)
4068               {
4069                 peep2_current_count++;
4070                 if (--i < 0)
4071                     i = MAX_INSNS_PER_PEEP2;
4072                 peep2_insn_data[i].insn = x;
4073                 df_simulate_one_insn_backwards (bb, x, &live);
4074                 COPY_REG_SET (peep2_insn_data[i].live_before, &live);
4075               }
4076           }
4077       x = PREV_INSN (x);
4078     }
4079   while (x != prev);
4080   CLEAR_REG_SET (&live);
4081 
4082   peep2_current = i;
4083 }
4084 
4085 /* Add INSN, which is in BB, at the end of the peep2 insn buffer if possible.
4086    Return true if we added it, false otherwise.  The caller will try to match
4087    peepholes against the buffer if we return false; otherwise it will try to
4088    add more instructions to the buffer.  */
4089 
4090 static bool
peep2_fill_buffer(basic_block bb,rtx_insn * insn,regset live)4091 peep2_fill_buffer (basic_block bb, rtx_insn *insn, regset live)
4092 {
4093   int pos;
4094 
4095   /* Once we have filled the maximum number of insns the buffer can hold,
4096      allow the caller to match the insns against peepholes.  We wait until
4097      the buffer is full in case the target has similar peepholes of different
4098      length; we always want to match the longest if possible.  */
4099   if (peep2_current_count == MAX_INSNS_PER_PEEP2)
4100     return false;
4101 
4102   /* If an insn has RTX_FRAME_RELATED_P set, do not allow it to be matched with
4103      any other pattern, lest it change the semantics of the frame info.  */
4104   if (RTX_FRAME_RELATED_P (insn))
4105     {
4106       /* Let the buffer drain first.  */
4107       if (peep2_current_count > 0)
4108           return false;
4109       /* Now the insn will be the only thing in the buffer.  */
4110     }
4111 
4112   pos = peep2_buf_position (peep2_current + peep2_current_count);
4113   peep2_insn_data[pos].insn = insn;
4114   COPY_REG_SET (peep2_insn_data[pos].live_before, live);
4115   peep2_current_count++;
4116 
4117   df_simulate_one_insn_forwards (bb, insn, live);
4118   return true;
4119 }
4120 
4121 /* Perform the peephole2 optimization pass.  */
4122 
4123 static void
peephole2_optimize(void)4124 peephole2_optimize (void)
4125 {
4126   rtx_insn *insn;
4127   bitmap live;
4128   int i;
4129   basic_block bb;
4130 
4131   peep2_do_cleanup_cfg = false;
4132   peep2_do_rebuild_jump_labels = false;
4133 
4134   df_set_flags (DF_LR_RUN_DCE);
4135   df_note_add_problem ();
4136   df_analyze ();
4137 
4138   /* Initialize the regsets we're going to use.  */
4139   for (i = 0; i < MAX_INSNS_PER_PEEP2 + 1; ++i)
4140     peep2_insn_data[i].live_before = BITMAP_ALLOC (&reg_obstack);
4141   search_ofs = 0;
4142   live = BITMAP_ALLOC (&reg_obstack);
4143 
4144   FOR_EACH_BB_REVERSE_FN (bb, cfun)
4145     {
4146       bool past_end = false;
4147       int pos;
4148 
4149       rtl_profile_for_bb (bb);
4150 
4151       /* Start up propagation.  */
4152       bitmap_copy (live, DF_LR_IN (bb));
4153       df_simulate_initialize_forwards (bb, live);
4154       peep2_reinit_state (live);
4155 
4156       insn = BB_HEAD (bb);
4157       for (;;)
4158           {
4159             rtx_insn *attempt, *head;
4160             int match_len;
4161 
4162             if (!past_end && !NONDEBUG_INSN_P (insn))
4163               {
4164               next_insn:
4165                 insn = NEXT_INSN (insn);
4166                 if (insn == NEXT_INSN (BB_END (bb)))
4167                     past_end = true;
4168                 continue;
4169               }
4170             if (!past_end && peep2_fill_buffer (bb, insn, live))
4171               goto next_insn;
4172 
4173             /* If we did not fill an empty buffer, it signals the end of the
4174                block.  */
4175             if (peep2_current_count == 0)
4176               break;
4177 
4178             /* The buffer filled to the current maximum, so try to match.  */
4179 
4180             pos = peep2_buf_position (peep2_current + peep2_current_count);
4181             peep2_insn_data[pos].insn = PEEP2_EOB;
4182             COPY_REG_SET (peep2_insn_data[pos].live_before, live);
4183 
4184             /* Match the peephole.  */
4185             head = peep2_insn_data[peep2_current].insn;
4186             attempt = peephole2_insns (PATTERN (head), head, &match_len);
4187             if (attempt != NULL)
4188               {
4189                 rtx_insn *last = peep2_attempt (bb, head, match_len, attempt);
4190                 if (last)
4191                     {
4192                       peep2_update_life (bb, match_len, last, PREV_INSN (attempt));
4193                       continue;
4194                     }
4195               }
4196 
4197             /* No match: advance the buffer by one insn.  */
4198             peep2_current = peep2_buf_position (peep2_current + 1);
4199             peep2_current_count--;
4200           }
4201     }
4202 
4203   default_rtl_profile ();
4204   for (i = 0; i < MAX_INSNS_PER_PEEP2 + 1; ++i)
4205     BITMAP_FREE (peep2_insn_data[i].live_before);
4206   BITMAP_FREE (live);
4207   if (peep2_do_rebuild_jump_labels)
4208     rebuild_jump_labels (get_insns ());
4209   if (peep2_do_cleanup_cfg)
4210     cleanup_cfg (CLEANUP_CFG_CHANGED);
4211 }
4212 
4213 /* Common predicates for use with define_bypass.  */
4214 
4215 /* Helper function for store_data_bypass_p, handle just a single SET
4216    IN_SET.  */
4217 
4218 static bool
store_data_bypass_p_1(rtx_insn * out_insn,rtx in_set)4219 store_data_bypass_p_1 (rtx_insn *out_insn, rtx in_set)
4220 {
4221   if (!MEM_P (SET_DEST (in_set)))
4222     return false;
4223 
4224   rtx out_set = single_set (out_insn);
4225   if (out_set)
4226     return !reg_mentioned_p (SET_DEST (out_set), SET_DEST (in_set));
4227 
4228   rtx out_pat = PATTERN (out_insn);
4229   if (GET_CODE (out_pat) != PARALLEL)
4230     return false;
4231 
4232   for (int i = 0; i < XVECLEN (out_pat, 0); i++)
4233     {
4234       rtx out_exp = XVECEXP (out_pat, 0, i);
4235 
4236       if (GET_CODE (out_exp) == CLOBBER || GET_CODE (out_exp) == USE)
4237           continue;
4238 
4239       gcc_assert (GET_CODE (out_exp) == SET);
4240 
4241       if (reg_mentioned_p (SET_DEST (out_exp), SET_DEST (in_set)))
4242           return false;
4243     }
4244 
4245   return true;
4246 }
4247 
4248 /* True if the dependency between OUT_INSN and IN_INSN is on the store
4249    data not the address operand(s) of the store.  IN_INSN and OUT_INSN
4250    must be either a single_set or a PARALLEL with SETs inside.  */
4251 
4252 int
store_data_bypass_p(rtx_insn * out_insn,rtx_insn * in_insn)4253 store_data_bypass_p (rtx_insn *out_insn, rtx_insn *in_insn)
4254 {
4255   rtx in_set = single_set (in_insn);
4256   if (in_set)
4257     return store_data_bypass_p_1 (out_insn, in_set);
4258 
4259   rtx in_pat = PATTERN (in_insn);
4260   if (GET_CODE (in_pat) != PARALLEL)
4261     return false;
4262 
4263   for (int i = 0; i < XVECLEN (in_pat, 0); i++)
4264     {
4265       rtx in_exp = XVECEXP (in_pat, 0, i);
4266 
4267       if (GET_CODE (in_exp) == CLOBBER || GET_CODE (in_exp) == USE)
4268           continue;
4269 
4270       gcc_assert (GET_CODE (in_exp) == SET);
4271 
4272       if (!store_data_bypass_p_1 (out_insn, in_exp))
4273           return false;
4274     }
4275 
4276   return true;
4277 }
4278 
4279 /* True if the dependency between OUT_INSN and IN_INSN is in the IF_THEN_ELSE
4280    condition, and not the THEN or ELSE branch.  OUT_INSN may be either a single
4281    or multiple set; IN_INSN should be single_set for truth, but for convenience
4282    of insn categorization may be any JUMP or CALL insn.  */
4283 
4284 int
if_test_bypass_p(rtx_insn * out_insn,rtx_insn * in_insn)4285 if_test_bypass_p (rtx_insn *out_insn, rtx_insn *in_insn)
4286 {
4287   rtx out_set, in_set;
4288 
4289   in_set = single_set (in_insn);
4290   if (! in_set)
4291     {
4292       gcc_assert (JUMP_P (in_insn) || CALL_P (in_insn));
4293       return false;
4294     }
4295 
4296   if (GET_CODE (SET_SRC (in_set)) != IF_THEN_ELSE)
4297     return false;
4298   in_set = SET_SRC (in_set);
4299 
4300   out_set = single_set (out_insn);
4301   if (out_set)
4302     {
4303       if (reg_mentioned_p (SET_DEST (out_set), XEXP (in_set, 1))
4304             || reg_mentioned_p (SET_DEST (out_set), XEXP (in_set, 2)))
4305           return false;
4306     }
4307   else
4308     {
4309       rtx out_pat;
4310       int i;
4311 
4312       out_pat = PATTERN (out_insn);
4313       gcc_assert (GET_CODE (out_pat) == PARALLEL);
4314 
4315       for (i = 0; i < XVECLEN (out_pat, 0); i++)
4316           {
4317             rtx exp = XVECEXP (out_pat, 0, i);
4318 
4319             if (GET_CODE (exp) == CLOBBER)
4320               continue;
4321 
4322             gcc_assert (GET_CODE (exp) == SET);
4323 
4324             if (reg_mentioned_p (SET_DEST (out_set), XEXP (in_set, 1))
4325                 || reg_mentioned_p (SET_DEST (out_set), XEXP (in_set, 2)))
4326               return false;
4327           }
4328     }
4329 
4330   return true;
4331 }
4332 
4333 static unsigned int
rest_of_handle_peephole2(void)4334 rest_of_handle_peephole2 (void)
4335 {
4336   if (HAVE_peephole2)
4337     peephole2_optimize ();
4338 
4339   return 0;
4340 }
4341 
4342 namespace {
4343 
4344 const pass_data pass_data_peephole2 =
4345 {
4346   RTL_PASS, /* type */
4347   "peephole2", /* name */
4348   OPTGROUP_NONE, /* optinfo_flags */
4349   TV_PEEPHOLE2, /* tv_id */
4350   0, /* properties_required */
4351   0, /* properties_provided */
4352   0, /* properties_destroyed */
4353   0, /* todo_flags_start */
4354   TODO_df_finish, /* todo_flags_finish */
4355 };
4356 
4357 class pass_peephole2 : public rtl_opt_pass
4358 {
4359 public:
pass_peephole2(gcc::context * ctxt)4360   pass_peephole2 (gcc::context *ctxt)
4361     : rtl_opt_pass (pass_data_peephole2, ctxt)
4362   {}
4363 
4364   /* opt_pass methods: */
4365   /* The epiphany backend creates a second instance of this pass, so we need
4366      a clone method.  */
clone()4367   opt_pass * clone () { return new pass_peephole2 (m_ctxt); }
gate(function *)4368   virtual bool gate (function *) { return (optimize > 0 && flag_peephole2); }
execute(function *)4369   virtual unsigned int execute (function *)
4370     {
4371       return rest_of_handle_peephole2 ();
4372     }
4373 
4374 }; // class pass_peephole2
4375 
4376 } // anon namespace
4377 
4378 rtl_opt_pass *
make_pass_peephole2(gcc::context * ctxt)4379 make_pass_peephole2 (gcc::context *ctxt)
4380 {
4381   return new pass_peephole2 (ctxt);
4382 }
4383 
4384 namespace {
4385 
4386 const pass_data pass_data_split_all_insns =
4387 {
4388   RTL_PASS, /* type */
4389   "split1", /* name */
4390   OPTGROUP_NONE, /* optinfo_flags */
4391   TV_NONE, /* tv_id */
4392   0, /* properties_required */
4393   PROP_rtl_split_insns, /* properties_provided */
4394   0, /* properties_destroyed */
4395   0, /* todo_flags_start */
4396   0, /* todo_flags_finish */
4397 };
4398 
4399 class pass_split_all_insns : public rtl_opt_pass
4400 {
4401 public:
pass_split_all_insns(gcc::context * ctxt)4402   pass_split_all_insns (gcc::context *ctxt)
4403     : rtl_opt_pass (pass_data_split_all_insns, ctxt)
4404   {}
4405 
4406   /* opt_pass methods: */
4407   /* The epiphany backend creates a second instance of this pass, so
4408      we need a clone method.  */
clone()4409   opt_pass * clone () { return new pass_split_all_insns (m_ctxt); }
execute(function *)4410   virtual unsigned int execute (function *)
4411     {
4412       split_all_insns ();
4413       return 0;
4414     }
4415 
4416 }; // class pass_split_all_insns
4417 
4418 } // anon namespace
4419 
4420 rtl_opt_pass *
make_pass_split_all_insns(gcc::context * ctxt)4421 make_pass_split_all_insns (gcc::context *ctxt)
4422 {
4423   return new pass_split_all_insns (ctxt);
4424 }
4425 
4426 namespace {
4427 
4428 const pass_data pass_data_split_after_reload =
4429 {
4430   RTL_PASS, /* type */
4431   "split2", /* name */
4432   OPTGROUP_NONE, /* optinfo_flags */
4433   TV_NONE, /* tv_id */
4434   0, /* properties_required */
4435   0, /* properties_provided */
4436   0, /* properties_destroyed */
4437   0, /* todo_flags_start */
4438   0, /* todo_flags_finish */
4439 };
4440 
4441 class pass_split_after_reload : public rtl_opt_pass
4442 {
4443 public:
pass_split_after_reload(gcc::context * ctxt)4444   pass_split_after_reload (gcc::context *ctxt)
4445     : rtl_opt_pass (pass_data_split_after_reload, ctxt)
4446   {}
4447 
4448   /* opt_pass methods: */
gate(function *)4449   virtual bool gate (function *)
4450     {
4451       /* If optimizing, then go ahead and split insns now.  */
4452       return optimize > 0;
4453     }
4454 
execute(function *)4455   virtual unsigned int execute (function *)
4456     {
4457       split_all_insns ();
4458       return 0;
4459     }
4460 
4461 }; // class pass_split_after_reload
4462 
4463 } // anon namespace
4464 
4465 rtl_opt_pass *
make_pass_split_after_reload(gcc::context * ctxt)4466 make_pass_split_after_reload (gcc::context *ctxt)
4467 {
4468   return new pass_split_after_reload (ctxt);
4469 }
4470 
4471 static bool
enable_split_before_sched2(void)4472 enable_split_before_sched2 (void)
4473 {
4474 #ifdef INSN_SCHEDULING
4475   return optimize > 0 && flag_schedule_insns_after_reload;
4476 #else
4477   return false;
4478 #endif
4479 }
4480 
4481 namespace {
4482 
4483 const pass_data pass_data_split_before_sched2 =
4484 {
4485   RTL_PASS, /* type */
4486   "split3", /* name */
4487   OPTGROUP_NONE, /* optinfo_flags */
4488   TV_NONE, /* tv_id */
4489   0, /* properties_required */
4490   0, /* properties_provided */
4491   0, /* properties_destroyed */
4492   0, /* todo_flags_start */
4493   0, /* todo_flags_finish */
4494 };
4495 
4496 class pass_split_before_sched2 : public rtl_opt_pass
4497 {
4498 public:
pass_split_before_sched2(gcc::context * ctxt)4499   pass_split_before_sched2 (gcc::context *ctxt)
4500     : rtl_opt_pass (pass_data_split_before_sched2, ctxt)
4501   {}
4502 
4503   /* opt_pass methods: */
gate(function *)4504   virtual bool gate (function *)
4505     {
4506       return enable_split_before_sched2 ();
4507     }
4508 
execute(function *)4509   virtual unsigned int execute (function *)
4510     {
4511       split_all_insns ();
4512       return 0;
4513     }
4514 
4515 }; // class pass_split_before_sched2
4516 
4517 } // anon namespace
4518 
4519 rtl_opt_pass *
make_pass_split_before_sched2(gcc::context * ctxt)4520 make_pass_split_before_sched2 (gcc::context *ctxt)
4521 {
4522   return new pass_split_before_sched2 (ctxt);
4523 }
4524 
4525 namespace {
4526 
4527 const pass_data pass_data_split_before_regstack =
4528 {
4529   RTL_PASS, /* type */
4530   "split4", /* name */
4531   OPTGROUP_NONE, /* optinfo_flags */
4532   TV_NONE, /* tv_id */
4533   0, /* properties_required */
4534   0, /* properties_provided */
4535   0, /* properties_destroyed */
4536   0, /* todo_flags_start */
4537   0, /* todo_flags_finish */
4538 };
4539 
4540 class pass_split_before_regstack : public rtl_opt_pass
4541 {
4542 public:
pass_split_before_regstack(gcc::context * ctxt)4543   pass_split_before_regstack (gcc::context *ctxt)
4544     : rtl_opt_pass (pass_data_split_before_regstack, ctxt)
4545   {}
4546 
4547   /* opt_pass methods: */
4548   virtual bool gate (function *);
execute(function *)4549   virtual unsigned int execute (function *)
4550     {
4551       split_all_insns ();
4552       return 0;
4553     }
4554 
4555 }; // class pass_split_before_regstack
4556 
4557 bool
gate(function *)4558 pass_split_before_regstack::gate (function *)
4559 {
4560 #if HAVE_ATTR_length && defined (STACK_REGS)
4561   /* If flow2 creates new instructions which need splitting
4562      and scheduling after reload is not done, they might not be
4563      split until final which doesn't allow splitting
4564      if HAVE_ATTR_length.  Selective scheduling can result in
4565      further instructions that need splitting.  */
4566 #ifdef INSN_SCHEDULING
4567   return !enable_split_before_sched2 () || flag_selective_scheduling2;
4568 #else
4569   return !enable_split_before_sched2 ();
4570 #endif
4571 #else
4572   return false;
4573 #endif
4574 }
4575 
4576 } // anon namespace
4577 
4578 rtl_opt_pass *
make_pass_split_before_regstack(gcc::context * ctxt)4579 make_pass_split_before_regstack (gcc::context *ctxt)
4580 {
4581   return new pass_split_before_regstack (ctxt);
4582 }
4583 
4584 namespace {
4585 
4586 const pass_data pass_data_split_for_shorten_branches =
4587 {
4588   RTL_PASS, /* type */
4589   "split5", /* name */
4590   OPTGROUP_NONE, /* optinfo_flags */
4591   TV_NONE, /* tv_id */
4592   0, /* properties_required */
4593   0, /* properties_provided */
4594   0, /* properties_destroyed */
4595   0, /* todo_flags_start */
4596   0, /* todo_flags_finish */
4597 };
4598 
4599 class pass_split_for_shorten_branches : public rtl_opt_pass
4600 {
4601 public:
pass_split_for_shorten_branches(gcc::context * ctxt)4602   pass_split_for_shorten_branches (gcc::context *ctxt)
4603     : rtl_opt_pass (pass_data_split_for_shorten_branches, ctxt)
4604   {}
4605 
4606   /* opt_pass methods: */
gate(function *)4607   virtual bool gate (function *)
4608     {
4609       /* The placement of the splitting that we do for shorten_branches
4610            depends on whether regstack is used by the target or not.  */
4611 #if HAVE_ATTR_length && !defined (STACK_REGS)
4612       return true;
4613 #else
4614       return false;
4615 #endif
4616     }
4617 
execute(function *)4618   virtual unsigned int execute (function *)
4619     {
4620       return split_all_insns_noflow ();
4621     }
4622 
4623 }; // class pass_split_for_shorten_branches
4624 
4625 } // anon namespace
4626 
4627 rtl_opt_pass *
make_pass_split_for_shorten_branches(gcc::context * ctxt)4628 make_pass_split_for_shorten_branches (gcc::context *ctxt)
4629 {
4630   return new pass_split_for_shorten_branches (ctxt);
4631 }
4632 
4633 /* (Re)initialize the target information after a change in target.  */
4634 
4635 void
recog_init()4636 recog_init ()
4637 {
4638   /* The information is zero-initialized, so we don't need to do anything
4639      first time round.  */
4640   if (!this_target_recog->x_initialized)
4641     {
4642       this_target_recog->x_initialized = true;
4643       return;
4644     }
4645   memset (this_target_recog->x_bool_attr_masks, 0,
4646             sizeof (this_target_recog->x_bool_attr_masks));
4647   for (unsigned int i = 0; i < NUM_INSN_CODES; ++i)
4648     if (this_target_recog->x_op_alt[i])
4649       {
4650           free (this_target_recog->x_op_alt[i]);
4651           this_target_recog->x_op_alt[i] = 0;
4652       }
4653 }
4654