OSDN Git Service

In ChangeLog:
[pf3gnuchains/gcc-fork.git] / gcc / gensupport.c
1 /* Support routines for the various generation passes.
2    Copyright (C) 2000, 2001 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
7    under the terms of the GNU General Public License as published by
8    the Free Software Foundation; either version 2, or (at your option)
9    any later version.
10
11    GCC is distributed in the hope that it will be useful, but WITHOUT
12    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
13    or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
14    License for more details.
15
16    You should have received a copy of the GNU General Public License
17    along with GCC; see the file COPYING.  If not, write to the Free
18    Software Foundation, 59 Temple Place - Suite 330, Boston, MA
19    02111-1307, USA.  */
20
21 #include "hconfig.h"
22 #include "system.h"
23 #include "rtl.h"
24 #include "obstack.h"
25 #include "errors.h"
26 #include "gensupport.h"
27
28
29 /* In case some macros used by files we include need it, define this here.  */
30 int target_flags;
31
32 static struct obstack obstack;
33 struct obstack *rtl_obstack = &obstack;
34
35 #define obstack_chunk_alloc xmalloc
36 #define obstack_chunk_free free
37
38 static int sequence_num;
39 static int errors;
40
41 static int predicable_default;
42 static const char *predicable_true;
43 static const char *predicable_false;
44
45 /* We initially queue all patterns, process the define_insn and
46    define_cond_exec patterns, then return them one at a time.  */
47
48 struct queue_elem
49 {
50   rtx data;
51   int lineno;
52   struct queue_elem *next;
53 };
54
55 static struct queue_elem *define_attr_queue;
56 static struct queue_elem **define_attr_tail = &define_attr_queue;
57 static struct queue_elem *define_insn_queue;
58 static struct queue_elem **define_insn_tail = &define_insn_queue;
59 static struct queue_elem *define_cond_exec_queue;
60 static struct queue_elem **define_cond_exec_tail = &define_cond_exec_queue;
61 static struct queue_elem *other_queue;
62 static struct queue_elem **other_tail = &other_queue;
63
64 static void queue_pattern PARAMS ((rtx, struct queue_elem ***, int));
65 static void remove_constraints PARAMS ((rtx));
66 static void process_rtx PARAMS ((rtx, int));
67
68 static int is_predicable PARAMS ((struct queue_elem *));
69 static void identify_predicable_attribute PARAMS ((void));
70 static int n_alternatives PARAMS ((const char *));
71 static void collect_insn_data PARAMS ((rtx, int *, int *));
72 static rtx alter_predicate_for_insn PARAMS ((rtx, int, int, int));
73 static const char *alter_test_for_insn PARAMS ((struct queue_elem *,
74                                                 struct queue_elem *));
75 static char *shift_output_template PARAMS ((char *, const char *, int));
76 static const char *alter_output_for_insn PARAMS ((struct queue_elem *,
77                                                   struct queue_elem *,
78                                                   int, int));
79 static void process_one_cond_exec PARAMS ((struct queue_elem *));
80 static void process_define_cond_exec PARAMS ((void));
81 \f
82 void
83 message_with_line VPARAMS ((int lineno, const char *msg, ...))
84 {
85   VA_OPEN (ap, msg);
86   VA_FIXEDARG (ap, int, lineno);
87   VA_FIXEDARG (ap, const char *, msg);
88
89   fprintf (stderr, "%s:%d: ", read_rtx_filename, lineno);
90   vfprintf (stderr, msg, ap);
91   fputc ('\n', stderr);
92
93   VA_CLOSE (ap);
94 }
95
96 /* Make a version of gen_rtx_CONST_INT so that GEN_INT can be used in
97    the gensupport programs.  */
98
99 rtx
100 gen_rtx_CONST_INT (mode, arg)
101      enum machine_mode mode ATTRIBUTE_UNUSED;
102      HOST_WIDE_INT arg;
103 {
104   rtx rt = rtx_alloc (CONST_INT);
105
106   XWINT (rt, 0) = arg;
107   return rt;
108 }
109 \f
110 /* Queue PATTERN on LIST_TAIL.  */
111
112 static void
113 queue_pattern (pattern, list_tail, lineno)
114      rtx pattern;
115      struct queue_elem ***list_tail;
116      int lineno;
117 {
118   struct queue_elem *e = (struct queue_elem *) xmalloc (sizeof (*e));
119   e->data = pattern;
120   e->lineno = lineno;
121   e->next = NULL;
122   **list_tail = e;
123   *list_tail = &e->next;
124 }
125
126 /* Recursively remove constraints from an rtx.  */
127
128 static void
129 remove_constraints (part)
130      rtx part;
131 {
132   int i, j;
133   const char *format_ptr;
134
135   if (part == 0)
136     return;
137
138   if (GET_CODE (part) == MATCH_OPERAND)
139     XSTR (part, 2) = "";
140   else if (GET_CODE (part) == MATCH_SCRATCH)
141     XSTR (part, 1) = "";
142
143   format_ptr = GET_RTX_FORMAT (GET_CODE (part));
144
145   for (i = 0; i < GET_RTX_LENGTH (GET_CODE (part)); i++)
146     switch (*format_ptr++)
147       {
148       case 'e':
149       case 'u':
150         remove_constraints (XEXP (part, i));
151         break;
152       case 'E':
153         if (XVEC (part, i) != NULL)
154           for (j = 0; j < XVECLEN (part, i); j++)
155             remove_constraints (XVECEXP (part, i, j));
156         break;
157       }
158 }
159
160 /* Process a top level rtx in some way, queueing as appropriate.  */
161
162 static void
163 process_rtx (desc, lineno)
164      rtx desc;
165      int lineno;
166 {
167   switch (GET_CODE (desc))
168     {
169     case DEFINE_INSN:
170       queue_pattern (desc, &define_insn_tail, lineno);
171       break;
172
173     case DEFINE_COND_EXEC:
174       queue_pattern (desc, &define_cond_exec_tail, lineno);
175       break;
176
177     case DEFINE_ATTR:
178       queue_pattern (desc, &define_attr_tail, lineno);
179       break;
180
181     case DEFINE_INSN_AND_SPLIT:
182       {
183         const char *split_cond;
184         rtx split;
185         rtvec attr;
186         int i;
187
188         /* Create a split with values from the insn_and_split.  */
189         split = rtx_alloc (DEFINE_SPLIT);
190
191         i = XVECLEN (desc, 1);
192         XVEC (split, 0) = rtvec_alloc (i);
193         while (--i >= 0)
194           {
195             XVECEXP (split, 0, i) = copy_rtx (XVECEXP (desc, 1, i));
196             remove_constraints (XVECEXP (split, 0, i));
197           }
198
199         /* If the split condition starts with "&&", append it to the
200            insn condition to create the new split condition.  */
201         split_cond = XSTR (desc, 4);
202         if (split_cond[0] == '&' && split_cond[1] == '&')
203           {
204             const char *insn_cond = XSTR (desc, 2);
205             size_t insn_cond_len = strlen (insn_cond);
206             size_t split_cond_len = strlen (split_cond);
207             char *combined;
208
209             combined = (char *) xmalloc (insn_cond_len + split_cond_len + 1);
210             memcpy (combined, insn_cond, insn_cond_len);
211             memcpy (combined + insn_cond_len, split_cond, split_cond_len + 1);
212
213             split_cond = combined;
214           }
215         XSTR (split, 1) = split_cond;
216         XVEC (split, 2) = XVEC (desc, 5);
217         XSTR (split, 3) = XSTR (desc, 6);
218
219         /* Fix up the DEFINE_INSN.  */
220         attr = XVEC (desc, 7);
221         PUT_CODE (desc, DEFINE_INSN);
222         XVEC (desc, 4) = attr;
223
224         /* Queue them.  */
225         queue_pattern (desc, &define_insn_tail, lineno);
226         queue_pattern (split, &other_tail, lineno);
227         break;
228       }
229
230     default:
231       queue_pattern (desc, &other_tail, lineno);
232       break;
233     }
234 }
235 \f
236 /* Return true if attribute PREDICABLE is true for ELEM, which holds
237    a DEFINE_INSN.  */
238
239 static int
240 is_predicable (elem)
241      struct queue_elem *elem;
242 {
243   rtvec vec = XVEC (elem->data, 4);
244   const char *value;
245   int i;
246
247   if (! vec)
248     return predicable_default;
249
250   for (i = GET_NUM_ELEM (vec) - 1; i >= 0; --i)
251     {
252       rtx sub = RTVEC_ELT (vec, i);
253       switch (GET_CODE (sub))
254         {
255         case SET_ATTR:
256           if (strcmp (XSTR (sub, 0), "predicable") == 0)
257             {
258               value = XSTR (sub, 1);
259               goto found;
260             }
261           break;
262
263         case SET_ATTR_ALTERNATIVE:
264           if (strcmp (XSTR (sub, 0), "predicable") == 0)
265             {
266               message_with_line (elem->lineno,
267                                  "multiple alternatives for `predicable'");
268               errors = 1;
269               return 0;
270             }
271           break;
272
273         case SET:
274           if (GET_CODE (SET_DEST (sub)) != ATTR
275               || strcmp (XSTR (SET_DEST (sub), 0), "predicable") != 0)
276             break;
277           sub = SET_SRC (sub);
278           if (GET_CODE (sub) == CONST_STRING)
279             {
280               value = XSTR (sub, 0);
281               goto found;
282             }
283
284           /* ??? It would be possible to handle this if we really tried.
285              It's not easy though, and I'm not going to bother until it
286              really proves necessary.  */
287           message_with_line (elem->lineno,
288                              "non-constant value for `predicable'");
289           errors = 1;
290           return 0;
291
292         default:
293           abort ();
294         }
295     }
296
297   return predicable_default;
298
299  found:
300   /* Verify that predicability does not vary on the alternative.  */
301   /* ??? It should be possible to handle this by simply eliminating
302      the non-predicable alternatives from the insn.  FRV would like
303      to do this.  Delay this until we've got the basics solid.  */
304   if (strchr (value, ',') != NULL)
305     {
306       message_with_line (elem->lineno,
307                          "multiple alternatives for `predicable'");
308       errors = 1;
309       return 0;
310     }
311
312   /* Find out which value we're looking at.  */
313   if (strcmp (value, predicable_true) == 0)
314     return 1;
315   if (strcmp (value, predicable_false) == 0)
316     return 0;
317
318   message_with_line (elem->lineno,
319                      "Unknown value `%s' for `predicable' attribute",
320                      value);
321   errors = 1;
322   return 0;
323 }
324
325 /* Examine the attribute "predicable"; discover its boolean values
326    and its default.  */
327
328 static void
329 identify_predicable_attribute ()
330 {
331   struct queue_elem *elem;
332   char *p_true, *p_false;
333   const char *value;
334   size_t len;
335
336   /* Look for the DEFINE_ATTR for `predicable', which must exist.  */
337   for (elem = define_attr_queue; elem ; elem = elem->next)
338     if (strcmp (XSTR (elem->data, 0), "predicable") == 0)
339       goto found;
340
341   message_with_line (define_cond_exec_queue->lineno,
342                      "Attribute `predicable' not defined");
343   errors = 1;
344   return;
345
346  found:
347   value = XSTR (elem->data, 1);
348   len = strlen (value);
349   p_false = (char *) xmalloc (len + 1);
350   memcpy (p_false, value, len + 1);
351
352   p_true = strchr (p_false, ',');
353   if (p_true == NULL || strchr (++p_true, ',') != NULL)
354     {
355       message_with_line (elem->lineno,
356                          "Attribute `predicable' is not a boolean");
357       errors = 1;
358       return;
359     }
360   p_true[-1] = '\0';
361
362   predicable_true = p_true;
363   predicable_false = p_false;
364
365   switch (GET_CODE (XEXP (elem->data, 2)))
366     {
367     case CONST_STRING:
368       value = XSTR (XEXP (elem->data, 2), 0);
369       break;
370
371     case CONST:
372       message_with_line (elem->lineno,
373                          "Attribute `predicable' cannot be const");
374       errors = 1;
375       return;
376
377     default:
378       message_with_line (elem->lineno,
379                          "Attribute `predicable' must have a constant default");
380       errors = 1;
381       return;
382     }
383
384   if (strcmp (value, p_true) == 0)
385     predicable_default = 1;
386   else if (strcmp (value, p_false) == 0)
387     predicable_default = 0;
388   else
389     {
390       message_with_line (elem->lineno,
391                          "Unknown value `%s' for `predicable' attribute",
392                          value);
393       errors = 1;
394     }
395 }
396
397 /* Return the number of alternatives in constraint S.  */
398
399 static int
400 n_alternatives (s)
401      const char *s;
402 {
403   int n = 1;
404
405   if (s)
406     while (*s)
407       n += (*s++ == ',');
408
409   return n;
410 }
411
412 /* Determine how many alternatives there are in INSN, and how many
413    operands.  */
414
415 static void
416 collect_insn_data (pattern, palt, pmax)
417      rtx pattern;
418      int *palt, *pmax;
419 {
420   const char *fmt;
421   enum rtx_code code;
422   int i, j, len;
423
424   code = GET_CODE (pattern);
425   switch (code)
426     {
427     case MATCH_OPERAND:
428       i = n_alternatives (XSTR (pattern, 2));
429       *palt = (i > *palt ? i : *palt);
430       /* FALLTHRU */
431
432     case MATCH_OPERATOR:
433     case MATCH_SCRATCH:
434     case MATCH_PARALLEL:
435     case MATCH_INSN:
436       i = XINT (pattern, 0);
437       if (i > *pmax)
438         *pmax = i;
439       break;
440
441     default:
442       break;
443     }
444
445   fmt = GET_RTX_FORMAT (code);
446   len = GET_RTX_LENGTH (code);
447   for (i = 0; i < len; i++)
448     {
449       switch (fmt[i])
450         {
451         case 'e': case 'u':
452           collect_insn_data (XEXP (pattern, i), palt, pmax);
453           break;
454
455         case 'V':
456           if (XVEC (pattern, i) == NULL)
457             break;
458           /* FALLTHRU */
459         case 'E':
460           for (j = XVECLEN (pattern, i) - 1; j >= 0; --j)
461             collect_insn_data (XVECEXP (pattern, i, j), palt, pmax);
462           break;
463
464         case 'i': case 'w': case '0': case 's': case 'S': case 'T':
465           break;
466
467         default:
468           abort ();
469         }
470     }
471 }
472
473 static rtx
474 alter_predicate_for_insn (pattern, alt, max_op, lineno)
475      rtx pattern;
476      int alt, max_op, lineno;
477 {
478   const char *fmt;
479   enum rtx_code code;
480   int i, j, len;
481
482   code = GET_CODE (pattern);
483   switch (code)
484     {
485     case MATCH_OPERAND:
486       {
487         const char *c = XSTR (pattern, 2);
488
489         if (n_alternatives (c) != 1)
490           {
491             message_with_line (lineno,
492                                "Too many alternatives for operand %d",
493                                XINT (pattern, 0));
494             errors = 1;
495             return NULL;
496           }
497
498         /* Replicate C as needed to fill out ALT alternatives.  */
499         if (c && *c && alt > 1)
500           {
501             size_t c_len = strlen (c);
502             size_t len = alt * (c_len + 1);
503             char *new_c = (char *) xmalloc (len);
504
505             memcpy (new_c, c, c_len);
506             for (i = 1; i < alt; ++i)
507               {
508                 new_c[i * (c_len + 1) - 1] = ',';
509                 memcpy (&new_c[i * (c_len + 1)], c, c_len);
510               }
511             new_c[len - 1] = '\0';
512             XSTR (pattern, 2) = new_c;
513           }
514       }
515       /* FALLTHRU */
516
517     case MATCH_OPERATOR:
518     case MATCH_SCRATCH:
519     case MATCH_PARALLEL:
520     case MATCH_INSN:
521       XINT (pattern, 0) += max_op;
522       break;
523
524     default:
525       break;
526     }
527
528   fmt = GET_RTX_FORMAT (code);
529   len = GET_RTX_LENGTH (code);
530   for (i = 0; i < len; i++)
531     {
532       rtx r;
533
534       switch (fmt[i])
535         {
536         case 'e': case 'u':
537           r = alter_predicate_for_insn (XEXP (pattern, i), alt,
538                                         max_op, lineno);
539           if (r == NULL)
540             return r;
541           break;
542
543         case 'E':
544           for (j = XVECLEN (pattern, i) - 1; j >= 0; --j)
545             {
546               r = alter_predicate_for_insn (XVECEXP (pattern, i, j),
547                                             alt, max_op, lineno);
548               if (r == NULL)
549                 return r;
550             }
551           break;
552
553         case 'i': case 'w': case '0': case 's':
554           break;
555
556         default:
557           abort ();
558         }
559     }
560
561   return pattern;
562 }
563
564 static const char *
565 alter_test_for_insn (ce_elem, insn_elem)
566      struct queue_elem *ce_elem, *insn_elem;
567 {
568   const char *ce_test, *insn_test;
569   char *new_test;
570   size_t len, ce_len, insn_len;
571
572   ce_test = XSTR (ce_elem->data, 1);
573   insn_test = XSTR (insn_elem->data, 2);
574   if (!ce_test || *ce_test == '\0')
575     return insn_test;
576   if (!insn_test || *insn_test == '\0')
577     return ce_test;
578
579   ce_len = strlen (ce_test);
580   insn_len = strlen (insn_test);
581   len = 1 + ce_len + 1 + 4 + 1 + insn_len + 1 + 1;
582   new_test = (char *) xmalloc (len);
583
584   sprintf (new_test, "(%s) && (%s)", ce_test, insn_test);
585
586   return new_test;
587 }
588
589 /* Adjust all of the operand numbers in OLD to match the shift they'll
590    get from an operand displacement of DISP.  Return a pointer after the
591    adjusted string.  */
592
593 static char *
594 shift_output_template (new, old, disp)
595      char *new;
596      const char *old;
597      int disp;
598 {
599   while (*old)
600     {
601       char c = *old++;
602       *new++ = c;
603       if (c == '%')
604         {
605           c = *old++;
606           if (ISDIGIT ((unsigned char) c))
607             c += disp;
608           else if (ISALPHA (c))
609             {
610               *new++ = c;
611               c = *old++ + disp;
612             }
613           *new++ = c;
614         }
615     }
616
617   return new;
618 }
619
620 static const char *
621 alter_output_for_insn (ce_elem, insn_elem, alt, max_op)
622      struct queue_elem *ce_elem, *insn_elem;
623      int alt, max_op;
624 {
625   const char *ce_out, *insn_out;
626   char *new, *p;
627   size_t len, ce_len, insn_len;
628
629   /* ??? Could coordinate with genoutput to not duplicate code here.  */
630
631   ce_out = XSTR (ce_elem->data, 2);
632   insn_out = XTMPL (insn_elem->data, 3);
633   if (!ce_out || *ce_out == '\0')
634     return insn_out;
635
636   ce_len = strlen (ce_out);
637   insn_len = strlen (insn_out);
638
639   if (*insn_out == '*')
640     /* You must take care of the predicate yourself.  */
641     return insn_out;
642
643   if (*insn_out == '@')
644     {
645       len = (ce_len + 1) * alt + insn_len + 1;
646       p = new = xmalloc (len);
647
648       do
649         {
650           do
651             *p++ = *insn_out++;
652           while (ISSPACE ((unsigned char) *insn_out));
653
654           if (*insn_out != '#')
655             {
656               p = shift_output_template (p, ce_out, max_op);
657               *p++ = ' ';
658             }
659
660           do
661             *p++ = *insn_out++;
662           while (*insn_out && *insn_out != '\n');
663         }
664       while (*insn_out);
665       *p = '\0';
666     }
667   else
668     {
669       len = ce_len + 1 + insn_len + 1;
670       new = xmalloc (len);
671
672       p = shift_output_template (new, ce_out, max_op);
673       *p++ = ' ';
674       memcpy (p, insn_out, insn_len + 1);
675     }
676
677   return new;
678 }
679
680 /* Replicate insns as appropriate for the given DEFINE_COND_EXEC.  */
681
682 static void
683 process_one_cond_exec (ce_elem)
684      struct queue_elem *ce_elem;
685 {
686   struct queue_elem *insn_elem;
687   for (insn_elem = define_insn_queue; insn_elem ; insn_elem = insn_elem->next)
688     {
689       int alternatives, max_operand;
690       rtx pred, insn, pattern;
691
692       if (! is_predicable (insn_elem))
693         continue;
694
695       alternatives = 1;
696       max_operand = -1;
697       collect_insn_data (insn_elem->data, &alternatives, &max_operand);
698       max_operand += 1;
699
700       if (XVECLEN (ce_elem->data, 0) != 1)
701         {
702           message_with_line (ce_elem->lineno,
703                              "too many patterns in predicate");
704           errors = 1;
705           return;
706         }
707
708       pred = copy_rtx (XVECEXP (ce_elem->data, 0, 0));
709       pred = alter_predicate_for_insn (pred, alternatives, max_operand,
710                                        ce_elem->lineno);
711       if (pred == NULL)
712         return;
713
714       /* Construct a new pattern for the new insn.  */
715       insn = copy_rtx (insn_elem->data);
716       XSTR (insn, 0) = "";
717       pattern = rtx_alloc (COND_EXEC);
718       XEXP (pattern, 0) = pred;
719       if (XVECLEN (insn, 1) == 1)
720         {
721           XEXP (pattern, 1) = XVECEXP (insn, 1, 0);
722           XVECEXP (insn, 1, 0) = pattern;
723           PUT_NUM_ELEM (XVEC (insn, 1), 1);
724         }
725       else
726         {
727           XEXP (pattern, 1) = rtx_alloc (PARALLEL);
728           XVEC (XEXP (pattern, 1), 0) = XVEC (insn, 1);
729           XVEC (insn, 1) = rtvec_alloc (1);
730           XVECEXP (insn, 1, 0) = pattern;
731         }
732
733       XSTR (insn, 2) = alter_test_for_insn (ce_elem, insn_elem);
734       XTMPL (insn, 3) = alter_output_for_insn (ce_elem, insn_elem,
735                                               alternatives, max_operand);
736
737       /* ??? Set `predicable' to false.  Not crucial since it's really
738          only used here, and we won't reprocess this new pattern.  */
739
740       /* Put the new pattern on the `other' list so that it
741          (a) is not reprocessed by other define_cond_exec patterns
742          (b) appears after all normal define_insn patterns.
743
744          ??? B is debatable.  If one has normal insns that match
745          cond_exec patterns, they will be preferred over these
746          generated patterns.  Whether this matters in practice, or if
747          it's a good thing, or whether we should thread these new
748          patterns into the define_insn chain just after their generator
749          is something we'll have to experiment with.  */
750
751       queue_pattern (insn, &other_tail, insn_elem->lineno);
752     }
753 }
754
755 /* If we have any DEFINE_COND_EXEC patterns, expand the DEFINE_INSN
756    patterns appropriately.  */
757
758 static void
759 process_define_cond_exec ()
760 {
761   struct queue_elem *elem;
762
763   identify_predicable_attribute ();
764   if (errors)
765     return;
766
767   for (elem = define_cond_exec_queue; elem ; elem = elem->next)
768     process_one_cond_exec (elem);
769 }
770 \f
771 /* The entry point for initializing the reader.  */
772
773 int
774 init_md_reader (filename)
775      const char *filename;
776 {
777   FILE *input_file;
778   int c;
779
780   read_rtx_filename = filename;
781   input_file = fopen (filename, "r");
782   if (input_file == 0)
783     {
784       perror (filename);
785       return FATAL_EXIT_CODE;
786     }
787
788   obstack_init (rtl_obstack);
789   errors = 0;
790   sequence_num = 0;
791
792   /* Read the entire file.  */
793   while (1)
794     {
795       rtx desc;
796       int lineno;
797
798       c = read_skip_spaces (input_file);
799       if (c == EOF)
800         break;
801
802       ungetc (c, input_file);
803       lineno = read_rtx_lineno;
804       desc = read_rtx (input_file);
805       process_rtx (desc, lineno);
806     }
807   fclose (input_file);
808
809   /* Process define_cond_exec patterns.  */
810   if (define_cond_exec_queue != NULL)
811     process_define_cond_exec ();
812
813   return errors ? FATAL_EXIT_CODE : SUCCESS_EXIT_CODE;
814 }
815
816 /* The entry point for reading a single rtx from an md file.  */
817
818 rtx
819 read_md_rtx (lineno, seqnr)
820      int *lineno;
821      int *seqnr;
822 {
823   struct queue_elem **queue, *elem;
824   rtx desc;
825
826   /* Read all patterns from a given queue before moving on to the next.  */
827   if (define_attr_queue != NULL)
828     queue = &define_attr_queue;
829   else if (define_insn_queue != NULL)
830     queue = &define_insn_queue;
831   else if (other_queue != NULL)
832     queue = &other_queue;
833   else
834     return NULL_RTX;
835
836   elem = *queue;
837   *queue = elem->next;
838   desc = elem->data;
839   *lineno = elem->lineno;
840   *seqnr = sequence_num;
841
842   free (elem);
843
844   switch (GET_CODE (desc))
845     {
846     case DEFINE_INSN:
847     case DEFINE_EXPAND:
848     case DEFINE_SPLIT:
849     case DEFINE_PEEPHOLE:
850     case DEFINE_PEEPHOLE2:
851       sequence_num++;
852       break;
853
854     default:
855       break;
856     }
857
858   return desc;
859 }
860
861 /* Until we can use the versions in libiberty.  */
862 char *
863 xstrdup (input)
864   const char *input;
865 {
866   size_t len = strlen (input) + 1;
867   char *output = xmalloc (len);
868   memcpy (output, input, len);
869   return output;
870 }
871
872 PTR
873 xcalloc (nelem, elsize)
874   size_t nelem, elsize;
875 {
876   PTR newmem;
877
878   if (nelem == 0 || elsize == 0)
879     nelem = elsize = 1;
880
881   newmem = really_call_calloc (nelem, elsize);
882   if (!newmem)
883     fatal ("virtual memory exhausted");
884   return (newmem);
885 }
886
887 PTR
888 xrealloc (old, size)
889   PTR old;
890   size_t size;
891 {
892   PTR ptr;
893   if (old)
894     ptr = (PTR) really_call_realloc (old, size);
895   else
896     ptr = (PTR) really_call_malloc (size);
897   if (!ptr)
898     fatal ("virtual memory exhausted");
899   return ptr;
900 }
901
902 PTR
903 xmalloc (size)
904   size_t size;
905 {
906   PTR val = (PTR) really_call_malloc (size);
907
908   if (val == 0)
909     fatal ("virtual memory exhausted");
910   return val;
911 }