source: trunk/third/gcc/bc-optab.c @ 11288

Revision 11288, 22.2 KB checked in by ghudson, 26 years ago (diff)
This commit was generated by cvs2svn to compensate for changes in r11287, which included commits to RCS files with non-trunk default branches.
Line 
1/* Bytecode conversion definitions for GNU C-compiler.
2   Copyright (C) 1993, 1994, 1997 Free Software Foundation, Inc.
3
4This file is part of GNU CC.
5
6GNU CC is free software; you can redistribute it and/or modify
7it under the terms of the GNU General Public License as published by
8the Free Software Foundation; either version 2, or (at your option)
9any later version.
10
11GNU CC is distributed in the hope that it will be useful,
12but WITHOUT ANY WARRANTY; without even the implied warranty of
13MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14GNU General Public License for more details.
15
16You should have received a copy of the GNU General Public License
17along with GNU CC; see the file COPYING.  If not, write to
18the Free Software Foundation, 59 Temple Place - Suite 330,
19Boston, MA 02111-1307, USA.  */
20
21
22#include "config.h"
23#include <stdio.h>
24#ifdef HAVE_STDLIB_H
25#include <stdlib.h>
26#endif
27#include "tree.h"
28#include "rtl.h"
29#include "machmode.h"
30#include "obstack.h"
31#include "bytecode.h"
32#include "bc-typecd.h"
33#include "bc-opcode.h"
34#include "bc-optab.h"
35
36#define obstack_chunk_alloc xmalloc
37#define obstack_chunk_free free
38
39extern char *xmalloc ();
40
41/* Table relating interpreter typecodes to machine modes.  */
42#define GET_TYPECODE_MODE(CODE) (typecode_mode[((int) CODE)])
43enum machine_mode typecode_mode[] = {
44#define DEFTYPECODE(CODE, NAME, MODE, TYPE) MODE,
45#include "bc-typecd.def"
46#undef DEFTYPECODE
47};
48
49/* Machine mode to type code map */
50static enum typecode signed_mode_to_code_map[MAX_MACHINE_MODE+1];
51static enum typecode unsigned_mode_to_code_map[MAX_MACHINE_MODE+1];
52
53#define GET_TYPECODE_SIZE(CODE) GET_MODE_SIZE (GET_TYPECODE_MODE (CODE))
54
55#define BIG_ARBITRARY_NUMBER 100000
56
57/* Table of recipes for conversions among scalar types, to be filled
58   in as needed at run time.  */
59static struct conversion_recipe
60{
61  unsigned char *opcodes;       /* Bytecodes to emit in order.  */
62  int nopcodes;                 /* Count of bytecodes.  */
63  int cost;                     /* A rather arbitrary cost function.  */
64} conversion_recipe[NUM_TYPECODES][NUM_TYPECODES];
65
66/* Binary operator tables.  */
67struct binary_operator optab_plus_expr[] = {
68  { addSI, SIcode, SIcode, SIcode },
69  { addDI, DIcode, DIcode, DIcode },
70  { addSF, SFcode, SFcode, SFcode },
71  { addDF, DFcode, DFcode, DFcode },
72  { addXF, XFcode, XFcode, XFcode },
73  { addPSI, Pcode, Pcode, SIcode },
74  { -1, -1, -1, -1 },
75};
76
77struct binary_operator optab_minus_expr[] = {
78  { subSI, SIcode, SIcode, SIcode },
79  { subDI, DIcode, DIcode, DIcode },
80  { subSF, SFcode, SFcode, SFcode },
81  { subDF, DFcode, DFcode, DFcode },
82  { subXF, XFcode, XFcode, XFcode },
83  { subPP, SIcode, Pcode, Pcode },
84  { -1, -1, -1, -1 },
85};
86
87/* The ordering of the tables for multiplicative operators
88   is such that unsigned operations will be preferred to signed
89   operations when one argument is unsigned.  */
90
91struct binary_operator optab_mult_expr[] = {
92  { mulSU, SUcode, SUcode, SUcode },
93  { mulDU, DUcode, DUcode, DUcode },
94  { mulSI, SIcode, SIcode, SIcode },
95  { mulDI, DIcode, DIcode, DIcode },
96  { mulSF, SFcode, SFcode, SFcode },
97  { mulDF, DFcode, DFcode, DFcode },
98  { mulXF, XFcode, XFcode, XFcode },
99  { -1, -1, -1, -1 },
100};
101
102struct binary_operator optab_trunc_div_expr[] = {
103  { divSU, SUcode, SUcode, SUcode },
104  { divDU, DUcode, DUcode, DUcode },
105  { divSI, SIcode, SIcode, SIcode },
106  { divDI, DIcode, DIcode, DIcode },
107  { -1, -1, -1, -1 },
108};
109
110struct binary_operator optab_trunc_mod_expr[] = {
111  { modSU, SUcode, SUcode, SUcode },
112  { modDU, DUcode, DUcode, DUcode },
113  { modSI, SIcode, SIcode, SIcode },
114  { modDI, DIcode, DIcode, DIcode },
115  { -1, -1, -1, -1 },
116};
117
118struct binary_operator optab_rdiv_expr[] = {
119  { divSF, SFcode, SFcode, SFcode },
120  { divDF, DFcode, DFcode, DFcode },
121  { divXF, XFcode, XFcode, XFcode },
122  { -1, -1, -1, -1 },
123};
124
125struct binary_operator optab_bit_and_expr[] = {
126  { andSI, SIcode, SIcode, SIcode },
127  { andDI, DIcode, DIcode, DIcode },
128  { -1, -1, -1, -1 },
129};
130
131struct binary_operator optab_bit_ior_expr[] = {
132  { iorSI, SIcode, SIcode, SIcode },
133  { iorDI, DIcode, DIcode, DIcode },
134  { -1, -1, -1, -1 },
135};
136
137struct binary_operator optab_bit_xor_expr[] = {
138  { xorSI, SIcode, SIcode, SIcode },
139  { xorDI, DIcode, DIcode, DIcode },
140  { -1, -1, -1, -1 },
141};
142
143struct binary_operator optab_lshift_expr[] = {
144  { lshiftSI, SIcode, SIcode, SIcode },
145  { lshiftSU, SUcode, SUcode, SIcode },
146  { lshiftDI, DIcode, DIcode, SIcode },
147  { lshiftDU, DUcode, DUcode, SIcode },
148  { -1, -1, -1, -1 },
149};
150
151struct binary_operator optab_rshift_expr[] = {
152  { rshiftSI, SIcode, SIcode, SIcode },
153  { rshiftSU, SUcode, SUcode, SIcode },
154  { rshiftDI, DIcode, DIcode, SIcode },
155  { rshiftDU, DUcode, DUcode, SIcode },
156  { -1, -1, -1, -1 },
157};
158
159struct binary_operator optab_truth_and_expr[] = {
160  { andSI, SIcode, Tcode, Tcode },
161  { -1, -1, -1, -1 },
162};
163
164struct binary_operator optab_truth_or_expr[] = {
165  { iorSI, SIcode, Tcode, Tcode },
166  { -1, -1, -1, -1 },
167};
168
169struct binary_operator optab_lt_expr[] = {
170  { ltSI, Tcode, SIcode, SIcode },
171  { ltSU, Tcode, SUcode, SUcode },
172  { ltDI, Tcode, DIcode, DIcode },
173  { ltDU, Tcode, DUcode, DUcode },
174  { ltSF, Tcode, SFcode, SFcode },
175  { ltDF, Tcode, DFcode, DFcode },
176  { ltXF, Tcode, XFcode, XFcode },
177  { ltP, Tcode, Pcode, Pcode },
178  { -1, -1, -1, -1 },
179};
180
181struct binary_operator optab_le_expr[] = {
182  { leSI, Tcode, SIcode, SIcode },
183  { leSU, Tcode, SUcode, SUcode },
184  { leDI, Tcode, DIcode, DIcode },
185  { leDU, Tcode, DUcode, DUcode },
186  { leSF, Tcode, SFcode, SFcode },
187  { leDF, Tcode, DFcode, DFcode },
188  { leXF, Tcode, XFcode, XFcode },
189  { leP, Tcode, Pcode, Pcode },
190  { -1, -1, -1, -1 },
191};
192
193struct binary_operator optab_ge_expr[] = {
194  { geSI, Tcode, SIcode, SIcode },
195  { geSU, Tcode, SUcode, SUcode },
196  { geDI, Tcode, DIcode, DIcode },
197  { geDU, Tcode, DUcode, DUcode },
198  { geSF, Tcode, SFcode, SFcode },
199  { geDF, Tcode, DFcode, DFcode },
200  { geXF, Tcode, XFcode, XFcode },
201  { geP, Tcode, Pcode, Pcode },
202  { -1, -1, -1, -1 },
203};
204
205struct binary_operator optab_gt_expr[] = {
206  { gtSI, Tcode, SIcode, SIcode },
207  { gtSU, Tcode, SUcode, SUcode },
208  { gtDI, Tcode, DIcode, DIcode },
209  { gtDU, Tcode, DUcode, DUcode },
210  { gtSF, Tcode, SFcode, SFcode },
211  { gtDF, Tcode, DFcode, DFcode },
212  { gtXF, Tcode, XFcode, XFcode },
213  { gtP, Tcode, Pcode, Pcode },
214  { -1, -1, -1, -1 },
215};
216
217struct binary_operator optab_eq_expr[] = {
218  { eqSI, Tcode, SIcode, SIcode },
219  { eqDI, Tcode, DIcode, DIcode },
220  { eqSF, Tcode, SFcode, SFcode },
221  { eqDF, Tcode, DFcode, DFcode },
222  { eqXF, Tcode, XFcode, XFcode },
223  { eqP, Tcode, Pcode, Pcode },
224  { -1, -1, -1, -1 },
225};
226
227struct binary_operator optab_ne_expr[] = {
228  { neSI, Tcode, SIcode, SIcode },
229  { neDI, Tcode, DIcode, DIcode },
230  { neSF, Tcode, SFcode, SFcode },
231  { neDF, Tcode, DFcode, DFcode },
232  { neXF, Tcode, XFcode, XFcode },
233  { neP, Tcode, Pcode, Pcode },
234  { -1, -1, -1, -1 },
235};
236
237/* Unary operator tables.  */
238struct unary_operator optab_negate_expr[] = {
239  { negSI, SIcode, SIcode },
240  { negDI, DIcode, DIcode },
241  { negSF, SFcode, SFcode },
242  { negDF, DFcode, DFcode },
243  { negXF, XFcode, XFcode },
244  { -1, -1, -1 },
245};
246
247struct unary_operator optab_bit_not_expr[] = {
248  { notSI, SIcode, SIcode },
249  { notDI, DIcode, DIcode },
250  { -1, -1, -1 },
251};
252
253struct unary_operator optab_truth_not_expr[] = {
254  { notT, SIcode, SIcode },
255  { -1, -1, -1 },
256};
257
258/* Increment operator tables.  */
259struct increment_operator optab_predecrement_expr[] = {
260  { predecQI, QIcode },
261  { predecQI, QUcode },
262  { predecHI, HIcode },
263  { predecHI, HUcode },
264  { predecSI, SIcode },
265  { predecSI, SUcode },
266  { predecDI, DIcode },
267  { predecDI, DUcode },
268  { predecP, Pcode },
269  { predecSF, SFcode },
270  { predecDF, DFcode },
271  { predecXF, XFcode },
272  { -1, -1 },
273};
274
275struct increment_operator optab_preincrement_expr[] = {
276  { preincQI, QIcode },
277  { preincQI, QUcode },
278  { preincHI, HIcode },
279  { preincHI, HUcode },
280  { preincSI, SIcode },
281  { preincSI, SUcode },
282  { preincDI, DIcode },
283  { preincDI, DUcode },
284  { preincP, Pcode },
285  { preincSF, SFcode },
286  { preincDF, DFcode },
287  { preincXF, XFcode },
288  { -1, -1 },
289};
290
291struct increment_operator optab_postdecrement_expr[] = {
292  { postdecQI, QIcode },
293  { postdecQI, QUcode },
294  { postdecHI, HIcode },
295  { postdecHI, HUcode },
296  { postdecSI, SIcode },
297  { postdecSI, SUcode },
298  { postdecDI, DIcode },
299  { postdecDI, DUcode },
300  { postdecP, Pcode },
301  { postdecSF, SFcode },
302  { postdecDF, DFcode },
303  { postdecXF, XFcode },
304  { -1, -1 },
305};
306
307struct increment_operator optab_postincrement_expr[] = {
308  { postincQI, QIcode },
309  { postincQI, QUcode },
310  { postincHI, HIcode },
311  { postincHI, HUcode },
312  { postincSI, SIcode },
313  { postincSI, SUcode },
314  { postincDI, DIcode },
315  { postincDI, DUcode },
316  { postincP, Pcode },
317  { postincSF, SFcode },
318  { postincDF, DFcode },
319  { postincXF, XFcode },
320  { -1, -1 },
321};
322
323/* Table of conversions supported by the interpreter.  */
324static struct conversion_info
325{
326  enum bytecode_opcode opcode;  /*  here indicates the conversion needs no opcode.  */
327  enum typecode from;
328  enum typecode to;
329  int cost;                     /* 1 for no-op conversions, 2 for widening conversions,
330                                   4 for int/float conversions, 8 for narrowing conversions.  */
331} conversion_info[] = {
332  { -1, QIcode, QUcode, 1 },
333  { -1, HIcode, HUcode, 1 },
334  { -1, SIcode, SUcode, 1 },
335  { -1, DIcode, DUcode, 1 },
336  { -1, QUcode, QIcode, 1 },
337  { -1, HUcode, HIcode, 1 },
338  { -1, SUcode, SIcode, 1 },
339  { -1, DUcode, DIcode, 1 },
340  { -1, Tcode, SIcode, 1 },
341  { convertQIHI, QIcode, HIcode, 2 },
342  { convertQUHU, QUcode, HUcode, 2 },
343  { convertQUSU, QUcode, SUcode, 2 },
344  { convertHISI, HIcode, SIcode, 2 },
345  { convertHUSU, HUcode, SUcode, 2 },
346  { convertSIDI, SIcode, DIcode, 2 },
347  { convertSUDU, SUcode, DUcode, 2 },
348  { convertSFDF, SFcode, DFcode, 2 },
349  { convertDFXF, DFcode, XFcode, 2 },
350  { convertHIQI, HIcode, QIcode, 8 },
351  { convertSIQI, SIcode, QIcode, 8 },
352  { convertSIHI, SIcode, HIcode, 8 },
353  { convertSUQU, SUcode, QUcode, 8 },
354  { convertDISI, DIcode, SIcode, 8 },
355  { convertDFSF, DFcode, SFcode, 8 },
356  { convertXFDF, XFcode, DFcode, 8 },
357  { convertPSI, Pcode, SIcode, 2 },
358  { convertSIP, SIcode, Pcode, 2 },
359  { convertSIT, SIcode, Tcode, 2 },
360  { convertDIT, DIcode, Tcode, 2 },
361  { convertSFT, SFcode, Tcode, 2 },
362  { convertDFT, DFcode, Tcode, 2 },
363  { convertXFT, XFcode, Tcode, 2 },
364  { convertQISI, QIcode, SIcode, 2 },
365  { convertPT, Pcode, Tcode, 2 },
366  { convertSISF, SIcode, SFcode, 4 },
367  { convertSIDF, SIcode, DFcode, 4 },
368  { convertSIXF, SIcode, XFcode, 4 },
369  { convertSUSF, SUcode, SFcode, 4 },
370  { convertSUDF, SUcode, DFcode, 4 },
371  { convertSUXF, SUcode, XFcode, 4 },
372  { convertDISF, DIcode, SFcode, 4 },
373  { convertDIDF, DIcode, DFcode, 4 },
374  { convertDIXF, DIcode, XFcode, 4 },
375  { convertDUSF, DUcode, SFcode, 4 },
376  { convertDUDF, DUcode, DFcode, 4 },
377  { convertDUXF, DUcode, XFcode, 4 },
378  { convertSFSI, SFcode, SIcode, 4 },
379  { convertDFSI, DFcode, SIcode, 4 },
380  { convertXFSI, XFcode, SIcode, 4 },
381  { convertSFSU, SFcode, SUcode, 4 },
382  { convertDFSU, DFcode, SUcode, 4 },
383  { convertXFSU, XFcode, SUcode, 4 },
384  { convertSFDI, SFcode, DIcode, 4 },
385  { convertDFDI, DFcode, DIcode, 4 },
386  { convertXFDI, XFcode, DIcode, 4 },
387  { convertSFDU, SFcode, DUcode, 4 },
388  { convertDFDU, DFcode, DUcode, 4 },
389  { convertXFDU, XFcode, DUcode, 4 },
390  { convertSIQI, SIcode, QIcode, 8 },
391};
392
393#define NUM_CONVERSIONS (sizeof conversion_info / sizeof (struct conversion_info))
394
395/* List form of a conversion recipe.  */
396struct conversion_list
397{
398  enum bytecode_opcode opcode;
399  enum typecode to;
400  int cost;
401  struct conversion_list *prev;
402};
403
404/* Determine if it is "reasonable" to add a given conversion to
405   a given list of conversions.  The following criteria define
406   "reasonable" conversion lists:
407   * No typecode appears more than once in the sequence (no loops).
408   * At most one conversion from integer to float or vice versa is present.
409   * Either sign extensions or zero extensions may be present, but not both.
410   * No widening conversions occur after a signed/unsigned conversion.
411   * The sequence of sizes must be strict nonincreasing or nondecreasing.  */
412
413static int
414conversion_reasonable_p (conversion, list)
415     struct conversion_info *conversion;
416     struct conversion_list *list;
417{
418  struct conversion_list *curr;
419  int curr_size, prev_size;
420  int has_int_float, has_float_int;
421  int has_sign_extend, has_zero_extend;
422  int has_signed_unsigned, has_unsigned_signed;
423
424  has_int_float = 0;
425  has_float_int = 0;
426  has_sign_extend = 0;
427  has_zero_extend = 0;
428  has_signed_unsigned = 0;
429  has_unsigned_signed = 0;
430
431  /* Make sure the destination typecode doesn't already appear in
432     the list.  */
433  for (curr = list; curr; curr = curr->prev)
434    if (conversion->to == curr->to)
435      return 0;
436
437  /* Check for certain kinds of conversions.  */
438  if (TYPECODE_INTEGER_P (conversion->from)
439      && TYPECODE_FLOAT_P (conversion->to))
440    has_int_float = 1;
441  if (TYPECODE_FLOAT_P (conversion->from)
442      && TYPECODE_INTEGER_P (conversion->to))
443    has_float_int = 1;
444  if (TYPECODE_SIGNED_P (conversion->from)
445      && TYPECODE_SIGNED_P (conversion->to)
446      && GET_TYPECODE_SIZE (conversion->from)
447      < GET_TYPECODE_SIZE (conversion->to))
448    has_sign_extend = 1;
449  if (TYPECODE_UNSIGNED_P (conversion->from)
450      && TYPECODE_UNSIGNED_P (conversion->to)
451      && GET_TYPECODE_SIZE (conversion->from)
452      < GET_TYPECODE_SIZE (conversion->to))
453    has_zero_extend = 1;
454
455  for (curr = list; curr && curr->prev; curr = curr->prev)
456    {
457      if (TYPECODE_INTEGER_P (curr->prev->to)
458          && TYPECODE_FLOAT_P (curr->to))
459        has_int_float = 1;
460      if (TYPECODE_FLOAT_P (curr->prev->to)
461          && TYPECODE_INTEGER_P (curr->to))
462        has_float_int = 1;
463      if (TYPECODE_SIGNED_P (curr->prev->to)
464          && TYPECODE_SIGNED_P (curr->to)
465          && GET_TYPECODE_SIZE (curr->prev->to)
466          < GET_TYPECODE_SIZE (curr->to))
467        has_sign_extend = 1;
468      if (TYPECODE_UNSIGNED_P (curr->prev->to)
469          && TYPECODE_UNSIGNED_P (curr->to)
470          && GET_TYPECODE_SIZE (curr->prev->to)
471          < GET_TYPECODE_SIZE (curr->to))
472        has_zero_extend = 1;
473      if (TYPECODE_SIGNED_P (curr->prev->to)
474          && TYPECODE_UNSIGNED_P (curr->to))
475        has_signed_unsigned = 1;
476      if (TYPECODE_UNSIGNED_P (curr->prev->to)
477          && TYPECODE_SIGNED_P (curr->to))
478        has_unsigned_signed = 1;
479    }
480
481  if (TYPECODE_INTEGER_P (conversion->from)
482      && TYPECODE_INTEGER_P (conversion->to)
483      && GET_TYPECODE_SIZE (conversion->to)
484      > GET_TYPECODE_SIZE (conversion->from)
485      && (has_signed_unsigned || has_unsigned_signed))
486    return 0;
487
488  if (has_float_int && has_int_float || has_sign_extend && has_zero_extend)
489    return 0;
490
491  /* Make sure the sequence of destination typecode sizes is
492     strictly nondecreasing or strictly nonincreasing.  */
493  prev_size = GET_TYPECODE_SIZE (conversion->to);
494  for (curr = list; curr; curr = curr->prev)
495    {
496      curr_size = GET_TYPECODE_SIZE (curr->to);
497      if (curr_size != prev_size)
498        break;
499    }
500  if (!curr)
501    return 1;
502
503  if (curr_size < prev_size)
504    for (prev_size = curr_size; curr; curr = curr->prev)
505      {
506        curr_size = GET_TYPECODE_SIZE (curr->to);
507        if (curr_size > prev_size)
508          return 0;
509        prev_size = curr_size;
510      }
511  else
512    for (prev_size = curr_size; curr; curr = curr->prev)
513      {
514        curr_size = GET_TYPECODE_SIZE (curr->to);
515        if (curr_size < prev_size)
516          return 0;
517        prev_size = curr_size;
518      }
519  return 1;
520}
521
522
523/* Exhaustively search all reasonable conversions to find one to
524   convert the given types.  */
525
526static struct conversion_recipe
527deduce_conversion (from, to)
528     enum typecode from, to;
529{
530  struct rl
531    {
532      struct conversion_list *list;
533      struct rl *next;
534    } *prev, curr, *good, *temp;
535  struct conversion_list *conv, *best;
536  int i, cost, bestcost;
537  struct conversion_recipe result;
538  struct obstack recipe_obstack;
539
540
541  obstack_init (&recipe_obstack);
542  curr.next = (struct rl *) obstack_alloc (&recipe_obstack, sizeof (struct rl));
543  curr.next->list
544    = (struct conversion_list *) obstack_alloc (&recipe_obstack,
545                                                sizeof (struct conversion_list));
546  curr.next->list->opcode = -1;
547  curr.next->list->to = from;
548  curr.next->list->cost = 0;
549  curr.next->list->prev = 0;
550  curr.next->next = 0;
551  good = 0;
552
553  while (curr.next)
554    {
555      /* Remove successful conversions from further consideration.  */
556      for (prev = &curr; prev; prev = prev->next)
557        if (prev->next && prev->next->list->to == to)
558          {
559            temp = prev->next->next;
560            prev->next->next = good;
561            good = prev->next;
562            prev->next = temp;
563          }
564
565      /* Go through each of the pending conversion chains, trying
566         all possible candidate conversions on them.  */
567      for (prev = curr.next, curr.next = 0; prev; prev = prev->next)
568        for (i = 0; i < NUM_CONVERSIONS; ++i)
569          if (conversion_info[i].from == prev->list->to
570              && conversion_reasonable_p (&conversion_info[i], prev->list))
571            {
572              temp = (struct rl *) obstack_alloc (&recipe_obstack,
573                                                  sizeof (struct rl));
574              temp->list = (struct conversion_list *)
575                obstack_alloc (&recipe_obstack,
576                               sizeof (struct conversion_list));
577              temp->list->opcode = conversion_info[i].opcode;
578              temp->list->to = conversion_info[i].to;
579              temp->list->cost = conversion_info[i].cost;
580              temp->list->prev = prev->list;
581              temp->next = curr.next;
582              curr.next = temp;
583            }
584    }
585
586  bestcost = BIG_ARBITRARY_NUMBER;
587  best = 0;
588  for (temp = good; temp; temp = temp->next)
589    {
590      for (conv = temp->list, cost = 0; conv; conv = conv->prev)
591        cost += conv->cost;
592      if (cost < bestcost)
593        {
594          bestcost = cost;
595          best = temp->list;
596        }
597    }
598
599  if (!best)
600    abort ();
601
602  for (i = 0, conv = best; conv; conv = conv->prev)
603    if (conv->opcode != -1)
604      ++i;
605
606  result.opcodes = (unsigned char *) xmalloc (i);
607  result.nopcodes = i;
608  for (conv = best; conv; conv = conv->prev)
609    if (conv->opcode != -1)
610      result.opcodes[--i] = conv->opcode;
611  result.cost = bestcost;
612  obstack_free (&recipe_obstack, 0);
613  return result;
614}
615
616#define DEDUCE_CONVERSION(FROM, TO)                             \
617  (conversion_recipe[(int) FROM][(int) TO].opcodes ? 0          \
618   : (conversion_recipe[(int) FROM][(int) TO]                   \
619       = deduce_conversion (FROM, TO), 0))
620
621
622/* Emit a conversion between the given scalar types.  */
623
624void
625emit_typecode_conversion (from, to)
626     enum typecode from, to;
627{
628  int i;
629
630  DEDUCE_CONVERSION (from, to);
631  for (i = 0; i < conversion_recipe[(int) from][(int) to].nopcodes; ++i)
632    bc_emit_instruction (conversion_recipe[(int) from][(int) to].opcodes[i]);
633}
634
635
636/* Initialize mode_to_code_map[] */
637
638void
639bc_init_mode_to_code_map ()
640{
641  int mode;
642
643  for (mode = 0; mode < MAX_MACHINE_MODE + 1; mode++)
644    {
645      signed_mode_to_code_map[mode]
646        = unsigned_mode_to_code_map[mode]
647        = LAST_AND_UNUSED_TYPECODE;
648    }
649
650#define DEF_MODEMAP(SYM, CODE, UCODE, CONST, LOAD, STORE) \
651  { signed_mode_to_code_map[(int) SYM] = CODE; \
652    unsigned_mode_to_code_map[(int) SYM] = UCODE; }
653#include "modemap.def"
654#undef DEF_MODEMAP
655
656  /* Initialize opcode maps for const, load, and store */
657  bc_init_mode_to_opcode_maps ();
658}
659
660/* Given a machine mode return the preferred typecode.  */
661
662enum typecode
663preferred_typecode (mode, unsignedp)
664     enum machine_mode mode;
665     int unsignedp;
666{
667  enum typecode code = (unsignedp
668                        ? unsigned_mode_to_code_map
669                        : signed_mode_to_code_map) [MIN ((int) mode,
670                                                         (int) MAX_MACHINE_MODE)];
671
672  if (code == LAST_AND_UNUSED_TYPECODE)
673    abort ();
674
675  return code;
676}
677
678
679/* Expand a conversion between the given types.  */
680
681void
682bc_expand_conversion (from, to)
683     tree from, to;
684{
685  enum typecode fcode, tcode;
686
687  fcode = preferred_typecode (TYPE_MODE (from), TREE_UNSIGNED (from));
688  tcode = preferred_typecode (TYPE_MODE (to), TREE_UNSIGNED (to));
689
690  emit_typecode_conversion (fcode, tcode);
691}
692
693/* Expand a conversion of the given type to a truth value.  */
694
695void
696bc_expand_truth_conversion (from)
697     tree from;
698{
699  enum typecode fcode;
700
701  fcode = preferred_typecode (TYPE_MODE (from), TREE_UNSIGNED (from));
702  emit_typecode_conversion (fcode, Tcode);
703}
704
705/* Emit an appropriate binary operation.  */
706
707void
708bc_expand_binary_operation (optab, resulttype, arg0, arg1)
709     struct binary_operator optab[];
710     tree resulttype, arg0, arg1;
711{
712  int i, besti, cost, bestcost;
713  enum typecode resultcode, arg0code, arg1code;
714 
715  resultcode = preferred_typecode (TYPE_MODE (resulttype), TREE_UNSIGNED (resulttype));
716  arg0code = preferred_typecode (TYPE_MODE (TREE_TYPE (arg0)), TREE_UNSIGNED (resulttype));
717  arg1code = preferred_typecode (TYPE_MODE (TREE_TYPE (arg1)), TREE_UNSIGNED (resulttype));
718
719  besti = -1;
720  bestcost = BIG_ARBITRARY_NUMBER;
721
722  for (i = 0; optab[i].opcode != -1; ++i)
723    {
724      cost = 0;
725      DEDUCE_CONVERSION (arg0code, optab[i].arg0);
726      cost += conversion_recipe[(int) arg0code][(int) optab[i].arg0].cost;
727      DEDUCE_CONVERSION (arg1code, optab[i].arg1);
728      cost += conversion_recipe[(int) arg1code][(int) optab[i].arg1].cost;
729      if (cost < bestcost)
730        {
731          besti = i;
732          bestcost = cost;
733        }
734    }
735
736  if (besti == -1)
737    abort ();
738
739  expand_expr (arg1, 0, VOIDmode, 0);
740  emit_typecode_conversion (arg1code, optab[besti].arg1);
741  expand_expr (arg0, 0, VOIDmode, 0);
742  emit_typecode_conversion (arg0code, optab[besti].arg0);
743  bc_emit_instruction (optab[besti].opcode);
744  emit_typecode_conversion (optab[besti].result, resultcode);
745}
746
747/* Emit an appropriate unary operation.  */
748
749void
750bc_expand_unary_operation (optab, resulttype, arg0)
751     struct unary_operator optab[];
752     tree resulttype, arg0;
753{
754  int i, besti, cost, bestcost;
755  enum typecode resultcode, arg0code;
756 
757  resultcode = preferred_typecode (TYPE_MODE (resulttype), TREE_UNSIGNED (resulttype));
758  arg0code = preferred_typecode (TYPE_MODE (TREE_TYPE (arg0)), TREE_UNSIGNED (TREE_TYPE (arg0)));
759
760  besti = -1;
761  bestcost = BIG_ARBITRARY_NUMBER;
762
763  for (i = 0; optab[i].opcode != -1; ++i)
764    {
765      DEDUCE_CONVERSION (arg0code, optab[i].arg0);
766      cost = conversion_recipe[(int) arg0code][(int) optab[i].arg0].cost;
767      if (cost < bestcost)
768        {
769          besti = i;
770          bestcost = cost;
771        }
772    }
773
774  if (besti == -1)
775    abort ();
776
777  expand_expr (arg0, 0, VOIDmode, 0);
778  emit_typecode_conversion (arg0code, optab[besti].arg0);
779  bc_emit_instruction (optab[besti].opcode);
780  emit_typecode_conversion (optab[besti].result, resultcode);
781}
782
783
784/* Emit an appropriate increment.  */
785
786void
787bc_expand_increment (optab, type)
788     struct increment_operator optab[];
789     tree type;
790{
791  enum typecode code;
792  int i;
793
794  code = preferred_typecode (TYPE_MODE (type), TREE_UNSIGNED (type));
795  for (i = 0; (int) optab[i].opcode >= 0; ++i)
796    if (code == optab[i].arg)
797      {
798        bc_emit_instruction (optab[i].opcode);
799        return;
800      }
801  abort ();
802}
Note: See TracBrowser for help on using the repository browser.